Skip to content

Commit 26a69ce

Browse files
author
Jay Conrod
committed
x/exp/apidiff: copy changes from x/tools/internal/apidiff
We copied golang.org/x/exp/apidiff to x/tools a few months ago in anticipation of developing gorelease in x/tools, which would depend on apidiff. We've decided to develop gorelease here in x/exp instead, which means the copy in x/tools is no longer needed. This CL copies changes made to the copy in x/tools since it was made. Another CL will delete the copy in x/tools. Change-Id: Ied79138616c2f3b2f49a0ee5ca95ff3179351354 Reviewed-on: https://go-review.googlesource.com/c/exp/+/197298 Run-TryBot: Jay Conrod <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Jonathan Amsterdam <[email protected]>
1 parent 81c7196 commit 26a69ce

File tree

6 files changed

+111
-19
lines changed

6 files changed

+111
-19
lines changed

apidiff/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ var x = C // old type is int64, new is int
265265
var y int64 = x // fails with new: different types in assignment
266266
```
267267

268-
A change to the value of a constant can break compatiblity if the value is used
268+
A change to the value of a constant can break compatibility if the value is used
269269
in an array type:
270270

271271
```

apidiff/apidiff.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@ import (
2424
func Changes(old, new *types.Package) Report {
2525
d := newDiffer(old, new)
2626
d.checkPackage()
27-
return Report{
28-
Incompatible: d.incompatibles.collect(),
29-
Compatible: d.compatibles.collect(),
27+
r := Report{}
28+
for _, m := range d.incompatibles.collect() {
29+
r.Changes = append(r.Changes, Change{Message: m, Compatible: false})
3030
}
31+
for _, m := range d.compatibles.collect() {
32+
r.Changes = append(r.Changes, Change{Message: m, Compatible: true})
33+
}
34+
return r
3135
}
3236

3337
type differ struct {

apidiff/apidiff_test.go

+80-8
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import (
66
"go/types"
77
"io/ioutil"
88
"os"
9+
"os/exec"
910
"path/filepath"
1011
"reflect"
12+
"runtime"
1113
"sort"
1214
"strings"
1315
"testing"
@@ -26,22 +28,24 @@ func TestChanges(t *testing.T) {
2628
sort.Strings(wanti)
2729
sort.Strings(wantc)
2830

29-
oldpkg, err := load("apidiff/old", dir)
31+
oldpkg, err := load(t, "apidiff/old", dir)
3032
if err != nil {
3133
t.Fatal(err)
3234
}
33-
newpkg, err := load("apidiff/new", dir)
35+
newpkg, err := load(t, "apidiff/new", dir)
3436
if err != nil {
3537
t.Fatal(err)
3638
}
3739

3840
report := Changes(oldpkg.Types, newpkg.Types)
3941

40-
if !reflect.DeepEqual(report.Incompatible, wanti) {
41-
t.Errorf("incompatibles: got %v\nwant %v\n", report.Incompatible, wanti)
42+
got := report.messages(false)
43+
if !reflect.DeepEqual(got, wanti) {
44+
t.Errorf("incompatibles: got %v\nwant %v\n", got, wanti)
4245
}
43-
if !reflect.DeepEqual(report.Compatible, wantc) {
44-
t.Errorf("compatibles: got %v\nwant %v\n", report.Compatible, wantc)
46+
got = report.messages(true)
47+
if !reflect.DeepEqual(got, wantc) {
48+
t.Errorf("compatibles: got %v\nwant %v\n", got, wantc)
4549
}
4650
}
4751

@@ -113,7 +117,9 @@ func splitIntoPackages(t *testing.T, dir string) (incompatibles, compatibles []s
113117
return
114118
}
115119

116-
func load(importPath, goPath string) (*packages.Package, error) {
120+
func load(t *testing.T, importPath, goPath string) (*packages.Package, error) {
121+
needsGoPackages(t)
122+
117123
cfg := &packages.Config{
118124
Mode: packages.LoadTypes,
119125
}
@@ -132,7 +138,7 @@ func load(importPath, goPath string) (*packages.Package, error) {
132138
}
133139

134140
func TestExportedFields(t *testing.T) {
135-
pkg, err := load("golang.org/x/exp/apidiff/testdata/exported_fields", "")
141+
pkg, err := load(t, "golang.org/x/exp/apidiff/testdata/exported_fields", "")
136142
if err != nil {
137143
t.Fatal(err)
138144
}
@@ -164,3 +170,69 @@ func TestExportedFields(t *testing.T) {
164170
}
165171
}
166172
}
173+
174+
// needsGoPackages skips t if the go/packages driver (or 'go' tool) implied by
175+
// the current process environment is not present in the path.
176+
//
177+
// Copied and adapted from golang.org/x/tools/internal/testenv.
178+
func needsGoPackages(t *testing.T) {
179+
t.Helper()
180+
181+
tool := os.Getenv("GOPACKAGESDRIVER")
182+
switch tool {
183+
case "off":
184+
// "off" forces go/packages to use the go command.
185+
tool = "go"
186+
case "":
187+
if _, err := exec.LookPath("gopackagesdriver"); err == nil {
188+
tool = "gopackagesdriver"
189+
} else {
190+
tool = "go"
191+
}
192+
}
193+
194+
needsTool(t, tool)
195+
}
196+
197+
// needsTool skips t if the named tool is not present in the path.
198+
//
199+
// Copied and adapted from golang.org/x/tools/internal/testenv.
200+
func needsTool(t *testing.T, tool string) {
201+
_, err := exec.LookPath(tool)
202+
if err == nil {
203+
return
204+
}
205+
206+
t.Helper()
207+
if allowMissingTool(tool) {
208+
t.Skipf("skipping because %s tool not available: %v", tool, err)
209+
} else {
210+
t.Fatalf("%s tool not available: %v", tool, err)
211+
}
212+
}
213+
214+
func allowMissingTool(tool string) bool {
215+
if runtime.GOOS == "android" {
216+
// Android builds generally run tests on a separate machine from the build,
217+
// so don't expect any external tools to be available.
218+
return true
219+
}
220+
221+
if tool == "go" && os.Getenv("GO_BUILDER_NAME") == "illumos-amd64-joyent" {
222+
// Work around a misconfigured builder (see https://golang.org/issue/33950).
223+
return true
224+
}
225+
226+
// If a developer is actively working on this test, we expect them to have all
227+
// of its dependencies installed. However, if it's just a dependency of some
228+
// other module (for example, being run via 'go test all'), we should be more
229+
// tolerant of unusual environments.
230+
return !packageMainIsDevel()
231+
}
232+
233+
// packageMainIsDevel reports whether the module containing package main
234+
// is a development version (if module information is available).
235+
//
236+
// Builds in GOPATH mode and builds that lack module information are assumed to
237+
// be development versions.
238+
var packageMainIsDevel = func() bool { return true }

apidiff/report.go

+20-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,23 @@ import (
88

99
// Report describes the changes detected by Changes.
1010
type Report struct {
11-
Incompatible, Compatible []string
11+
Changes []Change
12+
}
13+
14+
// A Change describes a single API change.
15+
type Change struct {
16+
Message string
17+
Compatible bool
18+
}
19+
20+
func (r Report) messages(compatible bool) []string {
21+
var msgs []string
22+
for _, c := range r.Changes {
23+
if c.Compatible == compatible {
24+
msgs = append(msgs, c.Message)
25+
}
26+
}
27+
return msgs
1228
}
1329

1430
func (r Report) String() string {
@@ -28,13 +44,13 @@ func (r Report) Text(w io.Writer) error {
2844

2945
func (r Report) TextIncompatible(w io.Writer, withHeader bool) error {
3046
if withHeader {
31-
return r.writeMessages(w, "Incompatible changes:", r.Incompatible)
47+
return r.writeMessages(w, "Incompatible changes:", r.messages(false))
3248
}
33-
return r.writeMessages(w, "", r.Incompatible)
49+
return r.writeMessages(w, "", r.messages(false))
3450
}
3551

3652
func (r Report) TextCompatible(w io.Writer) error {
37-
return r.writeMessages(w, "Compatible changes:", r.Compatible)
53+
return r.writeMessages(w, "Compatible changes:", r.messages(true))
3854
}
3955

4056
func (r Report) writeMessages(w io.Writer, header string, msgs []string) error {

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ require (
1010
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028
1111
golang.org/x/mod v0.1.0
1212
golang.org/x/sys v0.0.0-20190412213103-97732733099d
13-
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479
13+
golang.org/x/tools v0.0.0-20190925164712-ae58c0ff6b32
1414
)

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w
2323
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
2424
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
2525
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
26-
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479 h1:lfN2PY/jymfnxkNHlbBF5DwPsUvhqUnrdgfK01iH2s0=
27-
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
26+
golang.org/x/tools v0.0.0-20190925164712-ae58c0ff6b32 h1:xE6VFETO5vvJp3W3iihukTHFkQiu9yrTMJNKu20CwE4=
27+
golang.org/x/tools v0.0.0-20190925164712-ae58c0ff6b32/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
2828
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

0 commit comments

Comments
 (0)