Skip to content

Commit 7425dc1

Browse files
committed
internal: support "all" in BuildContext
Handle BuildContexts where one or more parts are "all". These should only occur when searching for a matching Documentation, not sorting. (Because we sort only when there is more than one Documentation, and if there is an all/all Documentation then there aren't any others.) For golang/go#37232 Change-Id: I898aba8f73d2682798d56c47cc6773709f10c702 Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/290094 Trust: Jonathan Amsterdam <[email protected]> Run-TryBot: Jonathan Amsterdam <[email protected]> TryBot-Result: kokoro <[email protected]> Reviewed-by: Julie Qiu <[email protected]>
1 parent 2579a6b commit 7425dc1

File tree

6 files changed

+104
-28
lines changed

6 files changed

+104
-28
lines changed

internal/build_context.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ type BuildContext struct {
1111
GOOS, GOARCH string
1212
}
1313

14+
// All represents all values for a build context element (GOOS or GOARCH).
15+
const All = "all"
16+
1417
// BuildContexts are the build contexts we check when loading a package (see
1518
// internal/fetch/load.go).
1619
// We store documentation for all of the listed contexts.
@@ -25,6 +28,14 @@ var BuildContexts = []BuildContext{
2528
// CompareBuildContexts returns a negative number, 0, or a positive number depending on
2629
// the relative positions of c1 and c2 in BuildContexts.
2730
func CompareBuildContexts(c1, c2 BuildContext) int {
31+
if c1 == c2 {
32+
return 0
33+
}
34+
// We should never see a BuildContext with "all" here.
35+
if c1.GOOS == All || c1.GOARCH == All || c2.GOOS == All || c2.GOARCH == All {
36+
panic("BuildContext with 'all'")
37+
}
38+
2839
pos := func(c BuildContext) int {
2940
for i, d := range BuildContexts {
3041
if c == d {
@@ -44,12 +55,12 @@ func (d *Documentation) BuildContext() BuildContext {
4455
// DocumentationForBuildContext returns the first Documentation the list that
4556
// matches the BuildContext, or nil if none does. A Documentation matches if its
4657
// GOOS and GOARCH fields are the same as those of the BuildContext, or if the
47-
// BuildContext field is empty. That is, empty BuildContext fields act as
48-
// wildcards. So the zero BuildContext will match the first element of docs, if
49-
// there is one.
58+
// Documentation field is "all", or if the BuildContext field is empty. That is,
59+
// empty BuildContext fields act as wildcards. So the zero BuildContext will
60+
// match the first element of docs, if there is one.
5061
func DocumentationForBuildContext(docs []*Documentation, bc BuildContext) *Documentation {
5162
for _, d := range docs {
52-
if (bc.GOOS == "" || bc.GOOS == d.GOOS) && (bc.GOARCH == "" || bc.GOARCH == d.GOARCH) {
63+
if (bc.GOOS == "" || d.GOOS == All || bc.GOOS == d.GOOS) && (bc.GOARCH == "" || d.GOARCH == All || bc.GOARCH == d.GOARCH) {
5364
return d
5465
}
5566
}

internal/build_context_test.go

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,33 @@ package internal
77
import "testing"
88

99
func TestCompareBuildContexts(t *testing.T) {
10-
for i, c1 := range BuildContexts {
11-
if got := CompareBuildContexts(c1, c1); got != 0 {
12-
t.Errorf("%v: got %d, want 0", c1, got)
13-
}
14-
for _, c2 := range BuildContexts[i+1:] {
15-
if got := CompareBuildContexts(c1, c2); got >= 0 {
16-
t.Errorf("%v, %v: got %d, want < 0", c1, c2, got)
10+
check := func(c1, c2 BuildContext, want int) {
11+
t.Helper()
12+
got := CompareBuildContexts(c1, c2)
13+
switch want {
14+
case 0:
15+
if got != 0 {
16+
t.Errorf("%v vs. %v: got %d, want 0", c1, c2, got)
1717
}
18-
if got := CompareBuildContexts(c2, c1); got <= 0 {
19-
t.Errorf("%v, %v: got %d, want > 0", c2, c1, got)
18+
case 1:
19+
if got <= 0 {
20+
t.Errorf("%v vs. %v: got %d, want > 0", c1, c2, got)
21+
}
22+
case -1:
23+
if got >= 0 {
24+
t.Errorf("%v vs. %v: got %d, want < 0", c1, c2, got)
2025
}
2126
}
2227
}
23-
got := CompareBuildContexts(BuildContext{"?", "?"}, BuildContexts[len(BuildContexts)-1])
24-
if got <= 0 {
25-
t.Errorf("unknown vs. last: got %d, want > 0", got)
28+
29+
for i, c1 := range BuildContexts {
30+
check(c1, c1, 0)
31+
for _, c2 := range BuildContexts[i+1:] {
32+
check(c1, c2, -1)
33+
check(c2, c1, 1)
34+
}
2635
}
36+
37+
// Special cases.
38+
check(BuildContext{"?", "?"}, BuildContexts[len(BuildContexts)-1], 1) // unknown is last
2739
}

internal/fetch/fetchdata_test.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ var moduleOnePackage = &testModule{
5454
Path: "github.com/basic/foo",
5555
},
5656
Documentation: []*internal.Documentation{{
57+
GOOS: internal.All,
58+
GOARCH: internal.All,
5759
Synopsis: "package foo exports a helpful constant.",
5860
}},
5961
Imports: []string{"net/http"},
@@ -124,6 +126,8 @@ var moduleMultiPackage = &testModule{
124126
Contents: "Another README FILE FOR TESTING.",
125127
},
126128
Documentation: []*internal.Documentation{{
129+
GOOS: internal.All,
130+
GOARCH: internal.All,
127131
Synopsis: "package bar",
128132
}},
129133
},
@@ -133,6 +137,8 @@ var moduleMultiPackage = &testModule{
133137
Path: "github.com/my/module/foo",
134138
},
135139
Documentation: []*internal.Documentation{{
140+
GOOS: internal.All,
141+
GOARCH: internal.All,
136142
Synopsis: "package foo",
137143
}},
138144
Imports: []string{"fmt", "github.com/my/module/bar"},
@@ -178,6 +184,8 @@ var moduleNoGoMod = &testModule{
178184
Path: "no.mod/module/p",
179185
},
180186
Documentation: []*internal.Documentation{{
187+
GOOS: internal.All,
188+
GOARCH: internal.All,
181189
Synopsis: "Package p is inside a module where a go.mod file hasn't been explicitly added yet.",
182190
}},
183191
},
@@ -241,6 +249,8 @@ var moduleBadPackages = &testModule{
241249
Path: "bad.mod/module/good",
242250
},
243251
Documentation: []*internal.Documentation{{
252+
GOOS: internal.All,
253+
GOARCH: internal.All,
244254
Synopsis: "Package good is inside a module that has bad packages.",
245255
}},
246256
},
@@ -397,6 +407,8 @@ var moduleNonRedist = &testModule{
397407
Path: "nonredistributable.mod/module/bar",
398408
},
399409
Documentation: []*internal.Documentation{{
410+
GOOS: internal.All,
411+
GOARCH: internal.All,
400412
Synopsis: "package bar",
401413
}},
402414
},
@@ -406,6 +418,8 @@ var moduleNonRedist = &testModule{
406418
Path: "nonredistributable.mod/module/bar/baz",
407419
},
408420
Documentation: []*internal.Documentation{{
421+
GOOS: internal.All,
422+
GOARCH: internal.All,
409423
Synopsis: "package baz",
410424
}},
411425
},
@@ -419,6 +433,8 @@ var moduleNonRedist = &testModule{
419433
Contents: "README FILE SHOW UP HERE BUT WILL BE REMOVED BEFORE DB INSERT",
420434
},
421435
Documentation: []*internal.Documentation{{
436+
GOOS: internal.All,
437+
GOARCH: internal.All,
422438
Synopsis: "package foo",
423439
}},
424440
Imports: []string{"fmt", "github.com/my/module/bar"},
@@ -468,7 +484,7 @@ var moduleBadImportPath = &testModule{
468484
Name: "foo",
469485
Path: "bad.import.path.com/good/import/path",
470486
},
471-
Documentation: []*internal.Documentation{{}},
487+
Documentation: []*internal.Documentation{{GOOS: internal.All, GOARCH: internal.All}},
472488
},
473489
},
474490
},
@@ -527,6 +543,8 @@ var moduleDocTest = &testModule{
527543
Path: "doc.test/permalink",
528544
},
529545
Documentation: []*internal.Documentation{{
546+
GOOS: internal.All,
547+
GOARCH: internal.All,
530548
Synopsis: "Package permalink is for testing the heading permalink documentation rendering feature.",
531549
}},
532550
},
@@ -566,6 +584,8 @@ var moduleDocTooLarge = &testModule{
566584
Path: "bigdoc.test",
567585
},
568586
Documentation: []*internal.Documentation{{
587+
GOOS: internal.All,
588+
GOARCH: internal.All,
569589
Synopsis: "This documentation is big.",
570590
}},
571591
},
@@ -674,6 +694,8 @@ var moduleStd = &testModule{
674694
Path: "builtin",
675695
},
676696
Documentation: []*internal.Documentation{{
697+
GOOS: internal.All,
698+
GOARCH: internal.All,
677699
Synopsis: "Package builtin provides documentation for Go's predeclared identifiers.",
678700
}},
679701
},
@@ -720,6 +742,8 @@ var moduleStd = &testModule{
720742
Path: "context",
721743
},
722744
Documentation: []*internal.Documentation{{
745+
GOOS: internal.All,
746+
GOARCH: internal.All,
723747
Synopsis: "Package context defines the Context type, which carries deadlines, cancelation signals, and other request-scoped values across API boundaries and between processes.",
724748
}},
725749
Imports: []string{"errors", "fmt", "reflect", "sync", "time"},
@@ -735,6 +759,8 @@ var moduleStd = &testModule{
735759
Path: "encoding/json",
736760
},
737761
Documentation: []*internal.Documentation{{
762+
GOOS: internal.All,
763+
GOARCH: internal.All,
738764
Synopsis: "Package json implements encoding and decoding of JSON as defined in RFC 7159.",
739765
}},
740766
Imports: []string{
@@ -761,6 +787,8 @@ var moduleStd = &testModule{
761787
Path: "errors",
762788
},
763789
Documentation: []*internal.Documentation{{
790+
GOOS: internal.All,
791+
GOARCH: internal.All,
764792
Synopsis: "Package errors implements functions to manipulate errors.",
765793
}},
766794
},
@@ -771,6 +799,8 @@ var moduleStd = &testModule{
771799
},
772800
Imports: []string{"errors", "fmt", "io", "os", "reflect", "sort", "strconv", "strings", "time"},
773801
Documentation: []*internal.Documentation{{
802+
GOOS: internal.All,
803+
GOARCH: internal.All,
774804
Synopsis: "Package flag implements command-line flag parsing.",
775805
}},
776806
},
@@ -807,6 +837,8 @@ var moduleMaster = &testModule{
807837
Path: "github.com/my/module/foo",
808838
},
809839
Documentation: []*internal.Documentation{{
840+
GOOS: internal.All,
841+
GOARCH: internal.All,
810842
Synopsis: "package foo exports a helpful constant.",
811843
}},
812844
},
@@ -843,6 +875,8 @@ var moduleLatest = &testModule{
843875
Path: "github.com/my/module/foo",
844876
},
845877
Documentation: []*internal.Documentation{{
878+
GOOS: internal.All,
879+
GOARCH: internal.All,
846880
Synopsis: "package foo exports a helpful constant.",
847881
}},
848882
},
@@ -892,6 +926,8 @@ package example_test
892926
Path: path + "/example",
893927
},
894928
Documentation: []*internal.Documentation{{
929+
GOOS: internal.All,
930+
GOARCH: internal.All,
895931
Synopsis: "Package example contains examples.",
896932
}},
897933
},

internal/fetch/load.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ func loadPackage(ctx context.Context, zipGoFiles []*zip.File, innerPath string,
112112
name: name,
113113
imports: imports,
114114
docs: []*internal.Documentation{{
115-
GOOS: bc.GOOS,
116-
GOARCH: bc.GOARCH,
115+
GOOS: internal.All,
116+
GOARCH: internal.All,
117117
Synopsis: synopsis,
118118
Source: source,
119119
}},
@@ -149,6 +149,14 @@ func loadPackage(ctx context.Context, zipGoFiles []*zip.File, innerPath string,
149149
pkg.docs = append(pkg.docs, doc)
150150
}
151151
}
152+
// If all the build contexts succeeded and had the same set of files, then
153+
// assume that the package doc is valid for all build contexts. Represent
154+
// this with a single Documentation whose GOOS and GOARCH are both "all".
155+
if len(docsByFiles) == 1 && len(pkg.docs) == len(internal.BuildContexts) {
156+
pkg.docs = pkg.docs[:1]
157+
pkg.docs[0].GOOS = internal.All
158+
pkg.docs[0].GOARCH = internal.All
159+
}
152160
return pkg, nil
153161
}
154162

internal/postgres/unit_test.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -449,13 +449,21 @@ func TestGetUnit(t *testing.T) {
449449
// Add a module that has documentation for two Go build contexts.
450450
m = sample.Module("a.com/twodoc", "v1.2.3", "p")
451451
pkg := m.Packages()[0]
452-
doc2 := &internal.Documentation{
453-
GOOS: "windows",
454-
GOARCH: "amd64",
455-
Synopsis: pkg.Documentation[0].Synopsis + " 2",
456-
Source: pkg.Documentation[0].Source,
452+
docs2 := []*internal.Documentation{
453+
{
454+
GOOS: "linux",
455+
GOARCH: "amd64",
456+
Synopsis: sample.Synopsis + " for linux",
457+
Source: sample.Documentation.Source,
458+
},
459+
{
460+
GOOS: "windows",
461+
GOARCH: "amd64",
462+
Synopsis: sample.Synopsis + " for windows",
463+
Source: sample.Documentation.Source,
464+
},
457465
}
458-
pkg.Documentation = append(pkg.Documentation, doc2)
466+
pkg.Documentation = docs2
459467
if err := testDB.InsertModule(ctx, m); err != nil {
460468
t.Fatal(err)
461469
}
@@ -578,7 +586,8 @@ func TestGetUnit(t *testing.T) {
578586
u := unit("a.com/twodoc/p", "a.com/twodoc", "v1.2.3", "p",
579587
nil,
580588
[]string{"p"})
581-
u.Documentation = append(u.Documentation, doc2)
589+
u.Documentation = docs2
590+
u.Subdirectories[0].Synopsis = docs2[0].Synopsis
582591
return u
583592
}(),
584593
},

internal/testing/sample/sample.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ var (
6262
Synopsis = "This is a package synopsis"
6363
ReadmeFilePath = "README.md"
6464
ReadmeContents = "readme"
65-
GOOS = "linux"
66-
GOARCH = "amd64"
65+
GOOS = internal.All
66+
GOARCH = internal.All
6767
)
6868

6969
// LicenseCmpOpts are options to use when comparing licenses with the cmp package.

0 commit comments

Comments
 (0)