Skip to content

Commit

Permalink
Support zsh, fish, and Powershell autocompletion, fixes #327 (#2234)
Browse files Browse the repository at this point in the history
* Bump spf13/cobra to v1.0.0
* Basic generation of zsh, fish, and powershell
* Add zsh instructions to install.sh
* Make the install_ddev.sh script install zsh completions if possible
* Add docs for completions
* Create a tarball of completion scripts
  • Loading branch information
rfay committed May 28, 2020
1 parent f2e54e4 commit e5bfb63
Show file tree
Hide file tree
Showing 40 changed files with 2,396 additions and 174 deletions.
21 changes: 14 additions & 7 deletions .circleci/generate_artifacts.sh
Expand Up @@ -12,7 +12,7 @@ BUILD_IMAGE_TARBALLS=false
ARTIFACTS=${1:-/artifacts}
BASE_DIR=$PWD

sudo mkdir -p $ARTIFACTS && sudo chmod 777 $ARTIFACTS
mkdir -p $ARTIFACTS || (sudo mkdir -p $ARTIFACTS && sudo chmod 777 $ARTIFACTS)
export VERSION=$(git describe --tags --always --dirty)

# If the version does not have a dash in it, it's not prerelease,
Expand Down Expand Up @@ -50,38 +50,45 @@ fi
# Generate and place extra items like autocomplete
$BUILTPATH/ddev_gen_autocomplete

# The completion scripts get placed into the linux build dir (.gotmp/bin)
# So now copy them into the real build directory
for dir in .gotmp/bin/darwin_amd64 .gotmp/bin/windows_amd64; do
cp .gotmp/bin/ddev_bash_completion.sh $dir
cp .gotmp/bin/ddev_*completion* $dir
done

# Generate macOS tarball/zipball
cd $BASE_DIR/.gotmp/bin/darwin_amd64
curl -sSL -o mkcert https://github.com/FiloSottile/mkcert/releases/download/${MKCERT_VERSION}/mkcert-${MKCERT_VERSION}-darwin-amd64 && chmod +x mkcert
tar -czf $ARTIFACTS/ddev_macos.$VERSION.tar.gz ddev ddev_bash_completion.sh mkcert
tar -czf $ARTIFACTS/ddev_macos.$VERSION.tar.gz ddev *completion*.sh mkcert

# Generate linux tarball/zipball
cd $BASE_DIR/.gotmp/bin
curl -sSL -o mkcert https://github.com/FiloSottile/mkcert/releases/download/${MKCERT_VERSION}/mkcert-${MKCERT_VERSION}-linux-amd64 && chmod +x mkcert
tar -czf $ARTIFACTS/ddev_linux.$VERSION.tar.gz ddev ddev_bash_completion.sh mkcert
tar -czf $ARTIFACTS/ddev_linux.$VERSION.tar.gz ddev *completion*.sh mkcert

# generate windows tarball/zipball
cd $BASE_DIR/.gotmp/bin/windows_amd64
curl -sSL -o mkcert.exe https://github.com/FiloSottile/mkcert/releases/download/${MKCERT_VERSION}/mkcert-${MKCERT_VERSION}-windows-amd64.exe
tar -czf $ARTIFACTS/ddev_windows.$VERSION.tar.gz ddev.exe ddev_bash_completion.sh mkcert.exe
zip $ARTIFACTS/ddev_windows.$VERSION.zip ddev.exe ddev_bash_completion.sh
tar -czf $ARTIFACTS/ddev_windows.$VERSION.tar.gz ddev.exe *completion*.sh mkcert.exe
zip $ARTIFACTS/ddev_windows.$VERSION.zip ddev.exe *completion*.sh
if [ -d chocolatey ]; then
tar -czf $ARTIFACTS/ddev_chocolatey.$VERSION.tar.gz chocolatey
fi

cp ddev_windows_installer*.exe $ARTIFACTS

# Create tarball of completion scripts
tar -czf $ARTIFACTS/ddev_shell_completion_scripts.$VERSION.tar.gz *completion*.sh

# Create macOS and Linux homebrew bottles
for os in sierra x86_64_linux ; do
NO_V_VERSION=${VERSION#v}
rm -rf /tmp/bottle
BOTTLE_BASE=/tmp/bottle/ddev/$NO_V_VERSION
mkdir -p $BOTTLE_BASE/{bin,etc/bash_completion.d}
mkdir -p $BOTTLE_BASE/{bin,etc/bash_completion.d,share/zsh-completions}
cp $BASE_DIR/.gotmp/bin/ddev_bash_completion.sh $BOTTLE_BASE/etc/bash_completion.d/ddev
cp $BASE_DIR/.gotmp/bin/ddev_zsh_completion.sh $BOTTLE_BASE/share/zsh-completions/_ddev

if [ "${os}" = "sierra" ]; then cp $BASE_DIR/.gotmp/bin/darwin_amd64/ddev $BOTTLE_BASE/bin ; fi
if [ "${os}" = "x86_64_linux" ]; then cp $BASE_DIR/.gotmp/bin/ddev $BOTTLE_BASE/bin ; fi
cp $BASE_DIR/{README.md,LICENSE} $BOTTLE_BASE
Expand Down
16 changes: 15 additions & 1 deletion cmd/ddev_gen_autocomplete/ddev_gen_autocomplete.go
Expand Up @@ -16,5 +16,19 @@ func main() {
util.CheckErr(err)
}
err := cmd.RootCmd.GenBashCompletionFile(filepath.Join(targetDir, "ddev_bash_completion.sh"))
util.CheckErr(err)
if err != nil {
util.Failed("could not generate ddev_bash_completion.sh: %v", err)
}
err = cmd.RootCmd.GenZshCompletionFile(filepath.Join(targetDir, "ddev_zsh_completion.sh"))
if err != nil {
util.Failed("could not generate ddev_zsh_completion.sh: %v", err)
}
err = cmd.RootCmd.GenFishCompletionFile(filepath.Join(targetDir, "ddev_fish_completion.sh"), true)
if err != nil {
util.Failed("could not generate ddev_fish_completion.sh: %v", err)
}
err = cmd.RootCmd.GenPowerShellCompletionFile(filepath.Join(targetDir, "ddev_powershell_completion.sh"))
if err != nil {
util.Failed("could not generate ddev_powershell_completion.sh: %v", err)
}
}
56 changes: 56 additions & 0 deletions docs/users/shell-completion.md
@@ -0,0 +1,56 @@
## Shell Completion

Most people like to have shell completion on the command line. In other words, when you're typing a command, you can hit <TAB> and the shell will show you what the options are. For example, if you type `ddev <TAB>`, you'll see all the possible commands. `ddev debug <TAB>` will show you the options for the command. And `ddev list -<TAB>` will show you all the flags available for `ddev list`.

Shells like bash and zsh need help to do this though, they have to know what the options are. DDEV-Local provides the necessary hint scripts, and if you use homebrew, they get installed automatically. But if you use oh-my-zsh, for example, you may have to manually install the hint script.

### tar Archive of Completion Scripts for Manual Deployment

Although most people will use techniques like homebrew for installation, a tar archive of the shell completion scripts is available in each release, called "ddev_shell_completion_scripts.<version>.tar.gz". If you need to manually install, you can download and untar the scripts, then copy them as needed to where they have to go. For example, `sudo cp ddev_bash_completion.sh /etc/bash_completion.d/ddev`.

Note that scripts for the fish shell and Windows Powershell are also provided, but no instructions are given here for deploying them.

## Bash Completion

**Bash Completion with Homebrew**: The easiest way to use bash completion on either macOS or Linux is to install with homebrew. `brew install bash-completion`. When you install it though, it will warn you with something like this, which may vary on your system.

```bash
Add the following line to your ~/.bash_profile:
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
```

*You need to add the suggested line to your ~/.bash_profile or ~/.profile to get it to work*, and then in the current shell you need tou `source ~/.bash_profile` or `source ~/.profile` to make it take effect. (You can also just open a new shell window.)

Then, if you're installing ddev from homebrew, each new release will automatically get a refreshed completions script.

**Bash Completion without Homebrew**: The completion script is exactly the same, it's just that you have to install it yourself. Each system may have a slightly different technique, and you'll need to figure it out. On Debian/Ubuntu, you would use [these instructions](http://crsouza.com/2008/07/28/enabling-bash-autocompletion-on-debian/) to enable bash-completion, and then `sudo mkdir -p /etc/bash_completion.d && sudo cp ddev_bash_completion.sh /etc/bash_completion.d`. This deploys the ddev_bash_completion.sh script where it needs to be. Again, every Linux distro has a different technique, and you may have to figure yours out.

### Zsh Completion

**Zsh Completion with Homebrew**: This works exactly the same as bash completion. `brew install zsh-completion`. You'll get instructions something like this:

```bash
if type brew &>/dev/null; then
FPATH=$(brew --prefix)/share/zsh-completions:$FPATH

autoload -Uz compinit
compinit
fi

You may also need to force rebuild `zcompdump`:

rm -f ~/.zcompdump; compinit

Additionally, if you receive "zsh compinit: insecure directories" warnings when attempting
to load these completions, you may need to run this:

chmod go-w '/usr/local/share'
```
So follow those instructions and your zsh should be set up.
### Oh-My-Zsh Completion
If you installed zsh with homebrew, ddev's completions will be automatically installed when you `brew install ddev`.
Otherwise, Oh-My-Zsh may be set up very differently in different places, so as a power zsh user you'll need to put ddev_bash_completion.sh where it belongs. `echo $fpath` will show you the places that it's most likely to belong. An obvious choice is ~/.oh-my-zsh/completions if that exists, so you can `mkdir -p ~/.oh-my-zsh/completions && cp ddev_zsh_completions.sh ~/.oh-my-zsh/completions/_ddev` and then `autoload -Uz compinit && compinit`.
5 changes: 3 additions & 2 deletions go.mod
Expand Up @@ -37,8 +37,9 @@ require (
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c // indirect
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/cobra v0.0.5
github.com/spf13/cobra v1.0.0
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.3.0
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
Expand All @@ -53,4 +54,4 @@ require (
gotest.tools v2.2.0+incompatible // indirect
)

go 1.13
go 1.14
7 changes: 7 additions & 0 deletions go.sum
Expand Up @@ -36,6 +36,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -190,8 +191,10 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/segmentio/backo-go v0.0.0-20160424052352-204274ad699c h1:rsRTAcCR5CeNLkvgBVSjQoDGRRt6kggsE6XYBqCv2KQ=
github.com/segmentio/backo-go v0.0.0-20160424052352-204274ad699c/go.mod h1:kJ9mm9YmoWSkk+oQ+5Cj8DEoRCX2JT6As4kEtIIOp1M=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.0.6 h1:hcP1GmhGigz/O7h1WVUM5KklBp1JoNS9FggWKdj/j3s=
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
Expand All @@ -211,12 +214,16 @@ github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Expand Up @@ -22,6 +22,7 @@ pages:
- 'Frequently-Asked Questions (FAQ)': 'users/faq.md'
- '.ddev/config.yaml Options': 'users/extend/config_yaml.md'
- 'Database Server Types': 'users/extend/database_types.md'
- 'Bash and Zsh Completion': 'users/shell-completion.md'
- 'Additional Project Hostnames': 'users/extend/additional-hostnames.md'
- 'Extending ddev':
- 'Extending and Customizing Environments': 'users/extend/customization-extendibility.md'
Expand Down
27 changes: 19 additions & 8 deletions scripts/install_ddev.sh
Expand Up @@ -65,18 +65,29 @@ else
sudo mv /tmp/ddev /tmp/macos_ddev_nfs_setup.sh /usr/local/bin/
fi

if command -v brew >/dev/null && [ -f "$(brew --prefix)/etc/bash_completion" ]; then
bash_completion_dir=$(brew --prefix)/etc/bash_completion.d
cp /tmp/ddev_bash_completion.sh $bash_completion_dir/ddev
printf "${GREEN}Installed ddev bash completions in $bash_completion_dir${RESET}\n"
rm /tmp/ddev_bash_completion.sh
else
printf "${YELLOW}Bash completion for ddev was not installed. You may manually install /tmp/ddev_bash_completion.sh in your bash_completions.d directory.${RESET}\n"
if command -v brew >/dev/null ; then
if [ -d "$(brew --prefix)/etc/bash_completion.d" ]; then
bash_completion_dir=$(brew --prefix)/etc/bash_completion.d
cp /tmp/ddev_bash_completion.sh $bash_completion_dir/ddev
printf "${GREEN}Installed ddev bash completions in $bash_completion_dir${RESET}\n"
rm /tmp/ddev_bash_completion.sh
else
printf "${YELLOW}Bash completion for ddev was not installed. You may manually install /tmp/ddev_bash_completion.sh in your bash_completion.d directory.${RESET}\n"
fi

if [ -d "$(brew --prefix)/share/zsh-completions" ] && [ -f /tmp/ddev_zsh_completion.sh ]; then
zsh_completion_dir=$(brew --prefix)/share/zsh-completions
cp /tmp/ddev_zsh_completion.sh $zsh_completion_dir/_ddev
printf "${GREEN}Installed ddev zsh completions in $zsh_completion_dir${RESET}\n"
rm /tmp/ddev_zsh_completion.sh
else
printf "${YELLOW}zsh completion for ddev was not installed. You may manually install /tmp/ddev_zsh_completion.sh in your zsh-completions directory.${RESET}\n"
fi
fi

rm /tmp/$TARBALL /tmp/$SHAFILE

printf "${GREEN}ddev is now installed. Run \"ddev\" to verify your installation and see usage.${RESET}\n"
if ! command -v mkcert ; then
if ! command -v mkcert >/dev/null ; then
printf "${YELLOW}Please install mkcert from https://github.com/FiloSottile/mkcert/releases and then run 'mkcert -install'.${RESET}\n"
fi
5 changes: 3 additions & 2 deletions vendor/github.com/spf13/cobra/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 13 additions & 15 deletions vendor/github.com/spf13/cobra/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions vendor/github.com/spf13/cobra/Makefile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e5bfb63

Please sign in to comment.