From d5dc7c7d177603afb3305c13777486af4cdbf6b6 Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Mon, 26 Aug 2019 17:23:21 -0500 Subject: [PATCH 1/9] Update go.coder.com/cli to v0.4.0 --- go.mod | 3 ++- go.sum | 6 ++++-- main.go | 7 ++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 26daea9..e8637c0 100644 --- a/go.mod +++ b/go.mod @@ -5,8 +5,9 @@ go 1.12 require ( github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 github.com/pkg/errors v0.8.1 // indirect + github.com/spf13/pflag v1.0.3 github.com/stretchr/testify v1.3.0 - go.coder.com/cli v0.1.0 + go.coder.com/cli v0.4.0 go.coder.com/flog v0.0.0-20190129195112-eaed154a0db8 go.coder.com/retry v0.0.0-20180926062817-cf12c95974ac golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd diff --git a/go.sum b/go.sum index c24ed7b..df0d6a1 100644 --- a/go.sum +++ b/go.sum @@ -13,12 +13,14 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -go.coder.com/cli v0.1.0 h1:ZAjpjXJxMnwj1TqXUi7nnXXuxiPRfwfoC2kViN93oMM= -go.coder.com/cli v0.1.0/go.mod h1:pbVagI9YH/HHMManxPFML4P527GDREwsb+yciZ7mtB8= +go.coder.com/cli v0.4.0 h1:PruDGwm/CPFndyK/eMowZG3vzg5CgohRWeXWCTr3zi8= +go.coder.com/cli v0.4.0/go.mod h1:hRTOURCR3LJF1FRW9arecgrzX+AHG7mfYMwThPIgq+w= go.coder.com/flog v0.0.0-20190129195112-eaed154a0db8 h1:PtQ3moPi4EAz3cyQhkUs1IGIXa2QgJpP60yMjOdu0kk= go.coder.com/flog v0.0.0-20190129195112-eaed154a0db8/go.mod h1:83JsYgXYv0EOaXjIMnaZ1Fl6ddNB3fJnDZ/8845mUJ8= go.coder.com/retry v0.0.0-20180926062817-cf12c95974ac h1:ekdpsuykRy/E+SDq5BquFomNhRCk8OOyhtnACW9Bi50= diff --git a/main.go b/main.go index 2a63211..d2c2b8e 100644 --- a/main.go +++ b/main.go @@ -1,13 +1,14 @@ package main import ( - "flag" "fmt" "math/rand" "os" "strings" "time" + "github.com/spf13/pflag" + "go.coder.com/cli" "go.coder.com/flog" ) @@ -50,7 +51,7 @@ func (c *rootCmd) Spec() cli.CommandSpec { } } -func (c *rootCmd) RegisterFlags(fl *flag.FlagSet) { +func (c *rootCmd) RegisterFlags(fl *pflag.FlagSet) { fl.BoolVar(&c.skipSync, "skipsync", false, "skip syncing local settings and extensions to remote host") fl.BoolVar(&c.syncBack, "b", false, "sync extensions back on termination") fl.BoolVar(&c.printVersion, "version", false, "print version information and exit") @@ -59,7 +60,7 @@ func (c *rootCmd) RegisterFlags(fl *flag.FlagSet) { fl.StringVar(&c.sshFlags, "ssh-flags", "", "custom SSH flags") } -func (c *rootCmd) Run(fl *flag.FlagSet) { +func (c *rootCmd) Run(fl *pflag.FlagSet) { if c.printVersion { fmt.Printf("%v\n", version) os.Exit(0) From 1985f23b500598a30b772e5b6356fde8a93c0190 Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Fri, 23 Aug 2019 23:53:00 +0000 Subject: [PATCH 2/9] Add ability to upload local binary --- main.go | 3 ++ sshcode.go | 87 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 73 insertions(+), 17 deletions(-) diff --git a/main.go b/main.go index d2c2b8e..f3a9b58 100644 --- a/main.go +++ b/main.go @@ -41,6 +41,7 @@ type rootCmd struct { noReuseConnection bool bindAddr string sshFlags string + codeServerPath string } func (c *rootCmd) Spec() cli.CommandSpec { @@ -58,6 +59,7 @@ func (c *rootCmd) RegisterFlags(fl *pflag.FlagSet) { fl.BoolVar(&c.noReuseConnection, "no-reuse-connection", false, "do not reuse SSH connection via control socket") fl.StringVar(&c.bindAddr, "bind", "", "local bind address for SSH tunnel, in [HOST][:PORT] syntax (default: 127.0.0.1)") fl.StringVar(&c.sshFlags, "ssh-flags", "", "custom SSH flags") + fl.StringVar(&c.codeServerPath, "code-server-path", "", "custom code-server binary to upload") } func (c *rootCmd) Run(fl *pflag.FlagSet) { @@ -84,6 +86,7 @@ func (c *rootCmd) Run(fl *pflag.FlagSet) { bindAddr: c.bindAddr, syncBack: c.syncBack, reuseConnection: !c.noReuseConnection, + codeServerPath: c.codeServerPath, }) if err != nil { diff --git a/sshcode.go b/sshcode.go index e4a623d..2e47332 100644 --- a/sshcode.go +++ b/sshcode.go @@ -36,6 +36,7 @@ type options struct { bindAddr string remotePort string sshFlags string + codeServerPath string } func sshCode(host, dir string, o options) error { @@ -76,23 +77,49 @@ func sshCode(host, dir string, o options) error { } } - flog.Info("ensuring code-server is updated...") - dlScript := downloadScript(codeServerPath) + // Upload local code-server or download code-server from CI server. + if o.codeServerPath != "" { + flog.Info("uploading local code-server binary...") + err = copyCodeServerBinary(o.sshFlags, host, o.codeServerPath, codeServerPath) + if err != nil { + return xerrors.Errorf("failed to upload local code-server binary to remote server: %w", err) + } - // Downloads the latest code-server and allows it to be executed. - sshCmdStr := fmt.Sprintf("ssh %v %v '/usr/bin/env bash -l'", o.sshFlags, host) + sshCmdStr := + fmt.Sprintf("ssh %v %v 'chmod +x %v'", + o.sshFlags, host, codeServerPath, + ) - sshCmd := exec.Command("sh", "-l", "-c", sshCmdStr) - sshCmd.Stdout = os.Stdout - sshCmd.Stderr = os.Stderr - sshCmd.Stdin = strings.NewReader(dlScript) - err = sshCmd.Run() - if err != nil { - return xerrors.Errorf("failed to update code-server: \n---ssh cmd---\n%s\n---download script---\n%s: %w", - sshCmdStr, - dlScript, - err, - ) + sshCmd := exec.Command("sh", "-l", "-c", sshCmdStr) + sshCmd.Stdout = os.Stdout + sshCmd.Stderr = os.Stderr + err = sshCmd.Run() + if err != nil { + return xerrors.Errorf("failed to make code-server binary executable:\n---ssh cmd---\n%s: %w", + sshCmdStr, + err, + ) + } + } else { + flog.Info("ensuring code-server is updated...") + dlScript := downloadScript(codeServerPath) + + // Downloads the latest code-server and allows it to be executed. + sshCmdStr := fmt.Sprintf("ssh %v %v '/usr/bin/env bash -l'", o.sshFlags, host) + + sshCmd := exec.Command("sh", "-l", "-c", sshCmdStr) + sshCmd.Stdout = os.Stdout + sshCmd.Stderr = os.Stderr + sshCmd.Stdin = strings.NewReader(dlScript) + err = sshCmd.Run() + if err != nil { + return xerrors.Errorf("failed to update code-server:\n---ssh cmd---\n%s"+ + "\n---download script---\n%s: %w", + sshCmdStr, + dlScript, + err, + ) + } } if !o.skipSync { @@ -117,13 +144,13 @@ func sshCode(host, dir string, o options) error { flog.Info("Tunneling remote port %v to %v", o.remotePort, o.bindAddr) - sshCmdStr = + sshCmdStr := fmt.Sprintf("ssh -tt -q -L %v:localhost:%v %v %v 'cd %v; %v --host 127.0.0.1 --allow-http --no-auth --port=%v'", o.bindAddr, o.remotePort, o.sshFlags, host, dir, codeServerPath, o.remotePort, ) // Starts code-server and forwards the remote port. - sshCmd = exec.Command("sh", "-l", "-c", sshCmdStr) + sshCmd := exec.Command("sh", "-l", "-c", sshCmdStr) sshCmd.Stdin = os.Stdin sshCmd.Stdout = os.Stdout sshCmd.Stderr = os.Stderr @@ -399,6 +426,20 @@ func checkSSHMaster(sshMasterCmd *exec.Cmd, sshFlags string, host string) error return xerrors.Errorf("max number of tries exceeded: %d", maxTries) } +// copyCodeServerBinary copies a code-server binary from local to remote. +func copyCodeServerBinary(sshFlags string, host string, localPath string, remotePath string) error { + if err := ensureFile(localPath); err != nil { + return err + } + + var ( + src = localPath + dest = host + ":" + remotePath + ) + + return rsync(src, dest, sshFlags) +} + func syncUserSettings(sshFlags string, host string, back bool) error { localConfDir, err := configDir() if err != nil { @@ -517,6 +558,18 @@ func ensureDir(path string) error { return nil } +// ensureFile tries to stat the specified path and ensure it's a file. +func ensureFile(path string) error { + info, err := os.Stat(path) + if err != nil { + return err + } + if info.IsDir() { + return xerrors.New("path is a directory") + } + return nil +} + // parseHost parses the host argument. If 'gcp:' is prefixed to the // host then a lookup is done using gcloud to determine the external IP and any // additional SSH arguments that should be used for ssh commands. Otherwise, host From c8e4017bc837a11f88a0cc3546dbcce01fbc15a4 Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Fri, 6 Sep 2019 16:09:04 +0000 Subject: [PATCH 3/9] Rename --code-server-path to --upload-code-server --- main.go | 16 ++++++++-------- sshcode.go | 26 +++++++++++++------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/main.go b/main.go index f3a9b58..b355dc1 100644 --- a/main.go +++ b/main.go @@ -41,7 +41,7 @@ type rootCmd struct { noReuseConnection bool bindAddr string sshFlags string - codeServerPath string + uploadCodeServer string } func (c *rootCmd) Spec() cli.CommandSpec { @@ -59,7 +59,7 @@ func (c *rootCmd) RegisterFlags(fl *pflag.FlagSet) { fl.BoolVar(&c.noReuseConnection, "no-reuse-connection", false, "do not reuse SSH connection via control socket") fl.StringVar(&c.bindAddr, "bind", "", "local bind address for SSH tunnel, in [HOST][:PORT] syntax (default: 127.0.0.1)") fl.StringVar(&c.sshFlags, "ssh-flags", "", "custom SSH flags") - fl.StringVar(&c.codeServerPath, "code-server-path", "", "custom code-server binary to upload") + fl.StringVar(&c.uploadCodeServer, "upload-code-server", "", "custom code-server binary to upload to the remote host") } func (c *rootCmd) Run(fl *pflag.FlagSet) { @@ -81,12 +81,12 @@ func (c *rootCmd) Run(fl *pflag.FlagSet) { } err := sshCode(host, dir, options{ - skipSync: c.skipSync, - sshFlags: c.sshFlags, - bindAddr: c.bindAddr, - syncBack: c.syncBack, - reuseConnection: !c.noReuseConnection, - codeServerPath: c.codeServerPath, + skipSync: c.skipSync, + sshFlags: c.sshFlags, + bindAddr: c.bindAddr, + syncBack: c.syncBack, + reuseConnection: !c.noReuseConnection, + uploadCodeServer: c.uploadCodeServer, }) if err != nil { diff --git a/sshcode.go b/sshcode.go index 2e47332..accdd0d 100644 --- a/sshcode.go +++ b/sshcode.go @@ -29,14 +29,14 @@ const ( ) type options struct { - skipSync bool - syncBack bool - noOpen bool - reuseConnection bool - bindAddr string - remotePort string - sshFlags string - codeServerPath string + skipSync bool + syncBack bool + noOpen bool + reuseConnection bool + bindAddr string + remotePort string + sshFlags string + uploadCodeServer string } func sshCode(host, dir string, o options) error { @@ -78,9 +78,9 @@ func sshCode(host, dir string, o options) error { } // Upload local code-server or download code-server from CI server. - if o.codeServerPath != "" { + if o.uploadCodeServer != "" { flog.Info("uploading local code-server binary...") - err = copyCodeServerBinary(o.sshFlags, host, o.codeServerPath, codeServerPath) + err = copyCodeServerBinary(o.sshFlags, host, o.uploadCodeServer, codeServerPath) if err != nil { return xerrors.Errorf("failed to upload local code-server binary to remote server: %w", err) } @@ -428,7 +428,7 @@ func checkSSHMaster(sshMasterCmd *exec.Cmd, sshFlags string, host string) error // copyCodeServerBinary copies a code-server binary from local to remote. func copyCodeServerBinary(sshFlags string, host string, localPath string, remotePath string) error { - if err := ensureFile(localPath); err != nil { + if err := validateIsFile(localPath); err != nil { return err } @@ -558,8 +558,8 @@ func ensureDir(path string) error { return nil } -// ensureFile tries to stat the specified path and ensure it's a file. -func ensureFile(path string) error { +// validateIsFile tries to stat the specified path and ensure it's a file. +func validateIsFile(path string) error { info, err := os.Stat(path) if err != nil { return err From 7e6845d1bda59a90b09f90b8fc7815cdc23267c5 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 11 Sep 2019 10:38:11 -0500 Subject: [PATCH 4/9] Update deps --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e8637c0..e378ffe 100644 --- a/go.mod +++ b/go.mod @@ -12,5 +12,5 @@ require ( go.coder.com/retry v0.0.0-20180926062817-cf12c95974ac golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be // indirect - golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373 + golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 ) diff --git a/go.sum b/go.sum index df0d6a1..19ceba8 100644 --- a/go.sum +++ b/go.sum @@ -34,5 +34,5 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be h1:mI+jhqkn68ybP0ORJqunXn+fq+Eeb4hHKqLQcFICjAc= golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373 h1:PPwnA7z1Pjf7XYaBP9GL1VAMZmcIWyFz7QCMSIIa3Bg= -golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 6277c6bb0444e3ef9af40c5baad038e162087a3b Mon Sep 17 00:00:00 2001 From: Gwon Seonggwang Date: Sun, 22 Sep 2019 04:17:06 +0900 Subject: [PATCH 5/9] Update tarname and tar option for ci build Closes #142 --- ci/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/build.sh b/ci/build.sh index 1f14096..9e30b09 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -10,8 +10,8 @@ build(){ go build -ldflags "-X main.version=${tag}" -o $tmpdir/sshcode pushd $tmpdir - tarname=sshcode-$GOOS-$GOARCH.tar - tar -cf $tarname sshcode + tarname=sshcode-$GOOS-$GOARCH.tar.gz + tar -czf $tarname sshcode popd cp $tmpdir/$tarname bin rm -rf $tmpdir From fd95a4079501b8f9dc1080cd79541838d1c05e4c Mon Sep 17 00:00:00 2001 From: Brandon Callifornia Date: Fri, 25 Oct 2019 11:41:18 +0200 Subject: [PATCH 6/9] Fixed allow-http-warning and no auth --- sshcode.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sshcode.go b/sshcode.go index accdd0d..e769c4b 100644 --- a/sshcode.go +++ b/sshcode.go @@ -145,7 +145,7 @@ func sshCode(host, dir string, o options) error { flog.Info("Tunneling remote port %v to %v", o.remotePort, o.bindAddr) sshCmdStr := - fmt.Sprintf("ssh -tt -q -L %v:localhost:%v %v %v 'cd %v; %v --host 127.0.0.1 --allow-http --no-auth --port=%v'", + fmt.Sprintf("ssh -tt -q -L %v:localhost:%v %v %v 'cd %v; %v --host 127.0.0.1 --auth none --port=%v'", o.bindAddr, o.remotePort, o.sshFlags, host, dir, codeServerPath, o.remotePort, ) From 7ebef26504f6390830e436362b3eae72b48c41e2 Mon Sep 17 00:00:00 2001 From: hassieswift621 Date: Sat, 7 Dec 2019 20:02:02 +0000 Subject: [PATCH 7/9] Remove duplicated word from sync user settings error --- sshcode.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sshcode.go b/sshcode.go index e769c4b..8b239aa 100644 --- a/sshcode.go +++ b/sshcode.go @@ -212,7 +212,7 @@ func sshCode(host, dir string, o options) error { err = syncUserSettings(o.sshFlags, host, true) if err != nil { - return xerrors.Errorf("failed to sync user settings settings back: %w", err) + return xerrors.Errorf("failed to sync user settings back: %w", err) } return nil From 50e859cd1084379374420cb5263d053eae3b0254 Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Wed, 14 Aug 2019 20:02:10 -0700 Subject: [PATCH 8/9] Add git bash and mingw support (#132) Supports git bash and mingw on Windows. Does not support cmd.exe. Signed-off-by: Dean Sheather Co-authored-by: Merith --- .gitignore | 1 + main.go | 6 +++++ settings.go | 4 ++++ sshcode.go | 63 ++++++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index dc0daa9..94251e3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ vendor bin .vscode sshcode +sshcode.exe diff --git a/main.go b/main.go index b355dc1..674f983 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "fmt" "math/rand" "os" + "runtime" "strings" "time" @@ -80,6 +81,11 @@ func (c *rootCmd) Run(fl *pflag.FlagSet) { dir = "~" } + // Get linux relative path if on windows. + if runtime.GOOS == "windows" { + dir = gitbashWindowsDir(dir) + } + err := sshCode(host, dir, options{ skipSync: c.skipSync, sshFlags: c.sshFlags, diff --git a/settings.go b/settings.go index ad962a3..e88c260 100644 --- a/settings.go +++ b/settings.go @@ -24,6 +24,8 @@ func configDir() (string, error) { path = os.ExpandEnv("$HOME/.config/Code/User/") case "darwin": path = os.ExpandEnv("$HOME/Library/Application Support/Code/User/") + case "windows": + return os.ExpandEnv("/c/Users/$USERNAME/AppData/Roaming/Code/User"), nil default: return "", xerrors.Errorf("unsupported platform: %s", runtime.GOOS) } @@ -39,6 +41,8 @@ func extensionsDir() (string, error) { switch runtime.GOOS { case "linux", "darwin": path = os.ExpandEnv("$HOME/.vscode/extensions/") + case "windows": + return os.ExpandEnv("/c/Users/$USERNAME/.vscode/extensions"), nil default: return "", xerrors.Errorf("unsupported platform: %s", runtime.GOOS) } diff --git a/sshcode.go b/sshcode.go index 8b239aa..5021c09 100644 --- a/sshcode.go +++ b/sshcode.go @@ -10,6 +10,7 @@ import ( "os/exec" "os/signal" "path/filepath" + "runtime" "strconv" "strings" "syscall" @@ -106,7 +107,6 @@ func sshCode(host, dir string, o options) error { // Downloads the latest code-server and allows it to be executed. sshCmdStr := fmt.Sprintf("ssh %v %v '/usr/bin/env bash -l'", o.sshFlags, host) - sshCmd := exec.Command("sh", "-l", "-c", sshCmdStr) sshCmd.Stdout = os.Stdout sshCmd.Stderr = os.Stderr @@ -145,10 +145,9 @@ func sshCode(host, dir string, o options) error { flog.Info("Tunneling remote port %v to %v", o.remotePort, o.bindAddr) sshCmdStr := - fmt.Sprintf("ssh -tt -q -L %v:localhost:%v %v %v 'cd %v; %v --host 127.0.0.1 --auth none --port=%v'", - o.bindAddr, o.remotePort, o.sshFlags, host, dir, codeServerPath, o.remotePort, + fmt.Sprintf("ssh -tt -q -L %v:localhost:%v %v %v '%v %v --host 127.0.0.1 --auth none --port=%v'", + o.bindAddr, o.remotePort, o.sshFlags, host, codeServerPath, dir, o.remotePort, ) - // Starts code-server and forwards the remote port. sshCmd := exec.Command("sh", "-l", "-c", sshCmdStr) sshCmd.Stdin = os.Stdin @@ -266,9 +265,12 @@ func openBrowser(url string) { const ( macPath = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" wslPath = "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe" + winPath = "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" ) switch { + case commandExists("chrome"): + openCmd = exec.Command("chrome", chromeOptions(url)...) case commandExists("google-chrome"): openCmd = exec.Command("google-chrome", chromeOptions(url)...) case commandExists("google-chrome-stable"): @@ -281,6 +283,8 @@ func openBrowser(url string) { openCmd = exec.Command(macPath, chromeOptions(url)...) case pathExists(wslPath): openCmd = exec.Command(wslPath, chromeOptions(url)...) + case pathExists(winPath): + openCmd = exec.Command(winPath, chromeOptions(url)...) default: err := browser.OpenURL(url) if err != nil { @@ -335,6 +339,11 @@ func randomPort() (string, error) { // checkSSHDirectory performs sanity and safety checks on sshDirectory, and // returns a new value for o.reuseConnection depending on the checks. func checkSSHDirectory(sshDirectory string, reuseConnection bool) bool { + if runtime.GOOS == "windows" { + flog.Info("OS is windows, disabling connection reuse feature") + return false + } + sshDirectoryMode, err := os.Lstat(expandPath(sshDirectory)) if err != nil { if reuseConnection { @@ -451,8 +460,10 @@ func syncUserSettings(sshFlags string, host string, back bool) error { return err } - const remoteSettingsDir = "~/.local/share/code-server/User/" - + var remoteSettingsDir = "~/.local/share/code-server/User/" + if runtime.GOOS == "windows" { + remoteSettingsDir = ".local/share/code-server/User/" + } var ( src = localConfDir + "/" dest = host + ":" + remoteSettingsDir @@ -477,7 +488,10 @@ func syncExtensions(sshFlags string, host string, back bool) error { return err } - const remoteExtensionsDir = "~/.local/share/code-server/extensions/" + var remoteExtensionsDir = "~/.local/share/code-server/extensions/" + if runtime.GOOS == "windows" { + remoteExtensionsDir = ".local/share/code-server/extensions/" + } var ( src = localExtensionsDir + "/" @@ -505,6 +519,7 @@ func rsync(src string, dest string, sshFlags string, excludePaths ...string) err // locally in order to properly delete an extension. "--delete", "--copy-unsafe-links", + "-zz", src, dest, )..., ) @@ -524,7 +539,7 @@ func downloadScript(codeServerPath string) string { [ "$(uname -m)" != "x86_64" ] && echo "Unsupported server architecture $(uname -m). code-server only has releases for x86_64 systems." && exit 1 pkill -f %v || true -mkdir -p ~/.local/share/code-server %v +mkdir -p $HOME/.local/share/code-server %v cd %v curlflags="-o latest-linux" if [ -f latest-linux ]; then @@ -535,8 +550,8 @@ curl $curlflags https://codesrv-ci.cdr.sh/latest-linux ln latest-linux %v chmod +x %v`, codeServerPath, - filepath.Dir(codeServerPath), - filepath.Dir(codeServerPath), + filepath.ToSlash(filepath.Dir(codeServerPath)), + filepath.ToSlash(filepath.Dir(codeServerPath)), codeServerPath, codeServerPath, codeServerPath, @@ -548,6 +563,11 @@ chmod +x %v`, func ensureDir(path string) error { _, err := os.Stat(path) if os.IsNotExist(err) { + // This fixes a issue where Go reads `/c/` as `C:\c\` and creates + // empty directories on the client that don't need to exist. + if runtime.GOOS == "windows" && strings.HasPrefix(path, "/c/") { + path = "C:" + path[2:] + } err = os.MkdirAll(path, 0750) } @@ -608,3 +628,26 @@ func parseGCPSSHCmd(instance string) (ip, sshFlags string, err error) { return strings.TrimSpace(userIP), sshFlags, nil } + +// gitbashWindowsDir strips a the msys2 install directory from the beginning of +// the path. On msys2, if a user provides `/workspace` sshcode will receive +// `C:/msys64/workspace` which won't work on the remote host. +func gitbashWindowsDir(dir string) string { + + // Don't bother figuring out path if it's relative to home dir. + if strings.HasPrefix(dir, "~/") { + if dir == "~" { + return "~/" + } + return dir + } + + mingwPrefix, err := exec.Command("sh", "-c", "{ cd / && pwd -W; }").Output() + if err != nil { + // Default to a sane location. + mingwPrefix = []byte("C:/mingw64") + } + + prefix := strings.TrimSuffix(string(mingwPrefix), "/\n") + return strings.TrimPrefix(dir, prefix) +} From b52faf9528bdaa4cab8a20492065fed358b48b94 Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Mon, 10 Aug 2020 14:34:05 -0400 Subject: [PATCH 9/9] Add deprecation notice to README See #185 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index dddd19e..3882f94 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # sshcode +**This project has been deprecated in favour of the [code-server install script](https://github.com/cdr/code-server#quick-install)** + +**See the discussion in [#185](https://github.com/cdr/sshcode/issues/185)** + +--- + [!["Open Issues"](https://img.shields.io/github/issues-raw/cdr/sshcode.svg)](https://github.com/cdr/sshcode/issues) [!["Latest Release"](https://img.shields.io/github/release/cdr/sshcode.svg)](https://github.com/cdr/sshcode/releases/latest) [![MIT license](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/cdr/sshcode/blob/master/LICENSE)