diff --git a/Taskfile.yaml b/Taskfile.yaml index d11d47a..a31d1b0 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -22,6 +22,7 @@ tasks: cmds: - task: static-analysis - task: test + - task: assert-windows-build - task: build static-analysis: @@ -157,6 +158,10 @@ tasks: - "{{ .TOOL_DIR }}/goreleaser release --clean --skip=publish --skip=sign --snapshot --config {{ .TMP_DIR }}/goreleaser.yaml" + assert-windows-build: + desc: Assert that binny compiles on Windows + cmds: + - "GOOS=windows go build ./cmd/binny" ## Release targets ################################# diff --git a/cmd/binny/cli/command/run.go b/cmd/binny/cli/command/run.go index 0af1477..25a443a 100644 --- a/cmd/binny/cli/command/run.go +++ b/cmd/binny/cli/command/run.go @@ -2,18 +2,10 @@ package command import ( "fmt" - "io" - "log" - "os" - "os/exec" - "os/signal" "path/filepath" - "syscall" - "github.com/creack/pty" "github.com/scylladb/go-set/strset" "github.com/spf13/cobra" - "golang.org/x/term" "github.com/anchore/binny" "github.com/anchore/binny/cmd/binny/cli/option" @@ -96,41 +88,3 @@ func runRunRUN(cfg RunConfig, name string, args []string) error { return run(fullPath, args) } - -func run(path string, args []string) error { - c := exec.Command(path, args...) - - ptmx, err := pty.Start(c) - if err != nil { - return err - } - - // make sure to close the pty at the end - defer func() { _ = ptmx.Close() }() // best effort - - // handle pty size - ch := make(chan os.Signal, 1) - signal.Notify(ch, syscall.SIGWINCH) - go func() { - for range ch { - if err := pty.InheritSize(os.Stdin, ptmx); err != nil { - log.Printf("error resizing pty: %s", err) - } - } - }() - ch <- syscall.SIGWINCH // initial resize - defer func() { signal.Stop(ch); close(ch) }() // cleanup signals when done - - // Set stdin in raw mode. - oldState, err := term.MakeRaw(int(os.Stdin.Fd())) - if err != nil { - panic(err) - } - defer func() { _ = term.Restore(int(os.Stdin.Fd()), oldState) }() // best effort - - // copy stdin to the pty and the pty to stdout. The goroutine will keep reading until the next keystroke before returning. - go func() { _, _ = io.Copy(ptmx, os.Stdin) }() - _, _ = io.Copy(os.Stdout, ptmx) - - return nil -} diff --git a/cmd/binny/cli/command/run_unix.go b/cmd/binny/cli/command/run_unix.go new file mode 100644 index 0000000..7fa1f21 --- /dev/null +++ b/cmd/binny/cli/command/run_unix.go @@ -0,0 +1,53 @@ +//go:build linux || darwin + +package command + +import ( + "io" + "log" + "os" + "os/exec" + "os/signal" + "syscall" + + "github.com/creack/pty" + "golang.org/x/term" +) + +func run(path string, args []string) error { + c := exec.Command(path, args...) + + ptmx, err := pty.Start(c) + if err != nil { + return err + } + + // make sure to close the pty at the end + defer func() { _ = ptmx.Close() }() // best effort + + // handle pty size + ch := make(chan os.Signal, 1) + signal.Notify(ch, syscall.SIGWINCH) + go func() { + for range ch { + if err := pty.InheritSize(os.Stdin, ptmx); err != nil { + log.Printf("error resizing pty: %s", err) + } + } + }() + ch <- syscall.SIGWINCH // initial resize + defer func() { signal.Stop(ch); close(ch) }() // cleanup signals when done + + // Set stdin in raw mode. + oldState, err := term.MakeRaw(int(os.Stdin.Fd())) + if err != nil { + panic(err) + } + defer func() { _ = term.Restore(int(os.Stdin.Fd()), oldState) }() // best effort + + // copy stdin to the pty and the pty to stdout. The goroutine will keep reading until the next keystroke before returning. + go func() { _, _ = io.Copy(ptmx, os.Stdin) }() + _, _ = io.Copy(os.Stdout, ptmx) + + return nil +} diff --git a/cmd/binny/cli/command/run_windows.go b/cmd/binny/cli/command/run_windows.go new file mode 100644 index 0000000..350f053 --- /dev/null +++ b/cmd/binny/cli/command/run_windows.go @@ -0,0 +1,13 @@ +package command + +import ( + "os" + "os/exec" +) + +func run(path string, args []string) error { + c := exec.Command(path, args...) + c.Stdout = os.Stdout + c.Stderr = os.Stderr + return c.Run() +}