From e7a78bc28f93eec24d92c7ad7acee2b111b71cad Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 20 Mar 2023 13:50:41 -0700 Subject: [PATCH] tool/gocross: support running from outside the repo dir A bunch of us invoke tool/go from outside the repo that hosts gocross, as a way of accessing our version-controlled toolchain. This removes assumptions from gocross that it's being invoked within the repository that contains its source code and toolchain configuration. Fixes tailscale/corp#9627 Signed-off-by: David Anderson --- tool/gocross/gocross-wrapper.sh | 7 +++++++ tool/gocross/toolchain.go | 18 ++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tool/gocross/gocross-wrapper.sh b/tool/gocross/gocross-wrapper.sh index b6a6aa560..2cfca0b2b 100755 --- a/tool/gocross/gocross-wrapper.sh +++ b/tool/gocross/gocross-wrapper.sh @@ -19,6 +19,13 @@ fi ( repo_root="$(dirname $0)/../.." +# Figuring out if gocross needs a rebuild, as well as the rebuild itself, need +# to happen with CWD inside this repo. Since we're in a subshell entirely +# dedicated to wrangling gocross and toolchains, cd over now before doing +# anything further so that the rest of this logic works the same if gocross is +# being invoked from somewhere else. +cd "$repo_root" + toolchain="$HOME/.cache/tailscale-go" if [ -d "$toolchain" ]; then diff --git a/tool/gocross/toolchain.go b/tool/gocross/toolchain.go index f5f790b43..5980dff04 100644 --- a/tool/gocross/toolchain.go +++ b/tool/gocross/toolchain.go @@ -15,11 +15,21 @@ import ( ) func toolchainRev() (string, error) { - cwd, err := os.Getwd() + // gocross gets built in the root of the repo that has toolchain + // information, so we can use os.Args[0] to locate toolchain info. + // + // We might be getting invoked via the synthetic goroot that we create, so + // walk symlinks to find the true location of gocross. + start, err := os.Executable() + if err != nil { + return "", err + } + start, err = filepath.EvalSymlinks(start) if err != nil { - return "", fmt.Errorf("getting CWD: %v", err) + return "", fmt.Errorf("evaluating symlinks in %q: %v", os.Args[0], err) } - d := cwd + start = filepath.Dir(start) + d := start findTopLevel: for { if _, err := os.Lstat(filepath.Join(d, ".git")); err == nil { @@ -29,7 +39,7 @@ findTopLevel: } d = filepath.Dir(d) if d == "/" { - return "", fmt.Errorf("couldn't find .git starting from %q, cannot manage toolchain", cwd) + return "", fmt.Errorf("couldn't find .git starting from %q, cannot manage toolchain", start) } }