}
optional := fileFeatures(*nextFile)
exception := fileFeatures(*exceptFile)
- fail = !compareAPI(bw, features, required, optional, exception,
- *allowNew && strings.Contains(runtime.Version(), "devel"))
+ fail = !compareAPI(bw, features, required, optional, exception, *allowNew)
}
// export emits the exported package features.
package main
import (
+ "errors"
"fmt"
exec "internal/execabs"
+ "internal/goversion"
+ "io/fs"
"log"
"os"
"path/filepath"
apiDir := filepath.Join(goroot, "api")
out, err := exec.Command(goCmd(), "tool", "api",
"-c", findAPIDirFiles(apiDir),
+ allowNew(apiDir),
"-next", filepath.Join(apiDir, "next.txt"),
"-except", filepath.Join(apiDir, "except.txt")).CombinedOutput()
if err != nil {
}
return strings.Join(apiFiles, ",")
}
+
+// allowNew returns the -allow_new flag to use for the 'go tool api' invocation.
+func allowNew(apiDir string) string {
+ // Verify that the api/go1.n.txt for previous Go version exists.
+ // It definitely should, otherwise it's a signal that the logic below may be outdated.
+ if _, err := os.Stat(filepath.Join(apiDir, fmt.Sprintf("go1.%d.txt", goversion.Version-1))); err != nil {
+ log.Fatalln("Problem with api file for previous release:", err)
+ }
+
+ // See whether the api/go1.n.txt for this Go version has been created.
+ // (As of April 2021, it gets created during the release of the first Beta.)
+ _, err := os.Stat(filepath.Join(apiDir, fmt.Sprintf("go1.%d.txt", goversion.Version)))
+ if errors.Is(err, fs.ErrNotExist) {
+ // It doesn't exist, so we're in development or before Beta 1.
+ // At this stage, unmentioned API additions are deemed okay.
+ // (They will be quietly shown in API check output, but the test won't fail).
+ return "-allow_new=true"
+ } else if err == nil {
+ // The api/go1.n.txt for this Go version has been created,
+ // so we're definitely past Beta 1 in the release cycle.
+ //
+ // From this point, enforce that api/go1.n.txt is an accurate and complete
+ // representation of what's going into the release by failing API check if
+ // there are API additions (a month into the freeze, there shouldn't be many).
+ //
+ // See golang.org/issue/43956.
+ return "-allow_new=false"
+ } else {
+ log.Fatal(err)
+ }
+ panic("unreachable")
+}