1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package help implements the ``go help'' command.
19 "cmd/go/internal/base"
22 // Help implements the 'help' command.
23 func Help(args
[]string) {
24 // 'go help documentation' generates doc.go.
25 if len(args
) == 1 && args
[0] == "documentation" {
26 fmt
.Println("// Copyright 2011 The Go Authors. All rights reserved.")
27 fmt
.Println("// Use of this source code is governed by a BSD-style")
28 fmt
.Println("// license that can be found in the LICENSE file.")
30 fmt
.Println("// Code generated by mkalldocs.sh; DO NOT EDIT.")
31 fmt
.Println("// Edit the documentation in other files and rerun mkalldocs.sh to generate this one.")
33 buf
:= new(bytes
.Buffer
)
34 PrintUsage(buf
, base
.Go
)
35 usage
:= &base
.Command
{Long
: buf
.String()}
36 cmds
:= []*base
.Command
{usage
}
37 for _
, cmd
:= range base
.Go
.Commands
{
38 if cmd
.UsageLine
== "gopath-get" {
39 // Avoid duplication of the "get" documentation.
42 cmds
= append(cmds
, cmd
)
43 cmds
= append(cmds
, cmd
.Commands
...)
45 tmpl(&commentWriter
{W
: os
.Stdout
}, documentationTemplate
, cmds
)
46 fmt
.Println("package main")
52 for i
, arg
:= range args
{
53 for _
, sub
:= range cmd
.Commands
{
54 if sub
.Name() == arg
{
60 // helpSuccess is the help command using as many args as possible that would succeed.
61 helpSuccess
:= "go help"
63 helpSuccess
= " " + strings
.Join(args
[:i
], " ")
65 fmt
.Fprintf(os
.Stderr
, "go help %s: unknown help topic. Run '%s'.\n", strings
.Join(args
, " "), helpSuccess
)
66 os
.Exit(2) // failed at 'go help cmd'
69 if len(cmd
.Commands
) > 0 {
70 PrintUsage(os
.Stdout
, cmd
)
72 tmpl(os
.Stdout
, helpTemplate
, cmd
)
74 // not exit 2: succeeded at 'go help cmd'.
78 var usageTemplate
= `{{.Long | trim}}
82 {{.UsageLine}} <command> [arguments]
85 {{range .Commands}}{{if or (.Runnable) .Commands}}
86 {{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
88 Use "go help{{with .LongName}} {{.}}{{end}} <command>" for more information about a command.
89 {{if eq (.UsageLine) "go"}}
90 Additional help topics:
91 {{range .Commands}}{{if and (not .Runnable) (not .Commands)}}
92 {{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
94 Use "go help{{with .LongName}} {{.}}{{end}} <topic>" for more information about that topic.
98 var helpTemplate
= `{{if .Runnable}}usage: {{.UsageLine}}
100 {{end}}{{.Long | trim}}
103 var documentationTemplate
= `{{range .}}{{if .Short}}{{.Short | capitalize}}
105 {{end}}{{if .Commands}}` + usageTemplate
+ `{{else}}{{if .Runnable}}Usage:
109 {{end}}{{.Long | trim}}
114 // commentWriter writes a Go comment to the underlying io.Writer,
115 // using line comment form (//).
116 type commentWriter
struct {
118 wroteSlashes
bool // Wrote "//" at the beginning of the current line.
121 func (c
*commentWriter
) Write(p
[]byte) (int, error
) {
123 for i
, b
:= range p
{
129 if _
, err
:= io
.WriteString(c
.W
, s
); err
!= nil {
132 c
.wroteSlashes
= true
134 n0
, err
:= c
.W
.Write(p
[i
: i
+1])
140 c
.wroteSlashes
= false
146 // An errWriter wraps a writer, recording whether a write error occurred.
147 type errWriter
struct {
152 func (w
*errWriter
) Write(b
[]byte) (int, error
) {
153 n
, err
:= w
.w
.Write(b
)
160 // tmpl executes the given template text on data, writing the result to w.
161 func tmpl(w io
.Writer
, text
string, data
interface{}) {
162 t
:= template
.New("top")
163 t
.Funcs(template
.FuncMap
{"trim": strings
.TrimSpace
, "capitalize": capitalize
})
164 template
.Must(t
.Parse(text
))
165 ew
:= &errWriter
{w
: w
}
166 err
:= t
.Execute(ew
, data
)
168 // I/O error writing. Ignore write on closed pipe.
169 if strings
.Contains(ew
.err
.Error(), "pipe") {
172 base
.Fatalf("writing output: %v", ew
.err
)
179 func capitalize(s
string) string {
183 r
, n
:= utf8
.DecodeRuneInString(s
)
184 return string(unicode
.ToTitle(r
)) + s
[n
:]
187 func PrintUsage(w io
.Writer
, cmd
*base
.Command
) {
188 bw
:= bufio
.NewWriter(w
)
189 tmpl(bw
, usageTemplate
, cmd
)