@@ -5,16 +5,24 @@ import (
55 "fmt"
66 "os/exec"
77 "runtime"
8+ "slices"
89 "strings"
910
1011 "github.com/loft-sh/devpod/pkg/command"
1112 "github.com/loft-sh/log"
1213 "github.com/skratchdot/open-golang/open"
1314)
1415
15- func Open (ctx context.Context , workspace , folder string , newWindow bool , flavor Flavor , log log.Logger ) error {
16+ const (
17+ FlatpakStable string = "com.visualstudio.code"
18+ FlatpakInsiders string = "com.visualstudio.code.insiders"
19+ FlatpakCodium string = "com.vscodium.codium"
20+ FlatpakCodiumInsiders string = "com.vscodium.codium-insiders"
21+ )
22+
23+ func Open (ctx context.Context , workspace , folder string , newWindow bool , flavor Flavor , sshConfigPath string , log log.Logger ) error {
1624 log .Infof ("Starting %s..." , flavor )
17- err := openViaCLI (ctx , workspace , folder , newWindow , flavor , log )
25+ err := openViaCLI (ctx , workspace , folder , newWindow , flavor , sshConfigPath , log )
1826 if err != nil {
1927 log .Debugf ("Error opening %s via cli: %v" , flavor , err )
2028 } else {
@@ -37,6 +45,8 @@ func openViaBrowser(workspace, folder string, newWindow bool, flavor Flavor, log
3745 protocol = `positron://`
3846 case FlavorCodium :
3947 protocol = `codium://`
48+ case FlavorCodiumInsiders :
49+ protocol = `codium-insiders://`
4050 }
4151
4252 openURL := protocol + `vscode-remote/ssh-remote+` + workspace + `.devpod/` + folder
@@ -54,20 +64,44 @@ func openViaBrowser(workspace, folder string, newWindow bool, flavor Flavor, log
5464 return nil
5565}
5666
57- func openViaCLI (ctx context.Context , workspace , folder string , newWindow bool , flavor Flavor , log log.Logger ) error {
67+ func openViaCLI (ctx context.Context , workspace , folder string , newWindow bool , flavor Flavor , sshConfigPath string , log log.Logger ) error {
5868 // try to find code cli
59- codePath := findCLI (flavor )
60- if codePath == "" {
69+ codePath := findCLI (flavor , log )
70+ if codePath == nil {
6171 return fmt .Errorf ("couldn't find the %s binary" , flavor )
6272 }
6373
74+ if codePath [0 ] == "flatpak" {
75+ log .Debugf ("Running with Flatpak suing the package %s." , codePath [2 ])
76+ out , err := exec .Command (codePath [0 ], "ps" , "--columns=application" ).Output ()
77+ if err != nil {
78+ return command .WrapCommandError (out , err )
79+ }
80+ splitted := strings .Split (string (out ), "\n " )
81+ foundRunning := false
82+ // Ignore the header
83+ for _ , str := range splitted [1 :] {
84+ if strings .TrimSpace (str ) == codePath [2 ] {
85+ foundRunning = true
86+ break
87+ }
88+ }
89+
90+ if foundRunning {
91+ log .Warnf ("The IDE is already running via Flatpak. If you are encountering SSH connectivity issues, make sure to give read access to your SSH config file (e.g flatpak override %s --filesystem=%s) and restart your IDE." , codePath [2 ], sshConfigPath )
92+ }
93+
94+ codePath = slices .Insert (codePath , 2 , fmt .Sprintf ("--filesystem=%s:ro" , sshConfigPath ))
95+ }
96+
6497 sshExtension := "ms-vscode-remote.remote-ssh"
65- if flavor == FlavorCodium {
98+ if flavor == FlavorCodium || flavor == FlavorCodiumInsiders {
6699 sshExtension = "jeanp413.open-remote-ssh"
67100 }
68101
69102 // make sure ms-vscode-remote.remote-ssh is installed
70- out , err := exec .Command (codePath , "--list-extensions" ).Output ()
103+ listArgs := append (codePath , "--list-extensions" )
104+ out , err := exec .Command (listArgs [0 ], listArgs [1 :]... ).Output ()
71105 if err != nil {
72106 return command .WrapCommandError (out , err )
73107 }
@@ -84,9 +118,9 @@ func openViaCLI(ctx context.Context, workspace, folder string, newWindow bool, f
84118
85119 // install remote-ssh extension
86120 if ! found {
87- args := [] string { "--install-extension" , sshExtension }
88- log .Debugf ("Run vscode command %s %s" , codePath , strings .Join (args , " " ))
89- out , err := exec .CommandContext (ctx , codePath , args ... ).Output ()
121+ args := append ( codePath , "--install-extension" , sshExtension )
122+ log .Debugf ("Run vscode command %s %s" , args [ 0 ] , strings .Join (args [ 1 :] , " " ))
123+ out , err := exec .CommandContext (ctx , args [ 0 ] , args [ 1 :] ... ).Output ()
90124 if err != nil {
91125 return fmt .Errorf ("install ssh extension: %w" , command .WrapCommandError (out , err ))
92126 }
@@ -104,66 +138,56 @@ func openViaCLI(ctx context.Context, workspace, folder string, newWindow bool, f
104138 }
105139 // Needs to be separated by `=` because of windows
106140 folderUriArg := fmt .Sprintf ("--folder-uri=vscode-remote://ssh-remote+%s.devpod/%s" , workspace , folder )
141+ args = append (codePath , args ... )
107142 args = append (args , folderUriArg )
108- log .Debugf ("Run %s command %s %s" , flavor , codePath , strings .Join (args , " " ))
109- out , err = exec .CommandContext (ctx , codePath , args ... ).CombinedOutput ()
143+ log .Debugf ("Run %s command %s %s" , flavor , args [ 0 ] , strings .Join (args [ 1 :] , " " ))
144+ out , err = exec .CommandContext (ctx , args [ 0 ] , args [ 1 :] ... ).CombinedOutput ()
110145 if err != nil {
111146 return command .WrapCommandError (out , err )
112147 }
113148
114149 return nil
115150}
116151
117- func findCLI (flavor Flavor ) string {
118- if flavor == FlavorStable {
119- if command .Exists ("code" ) {
120- return "code"
121- } else if runtime .GOOS == "darwin" && command .Exists ("/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code" ) {
122- return "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code"
123- }
124-
125- return ""
152+ func existsInFlatpak (packageName string , log log.Logger ) bool {
153+ if err := exec .Command ("flatpak" , "info" , packageName ).Run (); err == nil {
154+ return true
155+ } else {
156+ log .Debugf ("Flatpak command for %s returned: %s" , packageName , err )
126157 }
158+ return false
159+ }
127160
128- if flavor == FlavorInsiders {
129- if command .Exists ("code-insiders" ) {
130- return "code-insiders"
131- } else if runtime .GOOS == "darwin" && command .Exists ("/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code" ) {
132- return "/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code"
133- }
134-
135- return ""
161+ func getCommandArgs (execName , macOSPath , flatpakPackage string , log log.Logger ) []string {
162+ if command .Exists (execName ) {
163+ return []string {execName }
136164 }
137165
138- if flavor == FlavorCursor {
139- if command .Exists ("cursor" ) {
140- return "cursor"
141- } else if runtime .GOOS == "darwin" && command .Exists ("/Applications/Cursor.app/Contents/Resources/app/bin/cursor" ) {
142- return "/Applications/Cursor.app/Contents/Resources/app/bin/cursor"
143- }
144-
145- return ""
166+ if runtime .GOOS == "darwin" && command .Exists (macOSPath ) {
167+ return []string {macOSPath }
146168 }
147169
148- if flavor == FlavorPositron {
149- if command .Exists ("positron" ) {
150- return "positron"
151- } else if runtime .GOOS == "darwin" && command .Exists ("/Applications/Positron.app/Contents/Resources/app/bin/positron" ) {
152- return "/Applications/Positron.app/Contents/Resources/app/bin/positron"
153- }
154-
155- return ""
170+ if runtime .GOOS == "linux" && flatpakPackage != "" && command .Exists ("flatpak" ) && existsInFlatpak (flatpakPackage , log ) {
171+ return []string {"flatpak" , "run" , flatpakPackage }
156172 }
157173
158- if flavor == FlavorCodium {
159- if command .Exists ("codium" ) {
160- return "codium"
161- } else if runtime .GOOS == "darwin" && command .Exists ("/Applications/Codium.app/Contents/Resources/app/bin/codium" ) {
162- return "/Applications/Codium.app/Contents/Resources/app/bin/codium"
163- }
174+ return nil
175+ }
164176
165- return ""
177+ func findCLI (flavor Flavor , log log.Logger ) []string {
178+ switch flavor {
179+ case FlavorStable :
180+ return getCommandArgs ("code" , "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code" , FlatpakStable , log )
181+ case FlavorInsiders :
182+ return getCommandArgs ("code-insiders" , "/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code" , FlatpakInsiders , log )
183+ case FlavorCursor :
184+ return getCommandArgs ("cursor" , "/Applications/Cursor.app/Contents/Resources/app/bin/cursor" , "" , log )
185+ case FlavorPositron :
186+ return getCommandArgs ("positron" , "/Applications/Positron.app/Contents/Resources/app/bin/positron" , "" , log )
187+ case FlavorCodium :
188+ return getCommandArgs ("codium" , "/Applications/Codium.app/Contents/Resources/app/bin/codium" , FlatpakCodium , log )
189+ case FlavorCodiumInsiders :
190+ return getCommandArgs ("codium-insiders" , "/Applications/CodiumInsiders.app/Contents/Resources/app/bin/codium-insiders" , FlatpakCodiumInsiders , log )
166191 }
167-
168- return ""
192+ return nil
169193}
0 commit comments