]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/go/internal/gover/toolchain.go
go/version: add new package
[gostls13.git] / src / cmd / go / internal / gover / toolchain.go
1 // Copyright 2023 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package gover
6
7 import (
8         "cmd/go/internal/base"
9         "context"
10         "errors"
11         "fmt"
12         "strings"
13 )
14
15 // FromToolchain returns the Go version for the named toolchain,
16 // derived from the name itself (not by running the toolchain).
17 // A toolchain is named "goVERSION".
18 // A suffix after the VERSION introduced by a -, space, or tab is removed.
19 // Examples:
20 //
21 //      FromToolchain("go1.2.3") == "1.2.3"
22 //      FromToolchain("go1.2.3-bigcorp") == "1.2.3"
23 //      FromToolchain("invalid") == ""
24 func FromToolchain(name string) string {
25         if strings.ContainsAny(name, "\\/") {
26                 // The suffix must not include a path separator, since that would cause
27                 // exec.LookPath to resolve it from a relative directory instead of from
28                 // $PATH.
29                 return ""
30         }
31
32         var v string
33         if strings.HasPrefix(name, "go") {
34                 v = name[2:]
35         } else {
36                 return ""
37         }
38         // Some builds use custom suffixes; strip them.
39         if i := strings.IndexAny(v, " \t-"); i >= 0 {
40                 v = v[:i]
41         }
42         if !IsValid(v) {
43                 return ""
44         }
45         return v
46 }
47
48 func maybeToolchainVersion(name string) string {
49         if IsValid(name) {
50                 return name
51         }
52         return FromToolchain(name)
53 }
54
55 // ToolchainMax returns the maximum of x and y interpreted as toolchain names,
56 // compared using Compare(FromToolchain(x), FromToolchain(y)).
57 // If x and y compare equal, Max returns x.
58 func ToolchainMax(x, y string) string {
59         if Compare(FromToolchain(x), FromToolchain(y)) < 0 {
60                 return y
61         }
62         return x
63 }
64
65 // Startup records the information that went into the startup-time version switch.
66 // It is initialized by switchGoToolchain.
67 var Startup struct {
68         GOTOOLCHAIN   string // $GOTOOLCHAIN setting
69         AutoFile      string // go.mod or go.work file consulted
70         AutoGoVersion string // go line found in file
71         AutoToolchain string // toolchain line found in file
72 }
73
74 // A TooNewError explains that a module is too new for this version of Go.
75 type TooNewError struct {
76         What      string
77         GoVersion string
78         Toolchain string // for callers if they want to use it, but not printed
79 }
80
81 func (e *TooNewError) Error() string {
82         var explain string
83         if Startup.GOTOOLCHAIN != "" && Startup.GOTOOLCHAIN != "auto" {
84                 explain = "; GOTOOLCHAIN=" + Startup.GOTOOLCHAIN
85         }
86         if Startup.AutoFile != "" && (Startup.AutoGoVersion != "" || Startup.AutoToolchain != "") {
87                 explain += fmt.Sprintf("; %s sets ", base.ShortPath(Startup.AutoFile))
88                 if Startup.AutoToolchain != "" {
89                         explain += "toolchain " + Startup.AutoToolchain
90                 } else {
91                         explain += "go " + Startup.AutoGoVersion
92                 }
93         }
94         return fmt.Sprintf("%v requires go >= %v (running go %v%v)", e.What, e.GoVersion, Local(), explain)
95 }
96
97 var ErrTooNew = errors.New("module too new")
98
99 func (e *TooNewError) Is(err error) bool {
100         return err == ErrTooNew
101 }
102
103 // A Switcher provides the ability to switch to a new toolchain in response to TooNewErrors.
104 // See [cmd/go/internal/toolchain.Switcher] for documentation.
105 type Switcher interface {
106         Error(err error)
107         Switch(ctx context.Context)
108 }