@@ -37,6 +37,7 @@ const (
37
37
type Shell struct {
38
38
name name
39
39
binPath string
40
+ env []string
40
41
userShellrcPath string
41
42
planInitHook string
42
43
@@ -114,6 +115,14 @@ func WithHistoryFile(historyFile string) ShellOption {
114
115
}
115
116
}
116
117
118
+ func WithEnvVariables (envVariables map [string ]string ) ShellOption {
119
+ return func (s * Shell ) {
120
+ for k , v := range envVariables {
121
+ s .env = append (s .env , fmt .Sprintf ("%s=%s" , k , v ))
122
+ }
123
+ }
124
+ }
125
+
117
126
// rcfilePath returns the absolute path for an rcfile, which is usually in the
118
127
// user's home directory. It doesn't guarantee that the file exists.
119
128
func rcfilePath (basename string ) string {
@@ -134,21 +143,23 @@ func (s *Shell) Run(nixShellFilePath string) error {
134
143
// directories that are incompatible.
135
144
parentPath := cleanEnvPath (os .Getenv ("PATH" ), nixProfileDirs )
136
145
137
- env := append (
138
- os .Environ (),
146
+ env := append (s .env , os .Environ ()... )
147
+ env = append (
148
+ env ,
139
149
"PARENT_PATH=" + parentPath ,
140
150
"NIX_PROFILES=" + strings .Join (nixProfileDirs , " " ),
141
151
142
152
// Prevent the user's shellrc from re-sourcing nix-daemon.sh
143
153
// inside the devbox shell.
144
154
"__ETC_PROFILE_NIX_SOURCED=1" ,
145
155
)
156
+ debug .Log ("Running nix-shell with environment: %v" , env )
146
157
147
158
// Launch a fallback shell if we couldn't find the path to the user's
148
159
// default shell.
149
160
if s .binPath == "" {
150
161
cmd := exec .Command ("nix-shell" , "--pure" )
151
- cmd .Args = append (cmd .Args , toKeepArgs (env )... )
162
+ cmd .Args = append (cmd .Args , toKeepArgs (env , buildAllowList ( s . env ) )... )
152
163
cmd .Args = append (cmd .Args , nixShellFilePath )
153
164
cmd .Env = env
154
165
cmd .Stdin = os .Stdin
@@ -160,7 +171,7 @@ func (s *Shell) Run(nixShellFilePath string) error {
160
171
}
161
172
162
173
cmd := exec .Command ("nix-shell" , "--command" , s .execCommand (), "--pure" )
163
- cmd .Args = append (cmd .Args , toKeepArgs (env )... )
174
+ cmd .Args = append (cmd .Args , toKeepArgs (env , buildAllowList ( s . env ) )... )
164
175
cmd .Args = append (cmd .Args , nixShellFilePath )
165
176
cmd .Env = env
166
177
cmd .Stdin = os .Stdin
@@ -374,16 +385,25 @@ var envToKeep = map[string]bool{
374
385
"SSL_CERT_FILE" : true , // The path to non-Nix SSL certificates (used by some Nix and non-Nix programs).
375
386
}
376
387
388
+ func buildAllowList (allowList []string ) map [string ]bool {
389
+ for _ , kv := range allowList {
390
+ key , _ , _ := strings .Cut (kv , "=" )
391
+ envToKeep [key ] = true
392
+ }
393
+ return envToKeep
394
+ }
395
+
377
396
// toKeepArgs takes a slice of environment variables in key=value format and
378
397
// builds a slice of "--keep" arguments that tell nix-shell which ones to
379
398
// keep.
380
399
//
381
- // See envToKeep for the full set of kept environment variables.
382
- func toKeepArgs (env []string ) []string {
383
- args := make ([]string , 0 , len (envToKeep )* 2 )
400
+ // See envToKeep for the full set of permanent kept environment variables.
401
+ // We also --keep any variables set by package configuration.
402
+ func toKeepArgs (env []string , allowList map [string ]bool ) []string {
403
+ args := make ([]string , 0 , len (allowList )* 2 )
384
404
for _ , kv := range env {
385
405
key , _ , _ := strings .Cut (kv , "=" )
386
- if envToKeep [key ] {
406
+ if allowList [key ] {
387
407
args = append (args , "--keep" , key )
388
408
}
389
409
}
0 commit comments