[vscode-go] tools/installtools: add a helper to install Go tools for testing

44 views
Skip to first unread message

Hyang-Ah Hana Kim (Gerrit)

unread,
Oct 28, 2021, 4:32:39 PM10/28/21
to Hyang-Ah Hana Kim, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Suzy Mueller, Robert Findley, kokoro, golang-co...@googlegroups.com

Hyang-Ah Hana Kim submitted this change.

View Change


Approvals: Suzy Mueller: Looks good to me, approved Hyang-Ah Hana Kim: Trusted; Run TryBots kokoro: TryBots succeeded
tools/installtools: add a helper to install Go tools for testing

GitHub Action workflows had tool installation commands defined
in .yml file while Kokoro CI used a bash script. This change
made them to share the same logic.

Instead of using the existing build/all.bash script, this CL
reimplemented the installation logic in go

- to have one single program for all platforms (linux, windows, mac)
- to implement complex logic that switches between go get and
go install depending on the go version (versioned binary installation
using go install became available only after 1.16.

Updates golang/vscode-go#1825

Change-Id: I295856e7d2bdd2d1fc07efc1e794eccb42b55ad6
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/359397
Trust: Hyang-Ah Hana Kim <hya...@gmail.com>
Run-TryBot: Hyang-Ah Hana Kim <hya...@gmail.com>
TryBot-Result: kokoro <noreply...@google.com>
Reviewed-by: Suzy Mueller <suz...@golang.org>
---
M .github/workflows/release-nightly.yml
M .github/workflows/test-long-all.yml
M .github/workflows/test-smoke.yml
A tools/installtools/main.go
M build/all.bash
M build/Dockerfile
M .github/workflows/test-long.yml
7 files changed, 181 insertions(+), 122 deletions(-)

diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml
index cc6d298..1148a2c 100644
--- a/.github/workflows/release-nightly.yml
+++ b/.github/workflows/release-nightly.yml
@@ -44,29 +44,7 @@

- name: Install Go tools (Modules mode)
run: |
- go version
- go get github.com/acroca/go-symbols
- go get github.com/davidrjenni/reftools/cmd/fillstruct
- go get github.com/haya14busa/goplay/cmd/goplay
-
- # Install two versions of gocode (one as gocode-gomod)
- go get github.com/stamblerre/gocode
- mv "${HOME}/go/bin/gocode${{env.EXT}}" "${HOME}/go/bin/gocode-gomod${{env.EXT}}"
- go get github.com/mdempsky/gocode
-
- go get github.com/sqs/goreturns
- go get github.com/uudashr/gopkgs/v2/cmd/gopkgs
- go get github.com/zmb3/gogetdoc
- go get honnef.co/go/tools/...
- go get golang.org/x/tools/cmd/gorename
- go get golang.org/x/tools/gopls
- go get github.com/cweill/gotests/...
- go get github.com/rogpeppe/godef
- go get github.com/ramya-rao-a/go-outline
- go get github.com/go-delve/delve/cmd/dlv@master
- cp "${HOME}/go/bin/dlv${{env.EXT}}" "${HOME}/go/bin/dlv-dap${{env.EXT}}"
- go get github.com/go-delve/delve/cmd/dlv
- working-directory: ${{ runner.temp }}
+ go run ./tools/installtools/main.go
env:
GO111MODULE: on
EXT: "${{ matrix.os == 'windows-latest' && '.exe' || ''}}"
diff --git a/.github/workflows/test-long-all.yml b/.github/workflows/test-long-all.yml
index acc82c0..4b43f30 100644
--- a/.github/workflows/test-long-all.yml
+++ b/.github/workflows/test-long-all.yml
@@ -43,27 +43,7 @@
- name: Install Go tools (Modules mode)
run: |
go version
- go get github.com/acroca/go-symbols
- go get github.com/davidrjenni/reftools/cmd/fillstruct
- go get github.com/haya14busa/goplay/cmd/goplay
- # Install two versions of gocode (one as gocode-gomod)
- go get github.com/stamblerre/gocode
- mv "${HOME}/go/bin/gocode${{env.EXT}}" "${HOME}/go/bin/gocode-gomod${{env.EXT}}"
- go get github.com/mdempsky/gocode
- go get github.com/sqs/goreturns
- go get github.com/uudashr/gopkgs/v2/cmd/gopkgs
- go get github.com/zmb3/gogetdoc
- go get honnef.co/go/tools/...
- go get golang.org/x/tools/cmd/gorename
- go get golang.org/x/tools/gopls
- go get github.com/cweill/gotests/...
- go get github.com/rogpeppe/godef
- go get github.com/ramya-rao-a/go-outline
- # Install two versions of dlv (one as dlv-dap)
- go get github.com/go-delve/delve/cmd/dlv@master
- mv "${HOME}/go/bin/dlv${{env.EXT}}" "${HOME}/go/bin/dlv-dap${{env.EXT}}"
- go get github.com/go-delve/delve/cmd/dlv@latest
- working-directory: ${{ runner.temp }}
+ go run ./tools/installtools/main.go
env:
GO111MODULE: on
EXT: "${{ matrix.os == 'windows-latest' && '.exe' || ''}}"
diff --git a/.github/workflows/test-long.yml b/.github/workflows/test-long.yml
index 67711f1..91f1a76 100644
--- a/.github/workflows/test-long.yml
+++ b/.github/workflows/test-long.yml
@@ -43,27 +43,7 @@
- name: Install Go tools (Modules mode)
run: |
go version
- go get github.com/acroca/go-symbols
- go get github.com/davidrjenni/reftools/cmd/fillstruct
- go get github.com/haya14busa/goplay/cmd/goplay
- # Install two versions of gocode (one as gocode-gomod)
- go get github.com/stamblerre/gocode
- mv "${HOME}/go/bin/gocode${{env.EXT}}" "${HOME}/go/bin/gocode-gomod${{env.EXT}}"
- go get github.com/mdempsky/gocode
- go get github.com/sqs/goreturns
- go get github.com/uudashr/gopkgs/v2/cmd/gopkgs
- go get github.com/zmb3/gogetdoc
- go get honnef.co/go/tools/...
- go get golang.org/x/tools/cmd/gorename
- go get golang.org/x/tools/gopls
- go get github.com/cweill/gotests/...
- go get github.com/rogpeppe/godef
- go get github.com/ramya-rao-a/go-outline
- # Install two versions of dlv (one as dlv-dap)
- go get github.com/go-delve/delve/cmd/dlv@master
- mv "${HOME}/go/bin/dlv${{env.EXT}}" "${HOME}/go/bin/dlv-dap${{env.EXT}}"
- go get github.com/go-delve/delve/cmd/dlv@latest
- working-directory: ${{ runner.temp }}
+ go run ./tools/installtools/main.go
env:
GO111MODULE: on
EXT: "${{ matrix.os == 'windows-latest' && '.exe' || ''}}"
diff --git a/.github/workflows/test-smoke.yml b/.github/workflows/test-smoke.yml
index 270954f..3954b7f 100644
--- a/.github/workflows/test-smoke.yml
+++ b/.github/workflows/test-smoke.yml
@@ -40,27 +40,7 @@
- name: Install Go tools (Modules mode)
run: |
go version
- go get github.com/acroca/go-symbols
- go get github.com/davidrjenni/reftools/cmd/fillstruct
- go get github.com/haya14busa/goplay/cmd/goplay
- # Install two versions of gocode (one as gocode-gomod)
- go get github.com/stamblerre/gocode
- mv "${HOME}/go/bin/gocode${{env.EXT}}" "${HOME}/go/bin/gocode-gomod${{env.EXT}}"
- go get github.com/mdempsky/gocode
- go get github.com/sqs/goreturns
- go get github.com/uudashr/gopkgs/v2/cmd/gopkgs
- go get github.com/zmb3/gogetdoc
- go get honnef.co/go/tools/...
- go get golang.org/x/tools/cmd/gorename
- go get golang.org/x/tools/gopls
- go get github.com/cweill/gotests/...
- go get github.com/rogpeppe/godef
- go get github.com/ramya-rao-a/go-outline
- # Install two versions of dlv (one as dlv-dap)
- go get github.com/go-delve/delve/cmd/dlv@master
- mv "${HOME}/go/bin/dlv${{env.EXT}}" "${HOME}/go/bin/dlv-dap${{env.EXT}}"
- go get github.com/go-delve/delve/cmd/dlv@latest
- working-directory: ${{ runner.temp }}
+ go run ./tools/installtools/main.go
env:
GO111MODULE: on
EXT: "${{ matrix.os == 'windows-latest' && '.exe' || ''}}"
diff --git a/build/Dockerfile b/build/Dockerfile
index 17662f0..1ca02ee 100644
--- a/build/Dockerfile
+++ b/build/Dockerfile
@@ -6,9 +6,9 @@
ENV GOBIN /gobin

# Install other Go tools tests depend on
-RUN mkdir -p /scratch/build
-ADD build/all.bash /scratch/build/all.bash
-RUN /scratch/build/all.bash setup_env
+RUN mkdir -p /scratch/installtools
+ADD tools/installtools/main.go /scratch/installtools/main.go
+RUN go run /scratch/installtools/main.go

FROM node:latest

diff --git a/build/all.bash b/build/all.bash
index f981def..07539a3 100755
--- a/build/all.bash
+++ b/build/all.bash
@@ -92,36 +92,6 @@
cp build/nightly/const.ts src/const.ts
}

-# setup dependencies required for tests.
-install_dependencies() {
- # TARGET is where `go get` will output the compiled binaries.
- local GOPATHS=`go env GOPATH`
- local TARGET="${GOBIN}"
- if [[ -z "${GOBIN}" ]]; then TARGET="${GOPATHS%%:*}/bin" ; fi
-
- GO111MODULE=on go install golang.org/x/tools/gopls@latest
- GO111MODULE=on go install github.com/acroca/go-symbols@latest
- GO111MODULE=on go install github.com/cweill/gotests/gotests@latest
- GO111MODULE=on go install github.com/davidrjenni/reftools/cmd/fillstruct@latest
- GO111MODULE=on go install github.com/haya14busa/goplay/cmd/goplay@latest
-
- # We install two versions of gocode, one for module mode (gocode-gomod)
- # and another for GOPATH mode (gocode).
- GO111MODULE=on go install github.com/stamblerre/gocode@latest && mv "${TARGET}/gocode" "${TARGET}/gocode-gomod"
- GO111MODULE=on go install github.com/mdempsky/gocode@latest
-
- GO111MODULE=on go install github.com/ramya-rao-a/go-outline@latest
- GO111MODULE=on go install github.com/rogpeppe/godef@latest
- GO111MODULE=on go install github.com/sqs/goreturns@latest
- GO111MODULE=on go install github.com/uudashr/gopkgs/v2/cmd/gopkgs@latest
- GO111MODULE=on go install github.com/zmb3/gogetdoc@latest
- GO111MODULE=on go install honnef.co/go/tools/cmd/staticcheck@latest
- GO111MODULE=on go install golang.org/x/tools/cmd/gorename@latest
-
- GO111MODULE=on go install github.com/go-delve/delve/cmd/dlv@master && cp "${TARGET}/dlv" "${TARGET}/dlv-dap"
- GO111MODULE=on go install github.com/go-delve/delve/cmd/dlv@latest
-}
-
main() {
cd "$(root_dir)" # always run from the script root.
case "$1" in
@@ -144,9 +114,6 @@
"prepare_nightly")
prepare_nightly
;;
- "setup_env")
- install_dependencies
- ;;
*)
usage
exit 2
diff --git a/tools/installtools/main.go b/tools/installtools/main.go
new file mode 100644
index 0000000..99a2def
--- /dev/null
+++ b/tools/installtools/main.go
@@ -0,0 +1,146 @@
+// Binary installtools is a helper that installs Go tools extension tests depend on.
+package main
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "path"
+ "path/filepath"
+ "runtime"
+ "strings"
+)
+
+var tools = []struct {
+ path string
+ version string
+ dest string
+}{
+ // TODO: auto-generate based on allTools.ts.in.
+ {"golang.org/x/tools/gopls", "", ""},
+ {"github.com/acroca/go-symbols", "", ""},
+ {"github.com/cweill/gotests/gotests", "", ""},
+ {"github.com/davidrjenni/reftools/cmd/fillstruct", "", ""},
+ {"github.com/haya14busa/goplay/cmd/goplay", "", ""},
+ {"github.com/stamblerre/gocode", "", "gocode-gomod"},
+ {"github.com/mdempsky/gocode", "", ""},
+ {"github.com/ramya-rao-a/go-outline", "", ""},
+ {"github.com/rogpeppe/godef", "", ""},
+ {"github.com/sqs/goreturns", "", ""},
+ {"github.com/uudashr/gopkgs/v2/cmd/gopkgs", "", ""},
+ {"github.com/zmb3/gogetdoc", "", ""},
+ {"honnef.co/go/tools/cmd/staticcheck", "", ""},
+ {"golang.org/x/tools/cmd/gorename", "", ""},
+ {"github.com/go-delve/delve/cmd/dlv", "master", "dlv-dap"},
+ {"github.com/go-delve/delve/cmd/dlv", "", ""},
+}
+
+func main() {
+ ver, err := goVersion()
+ if err != nil {
+ exitf("failed to find go version: %v", err)
+ }
+ bin, err := goBin()
+ if err != nil {
+ exitf("failed to determine go tool installation directory: %v", err)
+ }
+ if ver < 1 {
+ exitf("unsupported go version: 1.%v", ver)
+ } else if ver < 16 {
+ err = installTools(bin, "get")
+ } else {
+ err = installTools(bin, "install")
+ }
+ if err != nil {
+ exitf("failed to install tools: %v", err)
+ }
+}
+
+func exitf(format string, args ...interface{}) {
+ fmt.Fprintf(os.Stderr, format, args...)
+ os.Exit(1)
+}
+
+// goVersion returns an integer N if go's version is 1.N.
+func goVersion() (int, error) {
+ cmd := exec.Command("go", "list", "-e", "-f", `{{context.ReleaseTags}}`, "--", "unsafe")
+ cmd.Env = append(os.Environ(), "GO111MODULE=off")
+ out, err := cmd.Output()
+ if err != nil {
+ return 0, fmt.Errorf("go list error: %v", err)
+ }
+ result := string(out)
+ if len(result) < 3 {
+ return 0, fmt.Errorf("bad ReleaseTagsOutput: %q", result)
+ }
+ // Split up "[go1.1 go1.15]"
+ tags := strings.Fields(result[1 : len(result)-2])
+ for i := len(tags) - 1; i >= 0; i-- {
+ var version int
+ if _, err := fmt.Sscanf(tags[i], "go1.%d", &version); err != nil {
+ continue
+ }
+ return version, nil
+ }
+ return 0, fmt.Errorf("no parseable ReleaseTags in %v", tags)
+}
+
+// goBin returns the directory where the go command will install binaries.
+func goBin() (string, error) {
+ if gobin := os.Getenv("GOBIN"); gobin != "" {
+ return gobin, nil
+ }
+ out, err := exec.Command("go", "env", "GOPATH").Output()
+ if err != nil {
+ return "", err
+ }
+ gopaths := filepath.SplitList(strings.TrimSpace(string(out)))
+ if len(gopaths) == 0 {
+ return "", fmt.Errorf("invalid GOPATH: %s", out)
+ }
+ return filepath.Join(gopaths[0], "bin"), nil
+}
+
+func installTools(binDir, installCmd string) error {
+ dir := ""
+ if installCmd == "get" { // run `go get` command from an empty directory.
+ dir = os.TempDir()
+ }
+ env := append(os.Environ(), "GO111MODULE=on")
+ for _, tool := range tools {
+ ver := tool.version
+ if ver == "" {
+ ver = "latest"
+ }
+ path := tool.path + "@" + ver
+ cmd := exec.Command("go", installCmd, path)
+ cmd.Env = env
+ cmd.Dir = dir
+ fmt.Println("go", installCmd, path)
+ if out, err := cmd.CombinedOutput(); err != nil {
+ return fmt.Errorf("installing %v: %s\n%v", path, out, err)
+ }
+ loc := filepath.Join(binDir, binName(tool.path))
+ if tool.dest != "" {
+ newLoc := filepath.Join(binDir, binName(tool.dest))
+ if err := os.Rename(loc, newLoc); err != nil {
+ return fmt.Errorf("copying %v to %v: %v", loc, newLoc, err)
+ }
+ loc = newLoc
+ }
+ fmt.Println("\tinstalled", loc)
+ }
+ return nil
+}
+
+func binName(toolPath string) string {
+ b := path.Base(toolPath)
+ if runtime.GOOS == "windows" {
+ return b + ".exe"
+ }
+ return b
+}
+
+func runWithGoInstall() error {
+ return nil
+}

To view, visit change 359397. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: vscode-go
Gerrit-Branch: master
Gerrit-Change-Id: I295856e7d2bdd2d1fc07efc1e794eccb42b55ad6
Gerrit-Change-Number: 359397
Gerrit-PatchSet: 2
Gerrit-Owner: Hyang-Ah Hana Kim <hya...@gmail.com>
Gerrit-Reviewer: Hyang-Ah Hana Kim <hya...@gmail.com>
Gerrit-Reviewer: Robert Findley <rfin...@google.com>
Gerrit-Reviewer: Suzy Mueller <suz...@golang.org>
Gerrit-Reviewer: kokoro <noreply...@google.com>
Gerrit-MessageType: merged
Reply all
Reply to author
Forward
0 new messages