|
10 | 10 | package main
|
11 | 11 |
|
12 | 12 | import (
|
| 13 | + "errors" |
13 | 14 | "fmt"
|
14 | 15 | exec "internal/execabs"
|
| 16 | + "internal/goversion" |
| 17 | + "io/fs" |
15 | 18 | "log"
|
16 | 19 | "os"
|
17 | 20 | "path/filepath"
|
@@ -43,6 +46,7 @@ func main() {
|
43 | 46 | apiDir := filepath.Join(goroot, "api")
|
44 | 47 | out, err := exec.Command(goCmd(), "tool", "api",
|
45 | 48 | "-c", findAPIDirFiles(apiDir),
|
| 49 | + allowNew(apiDir), |
46 | 50 | "-next", filepath.Join(apiDir, "next.txt"),
|
47 | 51 | "-except", filepath.Join(apiDir, "except.txt")).CombinedOutput()
|
48 | 52 | if err != nil {
|
@@ -71,3 +75,35 @@ func findAPIDirFiles(apiDir string) string {
|
71 | 75 | }
|
72 | 76 | return strings.Join(apiFiles, ",")
|
73 | 77 | }
|
| 78 | + |
| 79 | +// allowNew returns the -allow_new flag to use for the 'go tool api' invocation. |
| 80 | +func allowNew(apiDir string) string { |
| 81 | + // Verify that the api/go1.n.txt for previous Go version exists. |
| 82 | + // It definitely should, otherwise it's a signal that the logic below may be outdated. |
| 83 | + if _, err := os.Stat(filepath.Join(apiDir, fmt.Sprintf("go1.%d.txt", goversion.Version-1))); err != nil { |
| 84 | + log.Fatalln("Problem with api file for previous release:", err) |
| 85 | + } |
| 86 | + |
| 87 | + // See whether the api/go1.n.txt for this Go version has been created. |
| 88 | + // (As of April 2021, it gets created during the release of the first Beta.) |
| 89 | + _, err := os.Stat(filepath.Join(apiDir, fmt.Sprintf("go1.%d.txt", goversion.Version))) |
| 90 | + if errors.Is(err, fs.ErrNotExist) { |
| 91 | + // It doesn't exist, so we're in development or before Beta 1. |
| 92 | + // At this stage, unmentioned API additions are deemed okay. |
| 93 | + // (They will be quietly shown in API check output, but the test won't fail). |
| 94 | + return "-allow_new=true" |
| 95 | + } else if err == nil { |
| 96 | + // The api/go1.n.txt for this Go version has been created, |
| 97 | + // so we're definitely past Beta 1 in the release cycle. |
| 98 | + // |
| 99 | + // From this point, enforce that api/go1.n.txt is an accurate and complete |
| 100 | + // representation of what's going into the release by failing API check if |
| 101 | + // there are API additions (a month into the freeze, there shouldn't be many). |
| 102 | + // |
| 103 | + // See golang.org/issue/43956. |
| 104 | + return "-allow_new=false" |
| 105 | + } else { |
| 106 | + log.Fatal(err) |
| 107 | + } |
| 108 | + panic("unreachable") |
| 109 | +} |
0 commit comments