4
4
package impl
5
5
6
6
import (
7
- "fmt"
8
7
"os"
9
- "sort "
8
+ "slices "
10
9
"strings"
11
10
)
12
11
13
12
const devboxSetPrefix = "__DEVBOX_SET_"
14
13
14
+ // mapToPairs creates a slice of environment variable "key=value" pairs from a
15
+ // map.
15
16
func mapToPairs (m map [string ]string ) []string {
16
- pairs := []string {}
17
+ pairs := make ([]string , len (m ))
18
+ i := 0
17
19
for k , v := range m {
18
- pairs = append (pairs , fmt .Sprintf ("%s=%s" , k , v ))
20
+ pairs [i ] = k + "=" + v
21
+ i ++
19
22
}
23
+ slices .Sort (pairs ) // for reproducibility
20
24
return pairs
21
25
}
22
26
27
+ // pairsToMap creates a map from a slice of "key=value" environment variable
28
+ // pairs. Note that maps are not ordered, which can affect the final variable
29
+ // values when pairs contains duplicate keys.
23
30
func pairsToMap (pairs []string ) map [string ]string {
24
- vars := map [string ]string {}
31
+ vars := make ( map [string ]string , len ( pairs ))
25
32
for _ , p := range pairs {
26
33
k , v , ok := strings .Cut (p , "=" )
27
34
if ! ok {
@@ -32,14 +39,19 @@ func pairsToMap(pairs []string) map[string]string {
32
39
return vars
33
40
}
34
41
35
- // exportify takes a map of [string]string and returns a single string
36
- // of the form export KEY="VAL"; and escapes all the vals from special characters.
42
+ // exportify formats vars as a line-separated string of shell export statements.
43
+ // Each line is of the form `export key="value";` with any special characters in
44
+ // value escaped. This means that the shell will always interpret values as
45
+ // literal strings; no variable expansion or command substitution will take
46
+ // place.
37
47
func exportify (vars map [string ]string ) string {
38
- keys := make ([]string , 0 , len (vars ))
48
+ keys := make ([]string , len (vars ))
49
+ i := 0
39
50
for k := range vars {
40
- keys = append (keys , k )
51
+ keys [i ] = k
52
+ i ++
41
53
}
42
- sort . Strings (keys )
54
+ slices . Sort (keys ) // for reproducibility
43
55
44
56
strb := strings.Builder {}
45
57
for _ , k := range keys {
@@ -60,56 +72,6 @@ func exportify(vars map[string]string) string {
60
72
return strings .TrimSpace (strb .String ())
61
73
}
62
74
63
- // exportify takes a map of [string]string and returns an array of string
64
- // of the form KEY="VAL" and escapes all the vals from special characters.
65
- func keyEqualsValue (vars map [string ]string ) []string {
66
- keys := make ([]string , 0 , len (vars ))
67
- for k := range vars {
68
- keys = append (keys , k )
69
- }
70
- keyValues := make ([]string , 0 , len (vars ))
71
- sort .Strings (keys )
72
-
73
- for _ , k := range keys {
74
- if isApproved (k ) {
75
- strb := strings.Builder {}
76
- strb .WriteString (k )
77
- strb .WriteString (`=` )
78
- for _ , r := range vars [k ] {
79
- switch r {
80
- // Special characters inside double quotes:
81
- // https://pubs.opengroup.org/onlinepubs/009604499/utilities/xcu_chap02.html#tag_02_02_03
82
- case '$' , '`' , '"' , '\\' , '\n' :
83
- strb .WriteRune ('\\' )
84
- }
85
- strb .WriteRune (r )
86
- }
87
- keyValues = append (keyValues , strb .String ())
88
- }
89
- }
90
- return keyValues
91
- }
92
-
93
- func isApproved (key string ) bool {
94
- // list to keys
95
- // should find the corrupt key
96
- troublingEnvKeys := []string {
97
- "HOME" ,
98
- "NODE_CHANNEL_FD" ,
99
- }
100
- approved := true
101
- for _ , ak := range troublingEnvKeys {
102
- // DEVBOX_OG_PATH_<hash> being set causes devbox global shellenv or overwrite
103
- // the PATH after vscode opens and resets it to global shellenv
104
- // This causes vscode terminal to not be able to find devbox packages
105
- // after reopen in devbox environment action is called
106
- if key == ak || strings .HasPrefix (key , "DEVBOX_OG_PATH" ) {
107
- approved = false
108
- }
109
- }
110
- return approved
111
- }
112
-
113
75
// addEnvIfNotPreviouslySetByDevbox adds the key-value pairs from new to existing,
114
76
// but only if the key was not previously set by devbox
115
77
// Caveat, this won't mark the values as set by devbox automatically. Instead,
0 commit comments