diff --git a/clean_files.txt b/clean_files.txt index 85ec886b..1403c790 100644 --- a/clean_files.txt +++ b/clean_files.txt @@ -24,12 +24,6 @@ hooks .gitattributes lint_clean_files.sh -# plugins -# -plugins/available/history.plugin.bash -plugins/available/history-search.plugin.bash -plugins/available/history-substring-search.plugin.bash - # themes # themes/agnoster @@ -54,6 +48,11 @@ themes/modern plugins/available/basher.plugin.bash plugins/available/cmd-returned-notify.plugin.bash plugins/available/docker-machine.plugin.bash +plugins/available/go.plugin.bash +plugins/available/goenv.plugin.bash +plugins/available/history.plugin.bash +plugins/available/history-search.plugin.bash +plugins/available/history-substring-search.plugin.bash plugins/available/xterm.plugin.bash # completions diff --git a/plugins/available/go.plugin.bash b/plugins/available/go.plugin.bash old mode 100755 new mode 100644 index 566d7669..5592a006 --- a/plugins/available/go.plugin.bash +++ b/plugins/available/go.plugin.bash @@ -1,19 +1,36 @@ -#!/usr/bin/env bash - +# shellcheck shell=bash cite about-plugin about-plugin 'go environment variables & path configuration' -command -v go &>/dev/null || return +# Load after basher and goenv +# BASH_IT_LOAD_PRIORITY: 270 -function _go_pathmunge_wrap() { - IFS=':' local -a 'a=($1)' - local i=${#a[@]} - while [ $i -gt 0 ] ; do - i=$(( i - 1 )) - pathmunge "${a[i]}/bin" - done -} +# Test `go version` because goenv creates shim scripts that will be found in PATH +# but do not always resolve to a working install. +{ _command_exists go && go version &> /dev/null; } || return 0 export GOROOT="${GOROOT:-$(go env GOROOT)}" export GOPATH="${GOPATH:-$(go env GOPATH)}" -_go_pathmunge_wrap "${GOPATH}:${GOROOT}" + +# $GOPATH/bin is the default location for binaries. Because GOPATH accepts a list of paths and each +# might be managed differently, we add each path's /bin folder to PATH using pathmunge, +# while preserving ordering. +# e.g. GOPATH=foo:bar -> PATH=foo/bin:bar/bin +_bash-it-gopath-pathmunge() { + _about 'Ensures paths in GOPATH are added to PATH using pathmunge, with /bin appended' + _group 'go' + if [[ -z $GOPATH ]]; then + echo 'GOPATH empty' >&2 + return 1 + fi + local paths i + IFS=: read -r -a paths <<< "$GOPATH" + i=${#paths[@]} + while [[ $i -gt 0 ]]; do + i=$((i - 1)) + if [[ -n "${paths[i]}" ]]; then + pathmunge "${paths[i]}/bin" + fi + done +} +_bash-it-gopath-pathmunge diff --git a/plugins/available/goenv.plugin.bash b/plugins/available/goenv.plugin.bash index ecc1b1c2..d00fce67 100644 --- a/plugins/available/goenv.plugin.bash +++ b/plugins/available/goenv.plugin.bash @@ -1,20 +1,42 @@ +# shellcheck shell=bash cite about-plugin about-plugin 'load goenv, if you are using it' +# https://github.com/syndbg/goenv + +# Load after basher +# BASH_IT_LOAD_PRIORITY: 260 + # Don't modify the environment if we can't find the tool: # - Check if in $PATH already # - Check if installed manually to $GOENV_ROOT # - Check if installed manually to $HOME -_command_exists goenv || - [[ -n "$GOENV_ROOT" && -x "$GOENV_ROOT/bin/goenv" ]] || - [[ -x "$HOME/.goenv/bin/goenv" ]] || - return +_command_exists goenv \ + || [[ -n "$GOENV_ROOT" && -x "$GOENV_ROOT/bin/goenv" ]] \ + || [[ -x "$HOME/.goenv/bin/goenv" ]] \ + || return 0 # Set GOENV_ROOT, if not already set export GOENV_ROOT="${GOENV_ROOT:-$HOME/.goenv}" # Add GOENV_ROOT/bin to PATH, if that's where it's installed -! _command_exists goenv && [[ -x "$GOENV_ROOT/bin/goenv" ]] && pathmunge "$GOENV_ROOT/bin" +if ! _command_exists goenv && [[ -x "$GOENV_ROOT/bin/goenv" ]]; then + pathmunge "$GOENV_ROOT/bin" +fi # Initialize goenv eval "$(goenv init - bash)" + +# If moving to a directory with a goenv version set, reload the shell +# to ensure the shell environment matches expectations. +_bash-it-goenv-preexec() { + export GOENV_OLD_VERSION="$(goenv version-name)" +} +_bash-it-goenv-precmd() { + if [[ -n $GOENV_OLD_VERSION ]] && [[ "$GOENV_OLD_VERSION" != "$(goenv version-name)" ]]; then + exec env -u PATH -u GOROOT -u GOPATH -u GOENV_OLD_VERSION "${0/-/}" --login + fi + unset GOENV_OLD_VERSION +} +preexec_functions+=(_bash-it-goenv-preexec) +precmd_functions+=(_bash-it-goenv-precmd) diff --git a/test/plugins/go.plugin.bats b/test/plugins/go.plugin.bats index d511bd24..0211e845 100644 --- a/test/plugins/go.plugin.bats +++ b/test/plugins/go.plugin.bats @@ -4,57 +4,51 @@ load ../test_helper load ../../lib/helpers load ../../lib/composure -@test 'ensure _go_pathmunge_wrap is defined' { +@test 'ensure _bash-it-gopath-pathmunge is defined' { { [[ $CI ]] || _command_exists go; } || skip 'golang not found' load ../../plugins/available/go.plugin - run type -t _go_pathmunge_wrap + run type -t _bash-it-gopath-pathmunge assert_line 'function' } @test 'plugins go: single entry in GOPATH' { { [[ $CI ]] || _command_exists go; } || skip 'golang not found' export GOPATH="/foo" - export GOROOT="/baz" load ../../plugins/available/go.plugin - assert_equal "$(cut -d':' -f1,2 <<<$PATH)" "/foo/bin:/baz/bin" + assert_equal "$(cut -d':' -f1 <<<$PATH)" "/foo/bin" } @test 'plugins go: single entry in GOPATH, with space' { { [[ $CI ]] || _command_exists go; } || skip 'golang not found' export GOPATH="/foo bar" - export GOROOT="/baz" load ../../plugins/available/go.plugin - assert_equal "$(cut -d':' -f1,2 <<<$PATH)" "/foo bar/bin:/baz/bin" + assert_equal "$(cut -d':' -f1 <<<$PATH)" "/foo bar/bin" } @test 'plugins go: single entry in GOPATH, with escaped space' { { [[ $CI ]] || _command_exists go; } || skip 'golang not found' export GOPATH="/foo\ bar" - export GOROOT="/baz" load ../../plugins/available/go.plugin - assert_equal "$(cut -d':' -f1,2 <<<$PATH)" "/foo\ bar/bin:/baz/bin" + assert_equal "$(cut -d':' -f1 <<<$PATH)" "/foo\ bar/bin" } @test 'plugins go: multiple entries in GOPATH' { { [[ $CI ]] || _command_exists go; } || skip 'golang not found' export GOPATH="/foo:/bar" - export GOROOT="/baz" load ../../plugins/available/go.plugin - assert_equal "$(cut -d':' -f1,2,3 <<<$PATH)" "/foo/bin:/bar/bin:/baz/bin" + assert_equal "$(cut -d':' -f1,2 <<<$PATH)" "/foo/bin:/bar/bin" } @test 'plugins go: multiple entries in GOPATH, with space' { { [[ $CI ]] || _command_exists go; } || skip 'golang not found' export GOPATH="/foo:/foo bar" - export GOROOT="/baz" load ../../plugins/available/go.plugin - assert_equal "$(cut -d':' -f1,2,3 <<<$PATH)" "/foo/bin:/foo bar/bin:/baz/bin" + assert_equal "$(cut -d':' -f1,2 <<<$PATH)" "/foo/bin:/foo bar/bin" } @test 'plugins go: multiple entries in GOPATH, with escaped space' { { [[ $CI ]] || _command_exists go; } || skip 'golang not found' export GOPATH="/foo:/foo\ bar" - export GOROOT="/baz" load ../../plugins/available/go.plugin - assert_equal "$(cut -d':' -f1,2,3 <<<$PATH)" "/foo/bin:/foo\ bar/bin:/baz/bin" + assert_equal "$(cut -d':' -f1,2 <<<$PATH)" "/foo/bin:/foo\ bar/bin" }