TranslateProject/sources/tech/20170115 Magic GOPATH.md
DarkSun f753d6d7c3 选题: 20170115 Magic GOPATH
sources/tech/20170115 Magic GOPATH.md
2019-09-17 13:11:11 +08:00

4.3 KiB
Raw Blame History

Magic GOPATH

Update: With the advent of Go 1.11 and Go modules, this whole post is now useless. Unset your GOPATH entirely and switch to Go modules today!

Maybe someday Ill start writing about things besides Go again.

Go requires that you set an environment variable for your workspace called your GOPATH. The GOPATH is one of the most confusing aspects of Go to newcomers and even relatively seasoned developers alike. Its not immediately clear what would be better, but finding a good GOPATH value has implications for your source code repository layout, how many separate projects you have on your computer, how default project installation instructions work (via go get), and even how you interoperate with other projects and libraries.

Its taken until Go 1.8 to decide to set a default and that small change was one of the most talked about code reviews for the 1.8 release cycle.

After writing about GOPATH himself, Dave Cheney asked me to write a blog post about what I do.

My proposal

I set my GOPATH to always be the current working directory, unless a parent directory is clearly the GOPATH.

Heres the relevant part of my .bashrc:

# bash command to output calculated GOPATH.
calc_gopath() {
  local dir="$PWD"

  # we're going to walk up from the current directory to the root
  while true; do

    # if there's a '.gopath' file, use its contents as the GOPATH relative to
    # the directory containing it.
    if [ -f "$dir/.gopath" ]; then
      ( cd "$dir";
        # allow us to squash this behavior for cases we want to use vgo
        if [ "$(cat .gopath)" != "" ]; then
          cd "$(cat .gopath)";
          echo "$PWD";
        fi; )
      return
    fi

    # if there's a 'src' directory, the parent of that directory is now the
    # GOPATH
    if [ -d "$dir/src" ]; then
      echo "$dir"
      return
    fi

    # we can't go further, so bail. we'll make the original PWD the GOPATH.
    if [ "$dir" == "/" ]; then
      echo "$PWD"
      return
    fi

    # now we'll consider the parent directory
    dir="$(dirname "$dir")"
  done
}

my_prompt_command() {
  export GOPATH="$(calc_gopath)"

  # you can have other neat things in here. I also set my PS1 based on git
  # state
}

case "$TERM" in
xterm*|rxvt*)
  # Bash provides an environment variable called PROMPT_COMMAND. The contents
  # of this variable are executed as a regular Bash command just before Bash
  # displays a prompt. Let's only set it if we're in some kind of graphical
  # terminal I guess.
  PROMPT_COMMAND=my_prompt_command
  ;;
*)
  ;;
esac

The benefits are fantastic. If you want to quickly go get something and not have it clutter up your workspace, you can do something like:

cd $(mktemp -d) && go get github.com/the/thing

On the other hand, if youre jumping between multiple projects (whether or not they have the full workspace checked in or are just library packages), the GOPATH is set accurately.

More flexibly, if you have a tree where some parent directory is outside of the GOPATH but you want to set the GOPATH anyways, you can create a .gopath file and it will automatically set your GOPATH correctly any time your shell is inside that directory.

The whole thing is super nice. I kinda cant imagine doing something else anymore.

Fin.


via: https://www.jtolio.com/2017/01/magic-gopath

作者:jtolio.com 选题:lujun9972 译者:译者ID 校对:校对者ID

本文由 LCTT 原创编译,Linux中国 荣誉推出