internal/frontend: show build context on doc page

If it is not all/all, show the build context at
the bottom of the documentation.

This is just a preliminary implementation, so users
can experience the feature before we provide a proper UI.

For golang/go#37232

Change-Id: Ic48a246a8793e61917a31f66580249997255ba77
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/290095
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
diff --git a/content/static/css/unit_doc.css b/content/static/css/unit_doc.css
index 1b560f9..ecc1811 100644
--- a/content/static/css/unit_doc.css
+++ b/content/static/css/unit_doc.css
@@ -35,3 +35,8 @@
 .UnitDoc .Documentation h4 {
   font-size: 1.375rem;
 }
+.UnitDoc-buildContext {
+  font-style: italic;
+  padding-top: 1rem;
+  text-align: right;
+}
diff --git a/content/static/html/helpers/_unit_doc.tmpl b/content/static/html/helpers/_unit_doc.tmpl
index 6a46f3b..cbae337 100644
--- a/content/static/html/helpers/_unit_doc.tmpl
+++ b/content/static/html/helpers/_unit_doc.tmpl
@@ -12,6 +12,11 @@
     <div class="Documentation js-documentation">
       {{if .DocBody.String}}
         {{.DocBody}}
+        {{if or (ne .GOOS "all") (ne .GOARCH "all")}}
+          <div class=UnitDoc-buildContext>
+            GOOS={{.GOOS}}, GOARCH={{.GOARCH}}
+          </div>
+        {{end}}
       {{else}}
         <div class="UnitDoc-emptySection">
           <img src="/static/img/gopher-airplane.svg" alt="The Go Gopher"/>
diff --git a/internal/frontend/server_test.go b/internal/frontend/server_test.go
index ff76f54..d3acf26 100644
--- a/internal/frontend/server_test.go
+++ b/internal/frontend/server_test.go
@@ -351,6 +351,7 @@
 
 var (
 	in      = htmlcheck.In
+	notIn   = htmlcheck.NotIn
 	hasText = htmlcheck.HasText
 	attr    = htmlcheck.HasAttr
 
@@ -778,7 +779,9 @@
 			name:           "package default",
 			urlPath:        fmt.Sprintf("/%s", sample.PackagePath),
 			wantStatusCode: http.StatusOK,
-			want:           pagecheck.UnitHeader(pkgV100, unversioned, isPackage),
+			want: in("",
+				pagecheck.UnitHeader(pkgV100, unversioned, isPackage),
+				notIn(".UnitDoc-buildContext")),
 		},
 		{
 			name:           "package default redirect",
@@ -1037,25 +1040,33 @@
 			name:           "two docs default",
 			urlPath:        "/a.com/two/pkg",
 			wantStatusCode: http.StatusOK,
-			want:           in(".Documentation-variables", hasText("var L")),
+			want: in("",
+				in(".Documentation-variables", hasText("var L")),
+				in(".UnitDoc-buildContext", hasText("GOOS=linux"))),
 		},
 		{
 			name:           "two docs linux",
 			urlPath:        "/a.com/two/pkg?GOOS=linux",
 			wantStatusCode: http.StatusOK,
-			want:           in(".Documentation-variables", hasText("var L")),
+			want: in("",
+				in(".Documentation-variables", hasText("var L")),
+				in(".UnitDoc-buildContext", hasText("GOOS=linux"))),
 		},
 		{
 			name:           "two docs windows",
 			urlPath:        "/a.com/two/pkg?GOOS=windows",
 			wantStatusCode: http.StatusOK,
-			want:           in(".Documentation-variables", hasText("var W")),
+			want: in("",
+				in(".Documentation-variables", hasText("var W")),
+				in(".UnitDoc-buildContext", hasText("GOOS=windows"))),
 		},
 		{
 			name:           "two docs no match",
 			urlPath:        "/a.com/two/pkg?GOOS=dragonfly",
 			wantStatusCode: http.StatusOK,
-			want:           htmlcheck.NotIn(".Documentation-variables"),
+			want: in("",
+				notIn(".Documentation-variables"),
+				notIn(".UnitDoc-buildContext")),
 		},
 	}
 }
diff --git a/internal/frontend/unit_main.go b/internal/frontend/unit_main.go
index c14ab21..0b7ef21 100644
--- a/internal/frontend/unit_main.go
+++ b/internal/frontend/unit_main.go
@@ -79,6 +79,9 @@
 	// tag on the main unit page.
 	DocSynopsis string
 
+	// GOOS and GOARCH are the build context for the doc.
+	GOOS, GOARCH string
+
 	// SourceFiles contains .go files for the package.
 	SourceFiles []*File
 
@@ -161,11 +164,14 @@
 		docLinks, modLinks []link
 		files              []*File
 		synopsis           string
+		goos, goarch       string
 	)
 
 	doc := internal.DocumentationForBuildContext(unit.Documentation, bc)
 	if doc != nil {
 		synopsis = doc.Synopsis
+		goos = doc.GOOS
+		goarch = doc.GOARCH
 		end := middleware.ElapsedStat(ctx, "DecodePackage")
 		docPkg, err := godoc.DecodePackage(doc.Source)
 		end()
@@ -229,6 +235,8 @@
 		DocOutline:        docParts.Outline,
 		DocBody:           docParts.Body,
 		DocSynopsis:       synopsis,
+		GOOS:              goos,
+		GOARCH:            goarch,
 		SourceFiles:       files,
 		RepositoryURL:     um.SourceInfo.RepoURL(),
 		SourceURL:         um.SourceInfo.DirectoryURL(internal.Suffix(um.Path, um.ModulePath)),