]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: convert mkalldocs.sh to a Go program
authorBryan C. Mills <bcmills@google.com>
Wed, 15 Feb 2023 21:45:14 +0000 (16:45 -0500)
committerGopher Robot <gobot@golang.org>
Mon, 27 Feb 2023 21:45:11 +0000 (21:45 +0000)
mkalldocs.sh required a Unix shell, making it less accessible for
contributors on Windows. It also used a substantially different
codepath to regenerate the file than the one used to check the file
for staleness, making failures in TestDocsUpToDate more complex to
diagnose.

We can solve both of those problems by using the same technique as in
checkScriptReadme: use the test itself as the generator to update the
file. The test is already written in Go, the test binary already knows
how to mimic the 'go' command, and this approach brings the difference
between the test and the generator down to a single flag check.

Updates #26735.

Change-Id: I7c6f65cb0e0c29e334e38a45412e0a73c4d31d42
Reviewed-on: https://go-review.googlesource.com/c/go/+/468636
Reviewed-by: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Bryan Mills <bcmills@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>

src/cmd/go/alldocs.go
src/cmd/go/help_test.go
src/cmd/go/internal/help/help.go
src/cmd/go/main.go
src/cmd/go/mkalldocs.sh [deleted file]

index 0f8433efca71c8932e40b7f6527de9f3be2e30a5..fe177090161eeaeaa00bfcd1fa4a2de7d8cfb987 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Code generated by mkalldocs.sh; DO NOT EDIT.
+// Code generated by 'go test cmd/go -v -run=TestDocsUpToDate -fixdocs'; DO NOT EDIT.
 // Edit the documentation in other files and rerun mkalldocs.sh to generate this one.
 
 // Go is a tool for managing Go source code.
index 3e1d817ca5b236bf4954c1c3f3fd1d6811ec92cd..7f05cdf2cbcc7b6529840f6edb25552c64d4c26f 100644 (file)
@@ -5,37 +5,58 @@
 package main_test
 
 import (
-       "bytes"
+       "flag"
        "go/format"
-       diffpkg "internal/diff"
+       "internal/diff"
+       "internal/testenv"
        "os"
+       "strings"
        "testing"
-
-       "cmd/go/internal/help"
-       "cmd/go/internal/modload"
 )
 
+var fixDocs = flag.Bool("fixdocs", false, "if true, update alldocs.go")
+
 func TestDocsUpToDate(t *testing.T) {
-       t.Parallel()
+       if !*fixDocs {
+               t.Parallel()
+       }
 
-       if !modload.Enabled() {
-               t.Skipf("help.Help in GOPATH mode is configured by main.main")
+       // We run 'go help documentation' as a subprocess instead of
+       // calling help.Help directly because it may be sensitive to
+       // init-time configuration
+       cmd := testenv.Command(t, testGo, "help", "documentation")
+       // Unset GO111MODULE so that the 'go get' section matches
+       // the default 'go get' implementation.
+       cmd.Env = append(cmd.Environ(), "GO111MODULE=")
+       cmd.Stderr = new(strings.Builder)
+       out, err := cmd.Output()
+       if err != nil {
+               t.Fatalf("%v: %v\n%s", cmd, err, cmd.Stderr)
        }
 
-       buf := new(bytes.Buffer)
-       // Match the command in mkalldocs.sh that generates alldocs.go.
-       help.Help(buf, []string{"documentation"})
-       internal := buf.Bytes()
-       internal, err := format.Source(internal)
+       alldocs, err := format.Source(out)
        if err != nil {
-               t.Fatalf("gofmt docs: %v", err)
+               t.Fatalf("format.Source($(%v)): %v", cmd, err)
        }
-       alldocs, err := os.ReadFile("alldocs.go")
+
+       const srcPath = `alldocs.go`
+       old, err := os.ReadFile(srcPath)
        if err != nil {
-               t.Fatalf("error reading alldocs.go: %v", err)
+               t.Fatalf("error reading %s: %v", srcPath, err)
+       }
+       diff := diff.Diff(srcPath, old, "go help documentation | gofmt", alldocs)
+       if diff == nil {
+               t.Logf("%s is up to date.", srcPath)
+               return
        }
-       if !bytes.Equal(internal, alldocs) {
-               t.Errorf("alldocs.go is not up to date; run mkalldocs.sh to regenerate it\n%s",
-                       diffpkg.Diff("go help documentation | gofmt", internal, "alldocs.go", alldocs))
+
+       if *fixDocs {
+               if err := os.WriteFile(srcPath, alldocs, 0666); err != nil {
+                       t.Fatal(err)
+               }
+               t.Logf("wrote %d bytes to %s", len(alldocs), srcPath)
+       } else {
+               t.Logf("\n%s", diff)
+               t.Errorf("%s is stale. To update, run 'go generate cmd/go'.", srcPath)
        }
 }
index 804c910dacc2ee23f3ecfd5af5c06ae08001f936..dd1f2f745c0fde22a7f2a9c754436efa55ef20c0 100644 (file)
@@ -27,7 +27,7 @@ func Help(w io.Writer, args []string) {
                fmt.Fprintln(w, "// Use of this source code is governed by a BSD-style")
                fmt.Fprintln(w, "// license that can be found in the LICENSE file.")
                fmt.Fprintln(w)
-               fmt.Fprintln(w, "// Code generated by mkalldocs.sh; DO NOT EDIT.")
+               fmt.Fprintln(w, "// Code generated by 'go test cmd/go -v -run=TestDocsUpToDate -fixdocs'; DO NOT EDIT.")
                fmt.Fprintln(w, "// Edit the documentation in other files and rerun mkalldocs.sh to generate this one.")
                fmt.Fprintln(w)
                buf := new(strings.Builder)
index ee705e87e0513328ce7d3af2ce125357333ddcc0..8d1c3c0e8ba204d52ed40eb5f41168be9703b6a8 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:generate ./mkalldocs.sh
+//go:generate go test cmd/go -v -run=TestDocsUpToDate -fixdocs
 
 package main
 
diff --git a/src/cmd/go/mkalldocs.sh b/src/cmd/go/mkalldocs.sh
deleted file mode 100755 (executable)
index a2b0aca..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2012 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-set -e
-
-go build -o go.latest
-# If the command used to generate alldocs.go changes, update TestDocsUpToDate in
-# help_test.go.
-GO111MODULE='' ./go.latest help documentation >alldocs.go
-gofmt -w alldocs.go
-rm go.latest