Skip to content

Commit 985b007

Browse files
committed
On Windows, add the COMPOSE_CONVERT_WINDOWS_PATHS environment variable
to the ouput of the env command. Signed-off-by: Joffrey F <joffrey@docker.com>
1 parent 983bdb3 commit 985b007

File tree

2 files changed

+96
-1
lines changed

2 files changed

+96
-1
lines changed

commands/env.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"os"
77
"path/filepath"
8+
"runtime"
89
"strings"
910
"text/template"
1011

@@ -16,12 +17,13 @@ import (
1617
)
1718

1819
const (
19-
envTmpl = `{{ .Prefix }}DOCKER_TLS_VERIFY{{ .Delimiter }}{{ .DockerTLSVerify }}{{ .Suffix }}{{ .Prefix }}DOCKER_HOST{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}{{ .Prefix }}DOCKER_CERT_PATH{{ .Delimiter }}{{ .DockerCertPath }}{{ .Suffix }}{{ .Prefix }}DOCKER_MACHINE_NAME{{ .Delimiter }}{{ .MachineName }}{{ .Suffix }}{{ if .NoProxyVar }}{{ .Prefix }}{{ .NoProxyVar }}{{ .Delimiter }}{{ .NoProxyValue }}{{ .Suffix }}{{end}}{{ .UsageHint }}`
20+
envTmpl = `{{ .Prefix }}DOCKER_TLS_VERIFY{{ .Delimiter }}{{ .DockerTLSVerify }}{{ .Suffix }}{{ .Prefix }}DOCKER_HOST{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}{{ .Prefix }}DOCKER_CERT_PATH{{ .Delimiter }}{{ .DockerCertPath }}{{ .Suffix }}{{ .Prefix }}DOCKER_MACHINE_NAME{{ .Delimiter }}{{ .MachineName }}{{ .Suffix }}{{ if .ComposePathsVar }}{{ .Prefix }}COMPOSE_CONVERT_WINDOWS_PATHS{{ .Delimiter }}true{{ .Suffix }}{{end}}{{ if .NoProxyVar }}{{ .Prefix }}{{ .NoProxyVar }}{{ .Delimiter }}{{ .NoProxyValue }}{{ .Suffix }}{{end}}{{ .UsageHint }}`
2021
)
2122

2223
var (
2324
errImproperUnsetEnvArgs = errors.New("Error: Expected no machine name when the -u flag is present")
2425
defaultUsageHinter UsageHintGenerator
26+
runtimeOS = func() string { return runtime.GOOS }
2527
)
2628

2729
func init() {
@@ -39,6 +41,7 @@ type ShellConfig struct {
3941
MachineName string
4042
NoProxyVar string
4143
NoProxyValue string
44+
ComposePathsVar bool
4245
}
4346

4447
func cmdEnv(c CommandLine, api libmachine.API) error {
@@ -121,6 +124,10 @@ func shellCfgSet(c CommandLine, api libmachine.API) (*ShellConfig, error) {
121124
shellCfg.NoProxyValue = noProxyValue
122125
}
123126

127+
if runtimeOS() == "windows" {
128+
shellCfg.ComposePathsVar = true
129+
}
130+
124131
switch userShell {
125132
case "fish":
126133
shellCfg.Prefix = "set -gx "

commands/env_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ func TestShellCfgSet(t *testing.T) {
104104
// these `env` operations.
105105
defer revertUsageHinter(defaultUsageHinter)
106106
defaultUsageHinter = &SimpleUsageHintGenerator{usageHint}
107+
isRuntimeWindows := runtimeOS() == "windows"
107108

108109
var tests = []struct {
109110
description string
@@ -159,6 +160,7 @@ func TestShellCfgSet(t *testing.T) {
159160
DockerTLSVerify: "1",
160161
UsageHint: usageHint,
161162
MachineName: "quux",
163+
ComposePathsVar: isRuntimeWindows,
162164
},
163165
expectedErr: nil,
164166
},
@@ -195,6 +197,7 @@ func TestShellCfgSet(t *testing.T) {
195197
DockerTLSVerify: "1",
196198
UsageHint: usageHint,
197199
MachineName: defaultMachineName,
200+
ComposePathsVar: isRuntimeWindows,
198201
},
199202
expectedErr: nil,
200203
},
@@ -231,6 +234,7 @@ func TestShellCfgSet(t *testing.T) {
231234
DockerTLSVerify: "1",
232235
UsageHint: usageHint,
233236
MachineName: "quux",
237+
ComposePathsVar: isRuntimeWindows,
234238
},
235239
expectedErr: nil,
236240
},
@@ -267,6 +271,7 @@ func TestShellCfgSet(t *testing.T) {
267271
DockerTLSVerify: "1",
268272
UsageHint: usageHint,
269273
MachineName: "quux",
274+
ComposePathsVar: isRuntimeWindows,
270275
},
271276
expectedErr: nil,
272277
},
@@ -303,6 +308,7 @@ func TestShellCfgSet(t *testing.T) {
303308
DockerTLSVerify: "1",
304309
UsageHint: usageHint,
305310
MachineName: "quux",
311+
ComposePathsVar: isRuntimeWindows,
306312
},
307313
expectedErr: nil,
308314
},
@@ -339,6 +345,7 @@ func TestShellCfgSet(t *testing.T) {
339345
DockerTLSVerify: "1",
340346
UsageHint: usageHint,
341347
MachineName: "quux",
348+
ComposePathsVar: isRuntimeWindows,
342349
},
343350
expectedErr: nil,
344351
},
@@ -381,6 +388,7 @@ func TestShellCfgSet(t *testing.T) {
381388
NoProxyVar: "NO_PROXY",
382389
NoProxyValue: "1.2.3.4", // From FakeDriver
383390
MachineName: "quux",
391+
ComposePathsVar: isRuntimeWindows,
384392
},
385393
noProxyVar: "NO_PROXY",
386394
noProxyValue: "",
@@ -425,6 +433,7 @@ func TestShellCfgSet(t *testing.T) {
425433
NoProxyVar: "no_proxy",
426434
NoProxyValue: "192.168.59.1,1.2.3.4", // From FakeDriver
427435
MachineName: "quux",
436+
ComposePathsVar: isRuntimeWindows,
428437
},
429438
noProxyVar: "no_proxy",
430439
noProxyValue: "192.168.59.1",
@@ -448,6 +457,85 @@ func TestShellCfgSet(t *testing.T) {
448457
}
449458
}
450459

460+
func TestShellCfgSetWindowsRuntime(t *testing.T) {
461+
const (
462+
usageHint = "This is a usage hint"
463+
)
464+
465+
// TODO: This should be embedded in some kind of wrapper struct for all
466+
// these `env` operations.
467+
defer revertUsageHinter(defaultUsageHinter)
468+
defaultUsageHinter = &SimpleUsageHintGenerator{usageHint}
469+
470+
var tests = []struct {
471+
description string
472+
commandLine CommandLine
473+
api libmachine.API
474+
connChecker check.ConnChecker
475+
noProxyVar string
476+
noProxyValue string
477+
expectedShellCfg *ShellConfig
478+
expectedErr error
479+
}{
480+
{
481+
description: "powershell set happy path",
482+
commandLine: &commandstest.FakeCommandLine{
483+
CliArgs: []string{"quux"},
484+
LocalFlags: &commandstest.FakeFlagger{
485+
Data: map[string]interface{}{
486+
"shell": "powershell",
487+
"swarm": false,
488+
"no-proxy": false,
489+
},
490+
},
491+
},
492+
api: &libmachinetest.FakeAPI{
493+
Hosts: []*host.Host{
494+
{
495+
Name: "quux",
496+
},
497+
},
498+
},
499+
connChecker: &FakeConnChecker{
500+
DockerHost: "tcp://1.2.3.4:2376",
501+
AuthOptions: nil,
502+
Err: nil,
503+
},
504+
expectedShellCfg: &ShellConfig{
505+
Prefix: "$Env:",
506+
Suffix: "\"\n",
507+
Delimiter: " = \"",
508+
DockerCertPath: filepath.Join(mcndirs.GetMachineDir(), "quux"),
509+
DockerHost: "tcp://1.2.3.4:2376",
510+
DockerTLSVerify: "1",
511+
UsageHint: usageHint,
512+
MachineName: "quux",
513+
ComposePathsVar: true,
514+
},
515+
expectedErr: nil,
516+
},
517+
}
518+
519+
actualRuntimeOS := runtimeOS
520+
runtimeOS = func() string { return "windows" }
521+
defer func() { runtimeOS = actualRuntimeOS }()
522+
523+
for _, test := range tests {
524+
// TODO: Ideally this should not hit the environment at all but
525+
// rather should go through an interface.
526+
os.Setenv(test.noProxyVar, test.noProxyValue)
527+
528+
t.Log(test.description)
529+
530+
check.DefaultConnChecker = test.connChecker
531+
shellCfg, err := shellCfgSet(test.commandLine, test.api)
532+
assert.Equal(t, test.expectedShellCfg, shellCfg)
533+
assert.Equal(t, test.expectedErr, err)
534+
535+
os.Unsetenv(test.noProxyVar)
536+
}
537+
}
538+
451539
func TestShellCfgUnset(t *testing.T) {
452540
const (
453541
usageHint = "This is the unset usage hint"

0 commit comments

Comments
 (0)