@@ -10,6 +10,7 @@ import (
10
10
"os/exec"
11
11
"os/signal"
12
12
"path/filepath"
13
+ "runtime"
13
14
"strconv"
14
15
"strings"
15
16
"syscall"
@@ -106,7 +107,6 @@ func sshCode(host, dir string, o options) error {
106
107
107
108
// Downloads the latest code-server and allows it to be executed.
108
109
sshCmdStr := fmt .Sprintf ("ssh %v %v '/usr/bin/env bash -l'" , o .sshFlags , host )
109
-
110
110
sshCmd := exec .Command ("sh" , "-l" , "-c" , sshCmdStr )
111
111
sshCmd .Stdout = os .Stdout
112
112
sshCmd .Stderr = os .Stderr
@@ -145,10 +145,9 @@ func sshCode(host, dir string, o options) error {
145
145
flog .Info ("Tunneling remote port %v to %v" , o .remotePort , o .bindAddr )
146
146
147
147
sshCmdStr :=
148
- fmt .Sprintf ("ssh -tt -q -L %v:localhost:%v %v %v 'cd %v; %v --host 127.0.0.1 --auth none --port=%v'" ,
149
- o .bindAddr , o .remotePort , o .sshFlags , host , dir , codeServerPath , o .remotePort ,
148
+ fmt .Sprintf ("ssh -tt -q -L %v:localhost:%v %v %v '%v %v --host 127.0.0.1 --auth none --port=%v'" ,
149
+ o .bindAddr , o .remotePort , o .sshFlags , host , codeServerPath , dir , o .remotePort ,
150
150
)
151
-
152
151
// Starts code-server and forwards the remote port.
153
152
sshCmd := exec .Command ("sh" , "-l" , "-c" , sshCmdStr )
154
153
sshCmd .Stdin = os .Stdin
@@ -266,9 +265,12 @@ func openBrowser(url string) {
266
265
const (
267
266
macPath = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
268
267
wslPath = "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"
268
+ winPath = "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
269
269
)
270
270
271
271
switch {
272
+ case commandExists ("chrome" ):
273
+ openCmd = exec .Command ("chrome" , chromeOptions (url )... )
272
274
case commandExists ("google-chrome" ):
273
275
openCmd = exec .Command ("google-chrome" , chromeOptions (url )... )
274
276
case commandExists ("google-chrome-stable" ):
@@ -281,6 +283,8 @@ func openBrowser(url string) {
281
283
openCmd = exec .Command (macPath , chromeOptions (url )... )
282
284
case pathExists (wslPath ):
283
285
openCmd = exec .Command (wslPath , chromeOptions (url )... )
286
+ case pathExists (winPath ):
287
+ openCmd = exec .Command (winPath , chromeOptions (url )... )
284
288
default :
285
289
err := browser .OpenURL (url )
286
290
if err != nil {
@@ -335,6 +339,11 @@ func randomPort() (string, error) {
335
339
// checkSSHDirectory performs sanity and safety checks on sshDirectory, and
336
340
// returns a new value for o.reuseConnection depending on the checks.
337
341
func checkSSHDirectory (sshDirectory string , reuseConnection bool ) bool {
342
+ if runtime .GOOS == "windows" {
343
+ flog .Info ("OS is windows, disabling connection reuse feature" )
344
+ return false
345
+ }
346
+
338
347
sshDirectoryMode , err := os .Lstat (expandPath (sshDirectory ))
339
348
if err != nil {
340
349
if reuseConnection {
@@ -451,8 +460,10 @@ func syncUserSettings(sshFlags string, host string, back bool) error {
451
460
return err
452
461
}
453
462
454
- const remoteSettingsDir = "~/.local/share/code-server/User/"
455
-
463
+ var remoteSettingsDir = "~/.local/share/code-server/User/"
464
+ if runtime .GOOS == "windows" {
465
+ remoteSettingsDir = ".local/share/code-server/User/"
466
+ }
456
467
var (
457
468
src = localConfDir + "/"
458
469
dest = host + ":" + remoteSettingsDir
@@ -477,7 +488,10 @@ func syncExtensions(sshFlags string, host string, back bool) error {
477
488
return err
478
489
}
479
490
480
- const remoteExtensionsDir = "~/.local/share/code-server/extensions/"
491
+ var remoteExtensionsDir = "~/.local/share/code-server/extensions/"
492
+ if runtime .GOOS == "windows" {
493
+ remoteExtensionsDir = ".local/share/code-server/extensions/"
494
+ }
481
495
482
496
var (
483
497
src = localExtensionsDir + "/"
@@ -505,6 +519,7 @@ func rsync(src string, dest string, sshFlags string, excludePaths ...string) err
505
519
// locally in order to properly delete an extension.
506
520
"--delete" ,
507
521
"--copy-unsafe-links" ,
522
+ "-zz" ,
508
523
src , dest ,
509
524
)... ,
510
525
)
@@ -524,7 +539,7 @@ func downloadScript(codeServerPath string) string {
524
539
525
540
[ "$(uname -m)" != "x86_64" ] && echo "Unsupported server architecture $(uname -m). code-server only has releases for x86_64 systems." && exit 1
526
541
pkill -f %v || true
527
- mkdir -p ~ /.local/share/code-server %v
542
+ mkdir -p $HOME /.local/share/code-server %v
528
543
cd %v
529
544
curlflags="-o latest-linux"
530
545
if [ -f latest-linux ]; then
@@ -535,8 +550,8 @@ curl $curlflags https://codesrv-ci.cdr.sh/latest-linux
535
550
ln latest-linux %v
536
551
chmod +x %v` ,
537
552
codeServerPath ,
538
- filepath .Dir (codeServerPath ),
539
- filepath .Dir (codeServerPath ),
553
+ filepath .ToSlash ( filepath . Dir (codeServerPath ) ),
554
+ filepath .ToSlash ( filepath . Dir (codeServerPath ) ),
540
555
codeServerPath ,
541
556
codeServerPath ,
542
557
codeServerPath ,
@@ -548,6 +563,11 @@ chmod +x %v`,
548
563
func ensureDir (path string ) error {
549
564
_ , err := os .Stat (path )
550
565
if os .IsNotExist (err ) {
566
+ // This fixes a issue where Go reads `/c/` as `C:\c\` and creates
567
+ // empty directories on the client that don't need to exist.
568
+ if runtime .GOOS == "windows" && strings .HasPrefix (path , "/c/" ) {
569
+ path = "C:" + path [2 :]
570
+ }
551
571
err = os .MkdirAll (path , 0750 )
552
572
}
553
573
@@ -608,3 +628,26 @@ func parseGCPSSHCmd(instance string) (ip, sshFlags string, err error) {
608
628
609
629
return strings .TrimSpace (userIP ), sshFlags , nil
610
630
}
631
+
632
+ // gitbashWindowsDir strips a the msys2 install directory from the beginning of
633
+ // the path. On msys2, if a user provides `/workspace` sshcode will receive
634
+ // `C:/msys64/workspace` which won't work on the remote host.
635
+ func gitbashWindowsDir (dir string ) string {
636
+
637
+ // Don't bother figuring out path if it's relative to home dir.
638
+ if strings .HasPrefix (dir , "~/" ) {
639
+ if dir == "~" {
640
+ return "~/"
641
+ }
642
+ return dir
643
+ }
644
+
645
+ mingwPrefix , err := exec .Command ("sh" , "-c" , "{ cd / && pwd -W; }" ).Output ()
646
+ if err != nil {
647
+ // Default to a sane location.
648
+ mingwPrefix = []byte ("C:/mingw64" )
649
+ }
650
+
651
+ prefix := strings .TrimSuffix (string (mingwPrefix ), "/\n " )
652
+ return strings .TrimPrefix (dir , prefix )
653
+ }
0 commit comments