Skip to content
This repository has been archived by the owner on Sep 26, 2021. It is now read-only.

shell selection for env #1033

Merged
merged 9 commits into from Apr 30, 2015
Merged

Conversation

ehazlett
Copy link
Contributor

This adds PowerShell support and shell selection support (to force selection for bash, fish, etc) for the env command.

Refs #906

@ehazlett ehazlett added this to the 0.3.0 milestone Apr 20, 2015
@nathanleclaire
Copy link
Contributor

Why not switch to a text/template? It seems likely to be easier to understand and more maintainable given how complex this is getting.

@ehazlett
Copy link
Contributor Author

That works. Thx

@ehazlett ehazlett changed the title WIP: shell selection for env shell selection for env Apr 20, 2015
@ehazlett
Copy link
Contributor Author

@nathanleclaire updated PTAL

@nathanleclaire
Copy link
Contributor

Cool. I was thinking something more along the lines of this for the template (to help with readability):

{{ .Prefix }}DOCKER_TLS_VERIFY{{ .Delimiter }}{{ .DockerTLSVerify }}{{ .Suffix }}
{{ .Prefix }}DOCKER_HOST{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}
{{ .Prefix }}DOCKER_CERT_PATH{{ .Delimiter }}{{ .DockerCertPath }}{{ .Suffix }}
# {{ .UsageHint }}

(then the newlines would just be taken out of the suffix)

@nathanleclaire
Copy link
Contributor

On second thought, I think we can cut most of the verbosity in the switches down by having a template which does stuff like so:

{{ if .Shell -eq "fish" }}
set -x DOCKER_TLS_VERIFY {{ .DockerTlsVerify }};
set -x DOCKER_HOST {{ .DockerHost }};
set -x DOCKER_CERT_PATH {{ .DockerCertPath }};
{{ end }}
{{ if .Shell -eq "bash" }}
export DOCKER_TLS_VERIFY={{ .DockerTlsVerify }}
export DOCKER_HOST={{ .DockerHost }}
export DOCKER_CERT_PATH={{ .DockerCertPath }}
{{ end }}
# {{ .UsageHint }}

Does it sound good to you? It's a little more verbose in the actual template itself but I think it will be a lot more readable / easier to understand to anyone looking at the code.

@ehazlett
Copy link
Contributor Author

Fixing test.

The problem is the windows shells are very, very picky about whitespace. For example, if there is a line starting with a blank in powershell it dies.

Edit: as well as newlines.

@nathanleclaire
Copy link
Contributor

@ehazlett I see. That shouldn't be a problem if we're spitting out only the powershell-specific template when we are in powershell, wouldn't it? The example in that last comment would only output the relevant bits based on the shell.

(the .UsageHint could just be per-shell if needed)


func detectShell() (string, error) {
// attempt to get the SHELL env var
shell := filepath.Base(os.Getenv("SHELL"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this wrapped in filepath.Base so that we get the value we expect in case SHELL contains something like /usr/bin/zsh? Just making sure I understand correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct -- this is the current behavior today.

@blacktop
Copy link

Don't forget zsh homies! 😎

@ehazlett
Copy link
Contributor Author

@blacktop i believe zsh behaves the same as bash -- that's what we do today :)

@ehazlett
Copy link
Contributor Author

Tests updated. @nathanleclaire PTAL

@ehazlett
Copy link
Contributor Author

I think this would be better using some split text/template (as @nathanleclaire mentioned) however, there are several nuances regarding whitespace with the various terminals. I think we should continue on with this and we can revisit if we continue to add / or want to optimize.

@blacktop
Copy link

@ehazlett, you right, you right. 😉

I could have sworn that I used to be able to set the env like with $(boot2docker shellinit). i.e. $(docker-machine env dev), which gives the error: export: not valid in this context: shell:

I see now that I am supposed to type: eval "$(docker-machine env dev)" instead.

@hairyhenderson
Copy link
Contributor

@blacktop - yeah - eval is necessary now (see #795 and #783).

@ehazlett
Copy link
Contributor Author

@nathanleclaire that sound good to you?

@nathanleclaire
Copy link
Contributor

@ehazlett Yes, definitely- can you please add some docs? At least a small paragraph and example explaining that env works with cmd.exe and Powershell as well. I will be ready to go on this shortly after I get a chance to actually play around with it a bit, code looks good.

@nathanleclaire
Copy link
Contributor

Also, should we maybe not be hardcoding the docker-machine binary name?

@ehazlett
Copy link
Contributor Author

@nathanleclaire updated to remove the hardcoded binary.

@nathanleclaire
Copy link
Contributor

@ehazlett Nice, thanks - I'm getting some issues when using the command hint on Powershell. WDYT?

image

EDIT: Ah, the hint is slightly off. We should be including --shell etc. in the hint as well... I'll try that.

@nathanleclaire
Copy link
Contributor

Yeah, it works flawlessly if you do:

$ docker-machine env --shell powershell dev | Invoke-Expression

@nathanleclaire
Copy link
Contributor

Other than that, testing on Powershell and cmd.exe looks good on my end.

@ehazlett
Copy link
Contributor Author

Tests fixed. Usage hint updated for powershell.

ping @nathanleclaire

@nathanleclaire
Copy link
Contributor

LGTM let's do this 👍

Created separate issue to track documenting this : #1054

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
@ehazlett
Copy link
Contributor Author

/cc @ahmetalpbalkan would you mind taking a look to make sure this seems sane?

shell := filepath.Base(os.Getenv("SHELL"))
// none detected; check for windows env
if shell == "." && os.Getenv("windir") != "" {
log.Printf("On Windows, please specify either cmd or powershell with the --shell flag.\n\n")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be nice to put cmd, powershell strings in single quotes for readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point -- thx!

@ahmetb
Copy link
Contributor

ahmetb commented Apr 29, 2015

@ehazlett if they're working fine, LGTM

It's sort of hard to trace from the code by eye. So maybe if can you please paste the outputs/screenshots from cmd/powershell (without piping to invoke-expression) I can double check it for you.

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
@ehazlett
Copy link
Contributor Author

2015-04-30-110610_906x319_scrot

@ehazlett
Copy link
Contributor Author

2015-04-30-121847_1023x329_scrot

ehazlett added a commit that referenced this pull request Apr 30, 2015
@ehazlett ehazlett merged commit 03c245c into docker:master Apr 30, 2015
@ehazlett ehazlett deleted the env-shell-selection branch April 30, 2015 18:03
@masaeedu
Copy link

masaeedu commented Jul 8, 2015

Could the docs be updated to show how this can be used (as opposed to msysgit)?

@nathanleclaire
Copy link
Contributor

@masaeedu Take a look at the --shell flag documentation here.

@StefanScherer
Copy link
Member

@nathanleclaire Great, thanks for updating the docs.

One small thing for the cmd.exe is that the # sign is not a valid comment sign for the cmd.exe.

Here is a small proposal how it could look like for cmd.exe with rem and a command that sets the environment variables:

$ docker-machine.exe env --shell cmd dev
set DOCKER_TLS_VERIFY=1
set DOCKER_HOST=tcp://192.168.99.101:2376
set DOCKER_CERT_PATH=C:\Users\captain\.docker\machine\machines\dev
set DOCKER_MACHINE_NAME=dev
rem Run this command to configure your shell:
rem for /f "tokens=*" %i in ('docker-machine.exe env --shell=cmd dev') do %i

And in the powershell sample there is missing the is missing the machine name dev:

# Run this command to configure your shell:
# docker-machine.exe env --shell=powershell dev | Invoke-Expression

@ahmetb
Copy link
Contributor

ahmetb commented Jul 8, 2015

@StefanScherer cmd.exe output of env cmd was designed for copy-paste.

Your proposal looks interesting. Care to put that in a proposal/pull request?

@StefanScherer
Copy link
Member

@ahmetalpbalkan Have a look at #1493 ;-)

@masaeedu
Copy link

masaeedu commented Jul 8, 2015

@StefanScherer Re: missing machine name in the powershell output; that is odd, because I'm using 0.3.0 and it works correctly for me:

PS C:\Users\msaeedud> docker-machine env --shell powershell boot2docker
$Env:DOCKER_TLS_VERIFY = "1"
$Env:DOCKER_HOST = "tcp://192.168.155.24:2376"
$Env:DOCKER_CERT_PATH = "C:\Users\msaeedud\.docker\machine\machines\boot2docker"
$Env:DOCKER_MACHINE_NAME = "boot2docker"
# Run this command to configure your shell:
# C:\ProgramData\chocolatey\lib\docker-machine\bin\docker-machine.exe env --shell=powershell boot2docker | Invoke-Expression

Note how my machine name, boot2docker, showed up in the comment.

@StefanScherer
Copy link
Member

@masaeedu I have seen that the sourcecode is correct. It is only missing in the docs.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants