Commit 71d9e956 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

cmd/api: handle contexts re-converging

Fixes #4303

R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/6816058
parent e53a2c40
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
"os/exec" "os/exec"
"path" "path"
"path/filepath" "path/filepath"
"regexp"
"runtime" "runtime"
"sort" "sort"
"strconv" "strconv"
...@@ -192,17 +193,29 @@ func main() { ...@@ -192,17 +193,29 @@ func main() {
fail = !compareAPI(bw, features, required, optional, exception) 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) { func compareAPI(w io.Writer, features, required, optional, exception []string) (ok bool) {
ok = true ok = true
var optionalSet = make(map[string]bool) // feature => true optionalSet := set(optional)
var exceptionSet = make(map[string]bool) // exception => true exceptionSet := set(exception)
for _, f := range optional { featureSet := set(features)
optionalSet[f] = true
}
for _, f := range exception {
exceptionSet[f] = true
}
sort.Strings(features) sort.Strings(features)
sort.Strings(required) sort.Strings(required)
...@@ -215,15 +228,17 @@ func compareAPI(w io.Writer, features, required, optional, exception []string) ( ...@@ -215,15 +228,17 @@ func compareAPI(w io.Writer, features, required, optional, exception []string) (
for len(required) > 0 || len(features) > 0 { for len(required) > 0 || len(features) > 0 {
switch { switch {
case len(features) == 0 || required[0] < features[0]: case len(features) == 0 || (len(required) > 0 && required[0] < features[0]):
feature := take(&required) feature := take(&required)
if exceptionSet[feature] { if exceptionSet[feature] {
fmt.Fprintf(w, "~%s\n", feature) fmt.Fprintf(w, "~%s\n", feature)
} else if featureSet[featureWithoutContext(feature)] {
// okay.
} else { } else {
fmt.Fprintf(w, "-%s\n", feature) fmt.Fprintf(w, "-%s\n", feature)
ok = false // broke compatibility 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) newFeature := take(&features)
if optionalSet[newFeature] { if optionalSet[newFeature] {
// Known added feature to the upcoming release. // Known added feature to the upcoming release.
......
...@@ -84,10 +84,10 @@ func TestCompareAPI(t *testing.T) { ...@@ -84,10 +84,10 @@ func TestCompareAPI(t *testing.T) {
}{ }{
{ {
name: "feature added", name: "feature added",
features: []string{"C", "A", "B"}, features: []string{"A", "B", "C", "D", "E", "F"},
required: []string{"A", "C"}, required: []string{"B", "D"},
ok: true, ok: true,
out: "+B\n", out: "+A\n+C\n+E\n+F\n",
}, },
{ {
name: "feature removed", name: "feature removed",
...@@ -112,6 +112,21 @@ func TestCompareAPI(t *testing.T) { ...@@ -112,6 +112,21 @@ func TestCompareAPI(t *testing.T) {
ok: true, ok: true,
out: "~B\n", 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 { for _, tt := range tests {
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment