aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/api/goapi.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2012-05-22 18:41:20 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2012-05-22 18:41:20 -0700
commit71c1a7b77700ea8e549368c8606d74d7a7b5104f (patch)
treefa6ff20008539c733e4b1d11aaf7faa2ddf53014 /src/cmd/api/goapi.go
parent33a89b5fdad1917e292b7a8aea5f164c1460177d (diff)
downloadgo-71c1a7b77700ea8e549368c8606d74d7a7b5104f.tar.xz
cmd/api: add api/next.txt
This quiets all.bash noise for upcoming features we know about. The all.bash warnings will now only print for things not in next.txt (or in next.txt but not in the API). Once an API is frozen, we rename next.txt to a new frozen file (like go1.txt) Fixes #3651 R=golang-dev, r CC=golang-dev https://golang.org/cl/6218069
Diffstat (limited to 'src/cmd/api/goapi.go')
-rw-r--r--src/cmd/api/goapi.go105
1 files changed, 73 insertions, 32 deletions
diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go
index 3d5151754b..533636cd8a 100644
--- a/src/cmd/api/goapi.go
+++ b/src/cmd/api/goapi.go
@@ -35,8 +35,12 @@ import (
// Flags
var (
+ // TODO(bradfitz): once Go 1.1 comes out, allow the -c flag to take a comma-separated
+ // list of files, rather than just one.
checkFile = flag.String("c", "", "optional filename to check API against")
- verbose = flag.Bool("v", false, "Verbose debugging")
+ allowNew = flag.Bool("allow_new", true, "allow API additions")
+ nextFile = flag.String("next", "", "optional filename of tentative upcoming API features for the next release. This file can be lazily maintained. It only affects the delta warnings from the -c file printed on success.")
+ verbose = flag.Bool("v", false, "verbose debugging")
)
var contexts = []*build.Context{
@@ -123,45 +127,82 @@ func main() {
}
sort.Strings(features)
+ fail := false
+ defer func() {
+ if fail {
+ os.Exit(1)
+ }
+ }()
+
bw := bufio.NewWriter(os.Stdout)
defer bw.Flush()
- if *checkFile != "" {
- bs, err := ioutil.ReadFile(*checkFile)
- if err != nil {
- log.Fatalf("Error reading file %s: %v", *checkFile, err)
+ if *checkFile == "" {
+ for _, f := range features {
+ fmt.Fprintf(bw, "%s\n", f)
}
- v1 := strings.Split(strings.TrimSpace(string(bs)), "\n")
- sort.Strings(v1)
- v2 := features
- take := func(sl *[]string) string {
- s := (*sl)[0]
- *sl = (*sl)[1:]
- return s
+ return
+ }
+
+ var required []string
+ for _, filename := range []string{*checkFile} {
+ required = append(required, fileFeatures(filename)...)
+ }
+ sort.Strings(required)
+
+ var optional = make(map[string]bool) // feature => true
+ if *nextFile != "" {
+ for _, feature := range fileFeatures(*nextFile) {
+ optional[feature] = true
}
- changes := false
- for len(v1) > 0 || len(v2) > 0 {
- switch {
- case len(v2) == 0 || v1[0] < v2[0]:
- fmt.Fprintf(bw, "-%s\n", take(&v1))
- changes = true
- case len(v1) == 0 || v1[0] > v2[0]:
- fmt.Fprintf(bw, "+%s\n", take(&v2))
- // we allow API additions now
- default:
- take(&v1)
- take(&v2)
+ }
+
+ take := func(sl *[]string) string {
+ s := (*sl)[0]
+ *sl = (*sl)[1:]
+ return s
+ }
+
+ for len(required) > 0 || len(features) > 0 {
+ switch {
+ case len(features) == 0 || required[0] < features[0]:
+ fmt.Fprintf(bw, "-%s\n", take(&required))
+ fail = true // broke compatibility
+ case len(required) == 0 || required[0] > features[0]:
+ newFeature := take(&features)
+ if optional[newFeature] {
+ // Known added feature to the upcoming release.
+ // Delete it from the map so we can detect any upcoming features
+ // which were never seen. (so we can clean up the nextFile)
+ delete(optional, newFeature)
+ } else {
+ fmt.Fprintf(bw, "+%s\n", newFeature)
+ if !*allowNew {
+ fail = true // we're in lock-down mode for next release
+ }
}
+ default:
+ take(&required)
+ take(&features)
}
- if changes {
- bw.Flush()
- os.Exit(1)
- }
- } else {
- for _, f := range features {
- fmt.Fprintf(bw, "%s\n", f)
- }
}
+
+ var missing []string
+ for feature := range optional {
+ missing = append(missing, feature)
+ }
+ sort.Strings(missing)
+ for _, feature := range missing {
+ fmt.Fprintf(bw, "(in next file, but not in API) -%s\n", feature)
+ }
+}
+
+func fileFeatures(filename string) []string {
+ bs, err := ioutil.ReadFile(filename)
+ if err != nil {
+ log.Fatalf("Error reading file %s: %v", filename, err)
+ }
+ return strings.Split(strings.TrimSpace(string(bs)), "\n")
}
// pkgSymbol represents a symbol in a package