“go get” command

go get“ command is the standard way of downloading and installing packages and related dependencies, and let’s check the particulars of it through an example:
(1) Create a playstack repository in github;
(2) There is a LICENSE file and play directory in playstack folder;
(3) The play directory includes one main.go file:

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/NanXiao/stack"
  5. )
  6. func main() {
  7. s := stack.New()
  8. s.Push(0)
  9. s.Push(1)
  10. s.Pop()
  11. fmt.Println(s)
  12. }

The main package has one dependency package: stack. Actually, the main() function doesn’t play anything meaningful, and we just use this project as a sample. So the directory structure of playstack looks like this:

  1. .
  2. ├── LICENSE
  3. └── play
  4. └── main.go
  5. 1 directory, 2 files

Clean the $GOPATH directory, and use “go get“ command to download playstack:

  1. # tree
  2. .
  3. 0 directories, 0 files
  4. # go get github.com/NanXiao/playstack
  5. package github.com/NanXiao/playstack: no buildable Go source files in /root/gocode/src/github.com/NanXiao/playstack

go get“ command complains “no buildable Go source files in ...“, and it is because the objects which “go get“ works are packages, not repositories.There is no *.go source files in playstack, so it is not a valid package.

Tidy up $GOPATH folder, and execute “go get github.com/NanXiao/playstack/play“ instead:

  1. # tree
  2. .
  3. 0 directories, 0 files
  4. # go get github.com/NanXiao/playstack/play
  5. # tree
  6. .
  7. ├── bin
  8. └── play
  9. ├── pkg
  10. └── linux_amd64
  11. └── github.com
  12. └── NanXiao
  13. └── stack.a
  14. └── src
  15. └── github.com
  16. └── NanXiao
  17. ├── playstack
  18. ├── LICENSE
  19. └── play
  20. └── main.go
  21. └── stack
  22. ├── LICENSE
  23. ├── README.md
  24. ├── stack.go
  25. └── stack_test.go
  26. 11 directories, 8 files

We can see not only playstack and its dependency (stack) are all downloaded, but also the command (play) and library (stack) are all installed in the right place.

The mechanism behind “go get“ command is it will fetch the repositories of packages and dependencies (E.g., use “git clone“.), and you can check the detailed workflow by “go get -x“:

  1. # tree
  2. .
  3. 0 directories, 0 files
  4. # go get -x github.com/NanXiao/playstack/play
  5. cd .
  6. git clone https://github.com/NanXiao/playstack /root/gocode/src/github.com/NanXiao/playstack
  7. cd /root/gocode/src/github.com/NanXiao/playstack
  8. git submodule update --init --recursive
  9. cd /root/gocode/src/github.com/NanXiao/playstack
  10. git show-ref
  11. cd /root/gocode/src/github.com/NanXiao/playstack
  12. git submodule update --init --recursive
  13. cd .
  14. git clone https://github.com/NanXiao/stack /root/gocode/src/github.com/NanXiao/stack
  15. cd /root/gocode/src/github.com/NanXiao/stack
  16. git submodule update --init --recursive
  17. cd /root/gocode/src/github.com/NanXiao/stack
  18. git show-ref
  19. cd /root/gocode/src/github.com/NanXiao/stack
  20. git submodule update --init --recursive
  21. WORK=/tmp/go-build054180753
  22. mkdir -p $WORK/github.com/NanXiao/stack/_obj/
  23. mkdir -p $WORK/github.com/NanXiao/
  24. cd /root/gocode/src/github.com/NanXiao/stack
  25. /usr/local/go/pkg/tool/linux_amd64/compile -o $WORK/github.com/NanXiao/stack.a -trimpath $WORK -p github.com/NanXiao/stack -complete -buildid de4d90fa03d8091e075c1be9952d691376f8f044 -D _/root/gocode/src/github.com/NanXiao/stack -I $WORK -pack ./stack.go
  26. mkdir -p /root/gocode/pkg/linux_amd64/github.com/NanXiao/
  27. mv $WORK/github.com/NanXiao/stack.a /root/gocode/pkg/linux_amd64/github.com/NanXiao/stack.a
  28. mkdir -p $WORK/github.com/NanXiao/playstack/play/_obj/
  29. mkdir -p $WORK/github.com/NanXiao/playstack/play/_obj/exe/
  30. cd /root/gocode/src/github.com/NanXiao/playstack/play
  31. /usr/local/go/pkg/tool/linux_amd64/compile -o $WORK/github.com/NanXiao/playstack/play.a -trimpath $WORK -p main -complete -buildid e9a3c02979f7c6e57ce4452278c52e3e0e6a48e8 -D _/root/gocode/src/github.com/NanXiao/playstack/play -I $WORK -I /root/gocode/pkg/linux_amd64 -pack ./main.go
  32. cd .
  33. /usr/local/go/pkg/tool/linux_amd64/link -o $WORK/github.com/NanXiao/playstack/play/_obj/exe/a.out -L $WORK -L /root/gocode/pkg/linux_amd64 -extld=gcc -buildmode=exe -buildid=e9a3c02979f7c6e57ce4452278c52e3e0e6a48e8 $WORK/github.com/NanXiao/playstack/play.a
  34. mkdir -p /root/gocode/bin/
  35. mv $WORK/github.com/NanXiao/playstack/play/_obj/exe/a.out /root/gocode/bin/play

From the above output, we can see playstack repository is cloned first, then stack, At last the compilation and installation are executed.

If you only want to download the source files, and not compile and install, using “go get -d“ command:

  1. # tree
  2. .
  3. 0 directories, 0 files
  4. # go get -d github.com/NanXiao/playstack/play
  5. # tree
  6. .
  7. └── src
  8. └── github.com
  9. └── NanXiao
  10. ├── playstack
  11. ├── LICENSE
  12. └── play
  13. └── main.go
  14. └── stack
  15. ├── LICENSE
  16. ├── README.md
  17. ├── stack.go
  18. └── stack_test.go
  19. 6 directories, 6 files

You can also use “go get -u“ to update packages and their dependencies.

Reference:
Command go;
How does “go get” command know which files should be downloaded?.