internal/fetch: populate Unit.BuildContexts

Populate the lists of build contexts when fetching a module.

Currently we only do this when reading from the DB. We want
DataSources that rely only on fetch to have the right value.

For golang/go#47780

Change-Id: Ie85fba8ccb318bb4ed5c1f2153b0ba4216358022
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/344670
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/internal/fetch/fetchdata_test.go b/internal/fetch/fetchdata_test.go
index aef7177..c7bc799 100644
--- a/internal/fetch/fetchdata_test.go
+++ b/internal/fetch/fetchdata_test.go
@@ -87,7 +87,8 @@
 				},
 			},
 		}},
-		Imports: []string{"time"},
+		BuildContexts: []internal.BuildContext{internal.BuildContextAll},
+		Imports:       []string{"time"},
 	},
 }
 
@@ -142,7 +143,8 @@
 							API:      singleUnits[1].Documentation[0].API,
 						},
 					},
-					Imports: []string{"time"},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
+					Imports:       []string{"time"},
 				},
 			},
 		},
@@ -199,6 +201,7 @@
 							},
 						},
 					},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 				{
 					UnitMeta: internal.UnitMeta{
@@ -220,7 +223,8 @@
 							},
 						},
 					}},
-					Imports: []string{"example.com/multi/bar", "fmt"},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
+					Imports:       []string{"example.com/multi/bar", "fmt"},
 				},
 			},
 		},
@@ -304,6 +308,7 @@
 							},
 						}},
 					}},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 			},
 		},
@@ -410,6 +415,10 @@
 							Synopsis: "Package cpu implements processor feature detection used by the Go standard library.",
 						},
 					},
+					BuildContexts: []internal.BuildContext{
+						internal.BuildContextLinux, internal.BuildContextWindows,
+						internal.BuildContextDarwin, internal.BuildContextJS,
+					},
 				},
 			},
 		},
@@ -470,6 +479,7 @@
 						GOOS:   "linux",
 						GOARCH: "amd64",
 					}},
+					BuildContexts: []internal.BuildContext{internal.BuildContextLinux},
 				},
 			},
 		},
@@ -519,6 +529,7 @@
 							},
 						},
 					},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 				{
 					UnitMeta: internal.UnitMeta{
@@ -542,6 +553,7 @@
 							},
 						},
 					},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 				{
 					UnitMeta: internal.UnitMeta{
@@ -569,7 +581,8 @@
 							},
 						},
 					},
-					Imports: []string{"example.com/nonredist/bar", "fmt"},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
+					Imports:       []string{"example.com/nonredist/bar", "fmt"},
 				},
 			},
 		},
@@ -617,6 +630,7 @@
 						Path: "bad.import.path.com/good/import/path",
 					},
 					Documentation: []*internal.Documentation{{GOOS: internal.All, GOARCH: internal.All}},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 			},
 		},
@@ -681,6 +695,7 @@
 						GOARCH:   internal.All,
 						Synopsis: "Package permalink is for testing the heading permalink documentation rendering feature.",
 					}},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 			},
 		},
@@ -723,6 +738,7 @@
 						GOARCH:   internal.All,
 						Synopsis: "This documentation is big.",
 					}},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 			},
 		},
@@ -792,6 +808,7 @@
 							},
 						},
 					},
+					BuildContexts: []internal.BuildContext{internal.BuildContextJS},
 				},
 			},
 		},
@@ -859,6 +876,7 @@
 							},
 						},
 					},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 				{
 					UnitMeta: internal.UnitMeta{
@@ -1284,6 +1302,7 @@
 							},
 						},
 					},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 				{
 					UnitMeta: internal.UnitMeta{
@@ -1324,6 +1343,10 @@
 							Synopsis: "Pprof interprets and displays profiles of Go programs.",
 						},
 					},
+					BuildContexts: []internal.BuildContext{
+						internal.BuildContextLinux, internal.BuildContextWindows,
+						internal.BuildContextDarwin, internal.BuildContextJS,
+					},
 					Imports: []string{
 						"cmd/internal/objfile",
 						"crypto/tls",
@@ -1465,7 +1488,8 @@
 							},
 						},
 					},
-					Imports: []string{"errors", "fmt", "reflect", "sync", "time"},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
+					Imports:       []string{"errors", "fmt", "reflect", "sync", "time"},
 				},
 				{
 					UnitMeta: internal.UnitMeta{
@@ -2001,6 +2025,7 @@
 							},
 						},
 					},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 					Imports: []string{
 						"bytes",
 						"encoding",
@@ -2041,6 +2066,7 @@
 							},
 						},
 					},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 				{
 					UnitMeta: internal.UnitMeta{
@@ -2677,6 +2703,7 @@
 							},
 						},
 					},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 			},
 		},
@@ -2727,6 +2754,7 @@
 							},
 						},
 					},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 			},
 		},
@@ -2774,8 +2802,8 @@
 								},
 							},
 						},
-					},
-					},
+					}},
+					BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 				},
 			},
 		},
@@ -2830,6 +2858,7 @@
 							Synopsis: "Package example contains examples.",
 							API:      api,
 						}},
+						BuildContexts: []internal.BuildContext{internal.BuildContextAll},
 					},
 				},
 			},
diff --git a/internal/fetch/unit.go b/internal/fetch/unit.go
index 0f77a69..29de7c1 100644
--- a/internal/fetch/unit.go
+++ b/internal/fetch/unit.go
@@ -6,6 +6,7 @@
 
 import (
 	"path"
+	"sort"
 
 	"golang.org/x/pkgsite/internal"
 	"golang.org/x/pkgsite/internal/licenses"
@@ -65,6 +66,14 @@
 			dir.Name = pkg.name
 			dir.Imports = pkg.imports
 			dir.Documentation = pkg.docs
+			var bcs []internal.BuildContext
+			for _, d := range dir.Documentation {
+				bcs = append(bcs, internal.BuildContext{GOOS: d.GOOS, GOARCH: d.GOARCH})
+			}
+			sort.Slice(bcs, func(i, j int) bool {
+				return internal.CompareBuildContexts(bcs[i], bcs[j]) < 0
+			})
+			dir.BuildContexts = bcs
 		}
 		units = append(units, dir)
 	}
diff --git a/internal/postgres/insert_module_test.go b/internal/postgres/insert_module_test.go
index 0e1ca99..00e178d 100644
--- a/internal/postgres/insert_module_test.go
+++ b/internal/postgres/insert_module_test.go
@@ -111,7 +111,6 @@
 			}
 		}
 		wantu.Subdirectories = subdirectories
-		wantu.BuildContexts = got.BuildContexts
 		opts := cmp.Options{
 			cmpopts.EquateEmpty(),
 			cmpopts.IgnoreFields(licenses.Metadata{}, "Coverage", "OldCoverage"),
diff --git a/internal/testing/sample/sample.go b/internal/testing/sample/sample.go
index 27fdad1..72d5c12 100644
--- a/internal/testing/sample/sample.go
+++ b/internal/testing/sample/sample.go
@@ -225,6 +225,7 @@
 	return &internal.Unit{
 		UnitMeta:        *UnitMeta(path, modulePath, version, name, isRedistributable),
 		Documentation:   []*internal.Documentation{&doc},
+		BuildContexts:   []internal.BuildContext{{GOOS: doc.GOOS, GOARCH: doc.GOARCH}},
 		LicenseContents: Licenses(),
 		Imports:         imps,
 		NumImports:      len(imps),
diff --git a/internal/unit.go b/internal/unit.go
index db131f0..9d0d32e 100644
--- a/internal/unit.go
+++ b/internal/unit.go
@@ -45,7 +45,7 @@
 type Unit struct {
 	UnitMeta
 	Readme          *Readme
-	BuildContexts   []BuildContext   // set only on read
+	BuildContexts   []BuildContext
 	Documentation   []*Documentation // at most one on read
 	Subdirectories  []*PackageMeta
 	Imports         []string