This commit is contained in:
huangqian
2021-12-14 21:13:58 +08:00
5 changed files with 91 additions and 16 deletions

View File

@ -10,6 +10,7 @@ package gcmd
import (
"context"
"github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/text/gstr"
)
@ -70,16 +71,35 @@ func CommandFromCtx(ctx context.Context) *Command {
// AddCommand adds one or more sub-commands to current command.
func (c *Command) AddCommand(commands ...*Command) error {
for _, cmd := range commands {
cmd.Name = gstr.Trim(cmd.Name)
if cmd.Name == "" {
return gerror.New("command name should not be empty")
if err := c.doAddCommand(cmd); err != nil {
return err
}
cmd.parent = c
c.commands = append(c.commands, cmd)
}
return nil
}
// doAddCommand adds one sub-command to current command.
func (c *Command) doAddCommand(command *Command) error {
command.Name = gstr.Trim(command.Name)
if command.Name == "" {
return gerror.New("command name should not be empty")
}
// Repeated check.
var (
commandNameSet = gset.NewStrSet()
)
for _, cmd := range c.commands {
commandNameSet.Add(cmd.Name)
}
if commandNameSet.Contains(command.Name) {
return gerror.Newf(`command "%s" is already added to command "%s"`, command.Name, c.Name)
}
// Add the given command to its sub-commands array.
command.parent = c
c.commands = append(c.commands, command)
return nil
}
// AddObject adds one or more sub-commands to current command using struct object.
func (c *Command) AddObject(objects ...interface{}) error {
var (

View File

@ -42,11 +42,14 @@ func (c *Command) Print() {
name = p.parent.Name + " " + name
p = p.parent
}
if c.hasArgumentFromIndex() {
buffer.WriteString(fmt.Sprintf(`%s ARGUMENT [OPTION]`, name))
} else {
buffer.WriteString(fmt.Sprintf(`%s [OPTION]`, name))
buffer.WriteString(name)
if len(c.commands) > 0 {
buffer.WriteString(` COMMAND`)
}
if c.hasArgumentFromIndex() {
buffer.WriteString(` ARGUMENT`)
}
buffer.WriteString(` [OPTION]`)
}
buffer.WriteString("\n\n")
}

View File

@ -308,7 +308,9 @@ func newCommandFromMethod(object interface{}, method reflect.Value) (command *Co
func newArgumentsFromInput(object interface{}) (args []Argument, err error) {
var (
fields []gstructs.Field
fields []gstructs.Field
nameSet = gset.NewStrSet()
shortSet = gset.NewStrSet()
)
fields, err = gstructs.Fields(gstructs.FieldsInput{
Pointer: object,
@ -327,21 +329,40 @@ func newArgumentsFromInput(object interface{}) (args []Argument, err error) {
}
if arg.Name == helpOptionName {
return nil, gerror.Newf(
`option name "%s" is already token by built-in options`,
arg.Name,
`argument name "%s" defined in "%s.%s" is already token by built-in arguments`,
arg.Name, reflect.TypeOf(object).String(), field.Name(),
)
}
if arg.Short == helpOptionNameShort {
return nil, gerror.Newf(
`short option name "%s" is already token by built-in options`,
arg.Short,
`short argument name "%s" defined in "%s.%s" is already token by built-in arguments`,
arg.Short, reflect.TypeOf(object).String(), field.Name(),
)
}
if v, ok := metaData[tagNameArg]; ok {
arg.IsArg = gconv.Bool(v)
}
if nameSet.Contains(arg.Name) {
return nil, gerror.Newf(
`argument name "%s" defined in "%s.%s" is already token by other argument`,
arg.Name, reflect.TypeOf(object).String(), field.Name(),
)
}
nameSet.Add(arg.Name)
if arg.Short != "" {
if shortSet.Contains(arg.Short) {
return nil, gerror.Newf(
`short argument name "%s" defined in "%s.%s" is already token by other argument`,
arg.Short, reflect.TypeOf(object).String(), field.Name(),
)
}
shortSet.Add(arg.Short)
}
args = append(args, arg)
}
return
}

View File

@ -103,7 +103,7 @@ func ShellRun(cmd string) error {
}
// ShellExec executes given command `cmd` synchronously and returns the command result.
func ShellExec(cmd string, environment ...[]string) (string, error) {
func ShellExec(cmd string, environment ...[]string) (result string, err error) {
var (
buf = bytes.NewBuffer(nil)
p = NewProcess(
@ -114,7 +114,9 @@ func ShellExec(cmd string, environment ...[]string) (string, error) {
)
p.Stdout = buf
p.Stderr = buf
return buf.String(), p.Run()
err = p.Run()
result = buf.String()
return
}
// parseCommand parses command `cmd` into slice arguments.

View File

@ -0,0 +1,29 @@
// 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.
// go test *.go -bench=".*" -benchmem
package gproc_test
import (
"testing"
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/test/gtest"
)
func Test_ShellExec(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
s, err := gproc.ShellExec(`echo 123`)
t.AssertNil(err)
t.Assert(s, "123\n")
})
// error
gtest.C(t, func(t *gtest.T) {
_, err := gproc.ShellExec(`NoneExistCommandCall`)
t.AssertNE(err, nil)
})
}