mirror of
https://gitee.com/johng/gf.git
synced 2024-12-02 04:07:47 +08:00
242 lines
5.7 KiB
Go
242 lines
5.7 KiB
Go
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
|
//
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
// If a copy of the MIT was not distributed with this file,
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
//
|
|
|
|
package gcmd
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
|
|
"github.com/gogf/gf/v2/text/gstr"
|
|
)
|
|
|
|
// Print prints help info to stdout for current command.
|
|
func (c *Command) Print() {
|
|
c.PrintTo(os.Stdout)
|
|
}
|
|
|
|
// PrintTo prints help info to custom io.Writer.
|
|
func (c *Command) PrintTo(writer io.Writer) {
|
|
var (
|
|
prefix = gstr.Repeat(" ", 4)
|
|
buffer = bytes.NewBuffer(nil)
|
|
arguments = make([]Argument, len(c.Arguments))
|
|
)
|
|
// Copy options for printing.
|
|
copy(arguments, c.Arguments)
|
|
// Add built-in help option, just for info only.
|
|
arguments = append(arguments, defaultHelpOption)
|
|
|
|
// Usage.
|
|
if c.Usage != "" || c.Name != "" {
|
|
buffer.WriteString("USAGE\n")
|
|
buffer.WriteString(prefix)
|
|
if c.Usage != "" {
|
|
buffer.WriteString(c.Usage)
|
|
} else {
|
|
var (
|
|
p = c
|
|
name = c.Name
|
|
)
|
|
for p.parent != nil {
|
|
name = p.parent.Name + " " + name
|
|
p = p.parent
|
|
}
|
|
buffer.WriteString(name)
|
|
if len(c.commands) > 0 {
|
|
buffer.WriteString(` COMMAND`)
|
|
}
|
|
if c.hasArgumentFromIndex() {
|
|
buffer.WriteString(` ARGUMENT`)
|
|
}
|
|
buffer.WriteString(` [OPTION]`)
|
|
}
|
|
buffer.WriteString("\n\n")
|
|
}
|
|
// Command.
|
|
if len(c.commands) > 0 {
|
|
buffer.WriteString("COMMAND\n")
|
|
var (
|
|
maxSpaceLength = 0
|
|
)
|
|
for _, cmd := range c.commands {
|
|
if len(cmd.Name) > maxSpaceLength {
|
|
maxSpaceLength = len(cmd.Name)
|
|
}
|
|
}
|
|
for _, cmd := range c.commands {
|
|
var (
|
|
spaceLength = maxSpaceLength - len(cmd.Name)
|
|
wordwrapPrefix = gstr.Repeat(" ", len(prefix+cmd.Name)+spaceLength+4)
|
|
)
|
|
c.printLineBrief(printLineBriefInput{
|
|
Buffer: buffer,
|
|
Name: cmd.Name,
|
|
Prefix: prefix,
|
|
Brief: gstr.Trim(cmd.Brief),
|
|
WordwrapPrefix: wordwrapPrefix,
|
|
SpaceLength: spaceLength,
|
|
})
|
|
}
|
|
buffer.WriteString("\n")
|
|
}
|
|
|
|
// Argument.
|
|
if c.hasArgumentFromIndex() {
|
|
buffer.WriteString("ARGUMENT\n")
|
|
var (
|
|
maxSpaceLength = 0
|
|
)
|
|
for _, arg := range arguments {
|
|
if !arg.IsArg {
|
|
continue
|
|
}
|
|
if len(arg.Name) > maxSpaceLength {
|
|
maxSpaceLength = len(arg.Name)
|
|
}
|
|
}
|
|
for _, arg := range arguments {
|
|
if !arg.IsArg {
|
|
continue
|
|
}
|
|
var (
|
|
spaceLength = maxSpaceLength - len(arg.Name)
|
|
wordwrapPrefix = gstr.Repeat(" ", len(prefix+arg.Name)+spaceLength+4)
|
|
)
|
|
c.printLineBrief(printLineBriefInput{
|
|
Buffer: buffer,
|
|
Name: arg.Name,
|
|
Prefix: prefix,
|
|
Brief: gstr.Trim(arg.Brief),
|
|
WordwrapPrefix: wordwrapPrefix,
|
|
SpaceLength: spaceLength,
|
|
})
|
|
}
|
|
buffer.WriteString("\n")
|
|
}
|
|
|
|
// Option.
|
|
if c.hasArgumentFromOption() {
|
|
buffer.WriteString("OPTION\n")
|
|
var (
|
|
nameStr string
|
|
maxSpaceLength = 0
|
|
)
|
|
for _, arg := range arguments {
|
|
if arg.IsArg {
|
|
continue
|
|
}
|
|
if arg.Short != "" {
|
|
nameStr = fmt.Sprintf("-%s,--%s", arg.Short, arg.Name)
|
|
} else {
|
|
nameStr = fmt.Sprintf("-/--%s", arg.Name)
|
|
}
|
|
if len(nameStr) > maxSpaceLength {
|
|
maxSpaceLength = len(nameStr)
|
|
}
|
|
}
|
|
for _, arg := range arguments {
|
|
if arg.IsArg {
|
|
continue
|
|
}
|
|
if arg.Short != "" {
|
|
nameStr = fmt.Sprintf("-%s, --%s", arg.Short, arg.Name)
|
|
} else {
|
|
nameStr = fmt.Sprintf("-/--%s", arg.Name)
|
|
}
|
|
var (
|
|
brief = gstr.Trim(arg.Brief)
|
|
spaceLength = maxSpaceLength - len(nameStr)
|
|
wordwrapPrefix = gstr.Repeat(" ", len(prefix+nameStr)+spaceLength+4)
|
|
)
|
|
c.printLineBrief(printLineBriefInput{
|
|
Buffer: buffer,
|
|
Name: nameStr,
|
|
Prefix: prefix,
|
|
Brief: brief,
|
|
WordwrapPrefix: wordwrapPrefix,
|
|
SpaceLength: spaceLength,
|
|
})
|
|
}
|
|
buffer.WriteString("\n")
|
|
}
|
|
|
|
// Example.
|
|
if c.Examples != "" {
|
|
buffer.WriteString("EXAMPLE\n")
|
|
for _, line := range gstr.SplitAndTrim(gstr.Trim(c.Examples), "\n") {
|
|
buffer.WriteString(prefix)
|
|
buffer.WriteString(gstr.WordWrap(gstr.Trim(line), maxLineChars, "\n"+prefix))
|
|
buffer.WriteString("\n")
|
|
}
|
|
buffer.WriteString("\n")
|
|
}
|
|
|
|
// Description.
|
|
if c.Description != "" {
|
|
buffer.WriteString("DESCRIPTION\n")
|
|
for _, line := range gstr.SplitAndTrim(gstr.Trim(c.Description), "\n") {
|
|
buffer.WriteString(prefix)
|
|
buffer.WriteString(gstr.WordWrap(gstr.Trim(line), maxLineChars, "\n"+prefix))
|
|
buffer.WriteString("\n")
|
|
}
|
|
buffer.WriteString("\n")
|
|
}
|
|
|
|
// Additional.
|
|
if c.Additional != "" {
|
|
lineStr := gstr.WordWrap(gstr.Trim(c.Additional), maxLineChars, "\n")
|
|
buffer.WriteString(lineStr)
|
|
buffer.WriteString("\n")
|
|
}
|
|
content := buffer.String()
|
|
content = gstr.Replace(content, "\t", " ")
|
|
_, _ = writer.Write([]byte(content))
|
|
}
|
|
|
|
type printLineBriefInput struct {
|
|
Buffer *bytes.Buffer
|
|
Name string
|
|
Prefix string
|
|
Brief string
|
|
WordwrapPrefix string
|
|
SpaceLength int
|
|
}
|
|
|
|
func (c *Command) printLineBrief(in printLineBriefInput) {
|
|
briefArray := gstr.SplitAndTrim(in.Brief, "\n")
|
|
if len(briefArray) == 0 {
|
|
// If command brief is empty, it just prints its command name.
|
|
briefArray = []string{""}
|
|
}
|
|
for i, line := range briefArray {
|
|
var lineStr string
|
|
if i == 0 {
|
|
lineStr = fmt.Sprintf(
|
|
"%s%s%s%s\n",
|
|
in.Prefix, in.Name, gstr.Repeat(" ", in.SpaceLength+4), line,
|
|
)
|
|
} else {
|
|
lineStr = fmt.Sprintf(
|
|
"%s%s%s%s\n",
|
|
in.Prefix, gstr.Repeat(" ", len(in.Name)), gstr.Repeat(" ", in.SpaceLength+4), line,
|
|
)
|
|
}
|
|
lineStr = gstr.WordWrap(lineStr, maxLineChars, "\n"+in.WordwrapPrefix)
|
|
in.Buffer.WriteString(lineStr)
|
|
}
|
|
}
|
|
|
|
func (c *Command) defaultHelpFunc(ctx context.Context, parser *Parser) error {
|
|
// Print command help info to stdout.
|
|
c.Print()
|
|
return nil
|
|
}
|