toolchain

Imports

Imports #

"io/fs"
"os"
"path/filepath"
"strings"
"sync"
"cmd/go/internal/gover"
"context"
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/gover"
"cmd/go/internal/modfetch"
"cmd/internal/telemetry/counter"
"io/fs"
"io/fs"
"io/fs"
"os"
"path/filepath"
"cmd/go/internal/gover"
"internal/syscall/unix"
"io/fs"
"os"
"path/filepath"
"syscall"
"cmd/go/internal/gover"
"bytes"
"context"
"errors"
"flag"
"fmt"
"go/build"
"internal/godebug"
"io"
"io/fs"
"log"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/gover"
"cmd/go/internal/modfetch"
"cmd/go/internal/modload"
"cmd/go/internal/run"
"cmd/go/internal/work"
"cmd/internal/pathcache"
"cmd/internal/telemetry/counter"
"golang.org/x/mod/module"
"io/fs"
"syscall"
"cmd/go/internal/base"
"fmt"
"internal/godebug"
"os"
"os/exec"
"runtime"
"syscall"
"cmd/go/internal/base"

Constants & Variables

TestVersionSwitch var #

TestVersionSwitch is set in the test go binary to the value in $TESTGO_VERSION_SWITCH. Valid settings are: "switch" - simulate version switches by reinvoking the test go binary with a different TESTGO_VERSION. "mismatch" - like "switch" but forget to set TESTGO_VERSION, so it looks like we invoked a mismatched toolchain "loop" - like "mismatch" but forget the target check, causing a toolchain switching loop

var TestVersionSwitch string

countEnv const #

countEnv is a special environment variable that is incremented during each toolchain switch, to detect loops. It is cleared before invoking programs in 'go run', 'go test', 'go generate', and 'go tool' by invoking them in an environment filtered with FilterEnv, so user programs should not see this in their environment.

const countEnv = "GOTOOLCHAIN_INTERNAL_SWITCH_COUNT"

counterErrorsInvalidToolchainInFile var #

var counterErrorsInvalidToolchainInFile = *ast.CallExpr

counterSelectExec var #

var counterSelectExec = *ast.CallExpr

counterSwitchExec var #

var counterSwitchExec = *ast.CallExpr

gotoolchainModule const #

We download golang.org/toolchain version v0.0.1-.-. If the 0.0.1 indicates anything at all, its the version of the toolchain packaging: if for some reason we needed to change the way toolchains are packaged into module zip files in a future version of Go, we could switch to v0.0.2 and then older versions expecting the old format could use v0.0.1 and newer versions would use v0.0.2. Of course, then we'd also have to publish two of each module zip file. It's not likely we'll ever need to change this.

const gotoolchainModule = "golang.org/toolchain"

gotoolchainVersion const #

const gotoolchainVersion = "v0.0.1"

maxSwitch const #

maxSwitch is the maximum toolchain switching depth. Most uses should never see more than three. (Perhaps one for the initial GOTOOLCHAIN dispatch, a second for go get doing an upgrade, and a third if for some reason the chosen upgrade version is too small by a little.) When the count reaches maxSwitch - 10, we start logging the switched versions for debugging before crashing with a fatal error upon reaching maxSwitch. That should be enough to see the repetition.

const maxSwitch = 100

pathExts var #

var pathExts = *ast.CallExpr

targetEnv const #

targetEnv is a special environment variable set to the expected toolchain version during the toolchain switch by the parent process and cleared in the child process. When set, that indicates to the child to confirm that it provides the expected toolchain version.

const targetEnv = "GOTOOLCHAIN_INTERNAL_SWITCH_VERSION"

toolchainTrace var #

var toolchainTrace = *ast.BinaryExpr

writeBits var #

var writeBits fs.FileMode

Structs

Switcher struct #

A Switcher collects errors to be reported and then decides between reporting the errors or switching to a new toolchain to resolve them. The client calls [Switcher.Error] repeatedly with errors encountered and then calls [Switcher.Switch]. If the errors included any *gover.TooNewErrors (potentially wrapped) and switching is permitted by GOTOOLCHAIN, Switch switches to a new toolchain. Otherwise Switch prints all the errors using base.Error. See https://go.dev/doc/toolchain#switch.

type Switcher struct {
TooNew *gover.TooNewError
Errors []error
}

Functions

Error method #

Error reports the error to the Switcher, which saves it for processing during Switch.

func (s *Switcher) Error(err error)

Exec function #

Exec invokes the specified Go toolchain or else prints an error and exits the process. If $GOTOOLCHAIN is set to path or min+path, Exec only considers the PATH as a source of Go toolchains. Otherwise Exec tries the PATH but then downloads a toolchain if necessary.

func Exec(gotoolchain string)

FilterEnv function #

FilterEnv returns a copy of env with internal GOTOOLCHAIN environment variables filtered out.

func FilterEnv(env []string) []string

HasAuto function #

HasAuto reports whether the GOTOOLCHAIN setting allows "auto" upgrades.

func HasAuto() bool

HasPath function #

HasPath reports whether the GOTOOLCHAIN setting allows "path" upgrades.

func HasPath() bool

NeedSwitch method #

NeedSwitch reports whether Switch would attempt to switch toolchains.

func (s *Switcher) NeedSwitch() bool

NewerToolchain function #

NewerToolchain returns the name of the toolchain to use when we need to switch to a newer toolchain that must support at least the given Go version. See https://go.dev/doc/toolchain#switch. If the latest major release is 1.N.0, we use the latest patch release of 1.(N-1) if that's >= version. Otherwise we use the latest 1.N if that's allowed. Otherwise we use the latest release.

func NewerToolchain(ctx context.Context, version string) (string, error)

Select function #

Select invokes a different Go toolchain if directed by the GOTOOLCHAIN environment variable or the user's configuration or go.mod file. It must be called early in startup. See https://go.dev/doc/toolchain#select.

func Select()

Switch method #

Switch decides whether to switch to a newer toolchain to resolve any of the saved errors. It switches if toolchain switches are permitted and there is at least one TooNewError. If Switch decides not to switch toolchains, it prints the errors using base.Error and returns. If Switch decides to switch toolchains but cannot identify a toolchain to use. it prints the errors along with one more about not being able to find the toolchain and returns. Otherwise, Switch prints an informational message giving a reason for the switch and the toolchain being invoked and then switches toolchains. This operation never returns.

func (s *Switcher) Switch(ctx context.Context)

SwitchOrFatal function #

SwitchOrFatal attempts a toolchain switch based on the information in err and otherwise falls back to base.Fatal(err).

func SwitchOrFatal(ctx context.Context, err error)

addTooNew method #

addTooNew adds any TooNew errors that can be found in err.

func (s *Switcher) addTooNew(err error)

autoToolchains function #

autoToolchains returns the list of toolchain versions available to GOTOOLCHAIN=auto or =min+auto mode.

func autoToolchains(ctx context.Context) ([]string, error)

cutExt function #

cutExt looks for any of the known extensions at the end of file. If one is found, cutExt returns the file name with the extension trimmed, the extension itself, and true to signal that an extension was found. Otherwise cutExt returns file, "", false.

func cutExt(file string, exts []string) (name string, ext string, found bool)

execGoToolchain function #

func execGoToolchain(gotoolchain string, dir string, exe string)

execGoToolchain function #

execGoToolchain execs the Go toolchain with the given name (gotoolchain), GOROOT directory, and go command executable. The GOROOT directory is empty if we are invoking a command named gotoolchain found in $PATH.

func execGoToolchain(gotoolchain string, dir string, exe string)

goInstallVersion function #

goInstallVersion reports whether the command line is go install m@v or go run m@v. If so, Select must not read the go.mod or go.work file in "auto" or "path" mode.

func goInstallVersion(minVers string) bool

modGoToolchain function #

modGoToolchain finds the enclosing go.work or go.mod file and returns the go version and toolchain lines from the file. The toolchain line overrides the version line

func modGoToolchain() (file string, goVers string, toolchain string)

newerToolchain function #

newerToolchain implements NewerToolchain where the list of choices is known. It is separated out for easier testing of this logic.

func newerToolchain(need string, list []string) (string, error)

pathDirs function #

pathDirs returns the directories in the system search path.

func pathDirs() []string

pathDirs function #

pathDirs returns the directories in the system search path.

func pathDirs() []string

pathDirs function #

pathDirs returns the directories in the system search path.

func pathDirs() []string

pathDirs function #

pathDirs returns the directories in the system search path.

func pathDirs() []string

pathToolchains function #

pathToolchains returns the list of toolchain versions available to GOTOOLCHAIN=path or =min+path mode.

func pathToolchains(ctx context.Context) ([]string, error)

pathVersion function #

pathVersion returns the Go version implemented by the file described by de and info in directory dir. The analysis only uses the name itself; it does not run the program.

func pathVersion(dir string, de fs.DirEntry, info fs.FileInfo) (string, bool)

pathVersion function #

pathVersion returns the Go version implemented by the file described by de and info in directory dir. The analysis only uses the name itself; it does not run the program.

func pathVersion(dir string, de fs.DirEntry, info fs.FileInfo) (string, bool)

pathVersion function #

pathVersion returns the Go version implemented by the file described by de and info in directory dir. The analysis only uses the name itself; it does not run the program.

func pathVersion(dir string, de fs.DirEntry, info fs.FileInfo) (string, bool)

pathVersion function #

pathVersion returns the Go version implemented by the file described by de and info in directory dir. The analysis only uses the name itself; it does not run the program.

func pathVersion(dir string, de fs.DirEntry, info fs.FileInfo) (string, bool)

raceSafeCopy function #

raceSafeCopy copies the file old to the file new, being careful to ensure that if multiple go commands call raceSafeCopy(old, new) at the same time, they don't interfere with each other: both will succeed and return and later observe the correct content in new. Like in the build cache, we arrange this by opening new without truncation and then writing the content. Both go commands can do this simultaneously and will write the same thing (old never changes content).

func raceSafeCopy(old string, new string) error

size function #

func size(path string) int64

sysWriteBits function #

sysWriteBits determines which bits to OR into the mode to make a directory writable. It must be called when there are no other file system operations happening.

func sysWriteBits() fs.FileMode

sysWriteBits function #

func sysWriteBits() fs.FileMode

Generated with Arrow