Skip to content

Commit f736de0

Browse files
committed
cmd/doc: always print package clause except for commands
There was an implicit heuristic before about when to print the package clause or omit it, but it was undocumented and confusing. Get rid of it and print it always unless asking for the package docs for a command, which are more of a usage message than a programming question. This simplifies the processing. There are several paths to the output, so to put the fix in one place we place a wrapper before the output buffer than adds the clause when Write is first called. The tests don't verify this behavior, but they didn't before either. Unsure what the right approach is but this will do for now. Fixes #31457 Change-Id: Ia6a9e740d556f45265c55f06b5306621c7a40ea9 Reviewed-on: https://go-review.googlesource.com/c/go/+/177797 Reviewed-by: Russ Cox <[email protected]>
1 parent 1531192 commit f736de0

File tree

1 file changed

+35
-46
lines changed

1 file changed

+35
-46
lines changed

src/cmd/doc/pkg.go

Lines changed: 35 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,36 @@ const (
3131
)
3232

3333
type Package struct {
34-
writer io.Writer // Destination for output.
35-
name string // Package name, json for encoding/json.
36-
userPath string // String the user used to find this package.
37-
pkg *ast.Package // Parsed package.
38-
file *ast.File // Merged from all files in the package
39-
doc *doc.Package
40-
build *build.Package
41-
typedValue map[*doc.Value]bool // Consts and vars related to types.
42-
constructor map[*doc.Func]bool // Constructors.
43-
packageClausePrinted bool // Prevent repeated package clauses.
44-
fs *token.FileSet // Needed for printing.
45-
buf bytes.Buffer
34+
writer io.Writer // Destination for output.
35+
name string // Package name, json for encoding/json.
36+
userPath string // String the user used to find this package.
37+
pkg *ast.Package // Parsed package.
38+
file *ast.File // Merged from all files in the package
39+
doc *doc.Package
40+
build *build.Package
41+
typedValue map[*doc.Value]bool // Consts and vars related to types.
42+
constructor map[*doc.Func]bool // Constructors.
43+
fs *token.FileSet // Needed for printing.
44+
buf pkgBuffer
45+
}
46+
47+
// pkgBuffer is a wrapper for bytes.Buffer that prints a package clause the
48+
// first time Write is called.
49+
type pkgBuffer struct {
50+
pkg *Package
51+
printed bool // Prevent repeated package clauses.
52+
bytes.Buffer
53+
}
54+
55+
func (pb *pkgBuffer) Write(p []byte) (int, error) {
56+
if !pb.printed && len(p) > 0 {
57+
pb.printed = true
58+
// Only show package clause for commands if requested explicitly.
59+
if pb.pkg.pkg.Name != "main" || showCmd {
60+
pb.pkg.packageClause()
61+
}
62+
}
63+
return pb.Buffer.Write(p)
4664
}
4765

4866
type PackageError string // type returned by pkg.Fatalf.
@@ -171,7 +189,7 @@ func parsePackage(writer io.Writer, pkg *build.Package, userPath string) *Packag
171189
}
172190
}
173191

174-
return &Package{
192+
p := &Package{
175193
writer: writer,
176194
name: pkg.Name,
177195
userPath: userPath,
@@ -183,6 +201,8 @@ func parsePackage(writer io.Writer, pkg *build.Package, userPath string) *Packag
183201
build: pkg,
184202
fs: fs,
185203
}
204+
p.buf.pkg = p
205+
return p
186206
}
187207

188208
func (pkg *Package) Printf(format string, args ...interface{}) {
@@ -426,9 +446,6 @@ func joinStrings(ss []string) string {
426446
// allDoc prints all the docs for the package.
427447
func (pkg *Package) allDoc() {
428448
defer pkg.flush()
429-
if pkg.showInternals() {
430-
pkg.packageClause(false)
431-
}
432449

433450
doc.ToText(&pkg.buf, pkg.doc.Doc, "", indent, indentedWidth)
434451
pkg.newlines(1)
@@ -489,14 +506,11 @@ func (pkg *Package) allDoc() {
489506
// packageDoc prints the docs for the package (package doc plus one-liners of the rest).
490507
func (pkg *Package) packageDoc() {
491508
defer pkg.flush()
492-
if pkg.showInternals() {
493-
pkg.packageClause(false)
494-
}
495509

496510
doc.ToText(&pkg.buf, pkg.doc.Doc, "", indent, indentedWidth)
497511
pkg.newlines(1)
498512

499-
if !pkg.showInternals() {
513+
if pkg.pkg.Name == "main" && !showCmd {
500514
// Show only package docs for commands.
501515
return
502516
}
@@ -509,29 +523,8 @@ func (pkg *Package) packageDoc() {
509523
pkg.bugs()
510524
}
511525

512-
// showInternals reports whether we should show the internals
513-
// of a package as opposed to just the package docs.
514-
// Used to decide whether to suppress internals for commands.
515-
// Called only by Package.packageDoc.
516-
func (pkg *Package) showInternals() bool {
517-
return pkg.pkg.Name != "main" || showCmd
518-
}
519-
520526
// packageClause prints the package clause.
521-
// The argument boolean, if true, suppresses the output if the
522-
// user's argument is identical to the actual package path or
523-
// is empty, meaning it's the current directory.
524-
func (pkg *Package) packageClause(checkUserPath bool) {
525-
if pkg.packageClausePrinted {
526-
return
527-
}
528-
529-
if checkUserPath {
530-
if pkg.userPath == "" || pkg.userPath == pkg.build.ImportPath {
531-
return
532-
}
533-
}
534-
527+
func (pkg *Package) packageClause() {
535528
importPath := pkg.build.ImportComment
536529
if importPath == "" {
537530
importPath = pkg.build.ImportPath
@@ -563,7 +556,6 @@ func (pkg *Package) packageClause(checkUserPath bool) {
563556
if !usingModules && importPath != pkg.build.ImportPath {
564557
pkg.Printf("WARNING: package source is installed in %q\n", pkg.build.ImportPath)
565558
}
566-
pkg.packageClausePrinted = true
567559
}
568560

569561
// valueSummary prints a one-line summary for each set of values and constants.
@@ -701,9 +693,6 @@ func (pkg *Package) symbolDoc(symbol string) bool {
701693
found := false
702694
// Functions.
703695
for _, fun := range pkg.findFuncs(symbol) {
704-
if !found {
705-
pkg.packageClause(true)
706-
}
707696
// Symbol is a function.
708697
decl := fun.Decl
709698
pkg.emit(fun.Doc, decl)

0 commit comments

Comments
 (0)