LEFT | RIGHT |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Api computes the exported API of a set of Go packages. | 5 // Api computes the exported API of a set of Go packages. |
6 // | 6 // |
7 // BUG(bradfitz): Note that this tool is only currently suitable | 7 // BUG(bradfitz): Note that this tool is only currently suitable |
8 // for use on the Go standard library, not arbitrary packages. | 8 // for use on the Go standard library, not arbitrary packages. |
9 // Once the Go AST has type information, this tool will be more | 9 // Once the Go AST has type information, this tool will be more |
10 // reliable without hard-coded hacks throughout. | 10 // reliable without hard-coded hacks throughout. |
(...skipping 20 matching lines...) Expand all Loading... |
31 "path/filepath" | 31 "path/filepath" |
32 "regexp" | 32 "regexp" |
33 "runtime" | 33 "runtime" |
34 "sort" | 34 "sort" |
35 "strconv" | 35 "strconv" |
36 "strings" | 36 "strings" |
37 ) | 37 ) |
38 | 38 |
39 // Flags | 39 // Flags |
40 var ( | 40 var ( |
41 » // TODO(bradfitz): once Go 1.1 comes out, allow the -c flag to take a co
mma-separated | 41 » checkFile = flag.String("c", "", "optional comma-separated filename(s)
to check API against") |
42 » // list of files, rather than just one. | |
43 » checkFile = flag.String("c", "", "optional filename to check API agains
t") | |
44 allowNew = flag.Bool("allow_new", true, "allow API additions") | 42 allowNew = flag.Bool("allow_new", true, "allow API additions") |
45 exceptFile = flag.String("except", "", "optional filename of packages th
at are allowed to change without triggering a failure in the tool") | 43 exceptFile = flag.String("except", "", "optional filename of packages th
at are allowed to change without triggering a failure in the tool") |
46 nextFile = flag.String("next", "", "optional filename of tentative upc
oming 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.") | 44 nextFile = flag.String("next", "", "optional filename of tentative upc
oming 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.") |
47 verbose = flag.Bool("v", false, "verbose debugging") | 45 verbose = flag.Bool("v", false, "verbose debugging") |
48 forceCtx = flag.String("contexts", "", "optional comma-separated list
of <goos>-<goarch>[-cgo] to override default contexts.") | 46 forceCtx = flag.String("contexts", "", "optional comma-separated list
of <goos>-<goarch>[-cgo] to override default contexts.") |
49 ) | 47 ) |
50 | 48 |
51 // contexts are the default contexts which are scanned, unless | 49 // contexts are the default contexts which are scanned, unless |
52 // overridden by the -contexts flag. | 50 // overridden by the -contexts flag. |
53 var contexts = []*build.Context{ | 51 var contexts = []*build.Context{ |
(...skipping 18 matching lines...) Expand all Loading... |
72 {GOOS: "netbsd", GOARCH: "386", CgoEnabled: true}, | 70 {GOOS: "netbsd", GOARCH: "386", CgoEnabled: true}, |
73 {GOOS: "netbsd", GOARCH: "386"}, | 71 {GOOS: "netbsd", GOARCH: "386"}, |
74 {GOOS: "netbsd", GOARCH: "amd64", CgoEnabled: true}, | 72 {GOOS: "netbsd", GOARCH: "amd64", CgoEnabled: true}, |
75 {GOOS: "netbsd", GOARCH: "amd64"}, | 73 {GOOS: "netbsd", GOARCH: "amd64"}, |
76 {GOOS: "netbsd", GOARCH: "arm", CgoEnabled: true}, | 74 {GOOS: "netbsd", GOARCH: "arm", CgoEnabled: true}, |
77 {GOOS: "netbsd", GOARCH: "arm"}, | 75 {GOOS: "netbsd", GOARCH: "arm"}, |
78 {GOOS: "openbsd", GOARCH: "386", CgoEnabled: true}, | 76 {GOOS: "openbsd", GOARCH: "386", CgoEnabled: true}, |
79 {GOOS: "openbsd", GOARCH: "386"}, | 77 {GOOS: "openbsd", GOARCH: "386"}, |
80 {GOOS: "openbsd", GOARCH: "amd64", CgoEnabled: true}, | 78 {GOOS: "openbsd", GOARCH: "amd64", CgoEnabled: true}, |
81 {GOOS: "openbsd", GOARCH: "amd64"}, | 79 {GOOS: "openbsd", GOARCH: "amd64"}, |
82 {GOOS: "openbsd", GOARCH: "arm", CgoEnabled: true}, | |
83 {GOOS: "openbsd", GOARCH: "arm"}, | |
84 } | 80 } |
85 | 81 |
86 func contextName(c *build.Context) string { | 82 func contextName(c *build.Context) string { |
87 s := c.GOOS + "-" + c.GOARCH | 83 s := c.GOOS + "-" + c.GOARCH |
88 if c.CgoEnabled { | 84 if c.CgoEnabled { |
89 return s + "-cgo" | 85 return s + "-cgo" |
90 } | 86 } |
91 return s | 87 return s |
92 } | 88 } |
93 | 89 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 defer bw.Flush() | 192 defer bw.Flush() |
197 | 193 |
198 if *checkFile == "" { | 194 if *checkFile == "" { |
199 sort.Strings(features) | 195 sort.Strings(features) |
200 for _, f := range features { | 196 for _, f := range features { |
201 fmt.Fprintf(bw, "%s\n", f) | 197 fmt.Fprintf(bw, "%s\n", f) |
202 } | 198 } |
203 return | 199 return |
204 } | 200 } |
205 | 201 |
206 » required := fileFeatures(*checkFile) | 202 » var required []string |
| 203 » for _, file := range strings.Split(*checkFile, ",") { |
| 204 » » required = append(required, fileFeatures(file)...) |
| 205 » } |
207 optional := fileFeatures(*nextFile) | 206 optional := fileFeatures(*nextFile) |
208 exception := fileFeatures(*exceptFile) | 207 exception := fileFeatures(*exceptFile) |
209 fail = !compareAPI(bw, features, required, optional, exception) | 208 fail = !compareAPI(bw, features, required, optional, exception) |
210 } | 209 } |
211 | 210 |
212 func set(items []string) map[string]bool { | 211 func set(items []string) map[string]bool { |
213 s := make(map[string]bool) | 212 s := make(map[string]bool) |
214 for _, v := range items { | 213 for _, v := range items { |
215 s[v] = true | 214 s[v] = true |
216 } | 215 } |
(...skipping 23 matching lines...) Expand all Loading... |
240 s := (*sl)[0] | 239 s := (*sl)[0] |
241 *sl = (*sl)[1:] | 240 *sl = (*sl)[1:] |
242 return s | 241 return s |
243 } | 242 } |
244 | 243 |
245 for len(required) > 0 || len(features) > 0 { | 244 for len(required) > 0 || len(features) > 0 { |
246 switch { | 245 switch { |
247 case len(features) == 0 || (len(required) > 0 && required[0] < f
eatures[0]): | 246 case len(features) == 0 || (len(required) > 0 && required[0] < f
eatures[0]): |
248 feature := take(&required) | 247 feature := take(&required) |
249 if exceptionSet[feature] { | 248 if exceptionSet[feature] { |
250 » » » » fmt.Fprintf(w, "~%s\n", feature) | 249 » » » » // An "unfortunate" case: the feature was once |
| 250 » » » » // included in the API (e.g. go1.txt), but was |
| 251 » » » » // subsequently removed. These are already |
| 252 » » » » // acknowledged by being in the file |
| 253 » » » » // "api/except.txt". No need to print them out |
| 254 » » » » // here. |
251 } else if featureSet[featureWithoutContext(feature)] { | 255 } else if featureSet[featureWithoutContext(feature)] { |
252 // okay. | 256 // okay. |
253 } else { | 257 } else { |
254 fmt.Fprintf(w, "-%s\n", feature) | 258 fmt.Fprintf(w, "-%s\n", feature) |
255 ok = false // broke compatibility | 259 ok = false // broke compatibility |
256 } | 260 } |
257 case len(required) == 0 || (len(features) > 0 && required[0] > f
eatures[0]): | 261 case len(required) == 0 || (len(features) > 0 && required[0] > f
eatures[0]): |
258 newFeature := take(&features) | 262 newFeature := take(&features) |
259 if optionalSet[newFeature] { | 263 if optionalSet[newFeature] { |
260 // Known added feature to the upcoming release. | 264 // Known added feature to the upcoming release. |
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 } | 1195 } |
1192 | 1196 |
1193 func strListContains(l []string, s string) bool { | 1197 func strListContains(l []string, s string) bool { |
1194 for _, v := range l { | 1198 for _, v := range l { |
1195 if v == s { | 1199 if v == s { |
1196 return true | 1200 return true |
1197 } | 1201 } |
1198 } | 1202 } |
1199 return false | 1203 return false |
1200 } | 1204 } |
LEFT | RIGHT |