From 71d9e956a00e95f734f633056882475832d534f4 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 30 Oct 2012 13:12:59 +0100 Subject: [PATCH] cmd/api: handle contexts re-converging Fixes #4303 R=golang-dev, adg CC=golang-dev https://golang.org/cl/6816058 --- src/cmd/api/goapi.go | 35 +++++++++++++++++++++++++---------- src/cmd/api/goapi_test.go | 21 ++++++++++++++++++--- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go index d6ca892103..26b3482409 100644 --- a/src/cmd/api/goapi.go +++ b/src/cmd/api/goapi.go @@ -29,6 +29,7 @@ import ( "os/exec" "path" "path/filepath" + "regexp" "runtime" "sort" "strconv" @@ -192,17 +193,29 @@ func main() { fail = !compareAPI(bw, features, required, optional, exception) } +func set(items []string) map[string]bool { + s := make(map[string]bool) + for _, v := range items { + s[v] = true + } + return s +} + +var spaceParensRx = regexp.MustCompile(` \(\S+?\)`) + +func featureWithoutContext(f string) string { + if !strings.Contains(f, "(") { + return f + } + return spaceParensRx.ReplaceAllString(f, "") +} + func compareAPI(w io.Writer, features, required, optional, exception []string) (ok bool) { ok = true - var optionalSet = make(map[string]bool) // feature => true - var exceptionSet = make(map[string]bool) // exception => true - for _, f := range optional { - optionalSet[f] = true - } - for _, f := range exception { - exceptionSet[f] = true - } + optionalSet := set(optional) + exceptionSet := set(exception) + featureSet := set(features) sort.Strings(features) sort.Strings(required) @@ -215,15 +228,17 @@ func compareAPI(w io.Writer, features, required, optional, exception []string) ( for len(required) > 0 || len(features) > 0 { switch { - case len(features) == 0 || required[0] < features[0]: + case len(features) == 0 || (len(required) > 0 && required[0] < features[0]): feature := take(&required) if exceptionSet[feature] { fmt.Fprintf(w, "~%s\n", feature) + } else if featureSet[featureWithoutContext(feature)] { + // okay. } else { fmt.Fprintf(w, "-%s\n", feature) ok = false // broke compatibility } - case len(required) == 0 || required[0] > features[0]: + case len(required) == 0 || (len(features) > 0 && required[0] > features[0]): newFeature := take(&features) if optionalSet[newFeature] { // Known added feature to the upcoming release. diff --git a/src/cmd/api/goapi_test.go b/src/cmd/api/goapi_test.go index b4fccdfd4e..1a86c0ec70 100644 --- a/src/cmd/api/goapi_test.go +++ b/src/cmd/api/goapi_test.go @@ -84,10 +84,10 @@ func TestCompareAPI(t *testing.T) { }{ { name: "feature added", - features: []string{"C", "A", "B"}, - required: []string{"A", "C"}, + features: []string{"A", "B", "C", "D", "E", "F"}, + required: []string{"B", "D"}, ok: true, - out: "+B\n", + out: "+A\n+C\n+E\n+F\n", }, { name: "feature removed", @@ -112,6 +112,21 @@ func TestCompareAPI(t *testing.T) { ok: true, out: "~B\n", }, + { + // http://golang.org/issue/4303 + name: "contexts reconverging", + required: []string{ + "A", + "pkg syscall (darwin-386), type RawSockaddrInet6 struct", + "pkg syscall (darwin-amd64), type RawSockaddrInet6 struct", + }, + features: []string{ + "A", + "pkg syscall, type RawSockaddrInet6 struct", + }, + ok: true, + out: "+pkg syscall, type RawSockaddrInet6 struct\n", + }, } for _, tt := range tests { buf := new(bytes.Buffer) -- 2.48.1