mirror of
https://gitee.com/johng/gf.git
synced 2024-11-29 18:57:44 +08:00
improve package gcmd
This commit is contained in:
parent
4f0b45aeac
commit
01930c9899
@ -7,6 +7,7 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -141,3 +142,21 @@ func FormatCmdKey(s string) string {
|
||||
func FormatEnvKey(s string) string {
|
||||
return strings.ToUpper(strings.Replace(s, ".", "_", -1))
|
||||
}
|
||||
|
||||
// StripSlashes un-quotes a quoted string by AddSlashes.
|
||||
func StripSlashes(str string) string {
|
||||
var buf bytes.Buffer
|
||||
l, skip := len(str), false
|
||||
for i, char := range str {
|
||||
if skip {
|
||||
skip = false
|
||||
} else if char == '\\' {
|
||||
if i+1 < l && str[i+1] == '\\' {
|
||||
skip = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
buf.WriteRune(char)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ func (c *Command) Print() {
|
||||
|
||||
// Option.
|
||||
if len(options) > 0 {
|
||||
buffer.WriteString("OPTIONS\n")
|
||||
buffer.WriteString("OPTION\n")
|
||||
var (
|
||||
nameStr string
|
||||
maxSpaceLength = 0
|
||||
@ -110,16 +110,22 @@ func (c *Command) Print() {
|
||||
// Example.
|
||||
if c.Examples != "" {
|
||||
buffer.WriteString("EXAMPLE\n")
|
||||
buffer.WriteString(prefix)
|
||||
buffer.WriteString(gstr.WordWrap(gstr.Trim(c.Examples), maxLineChars, "\n"+prefix))
|
||||
for _, line := range gstr.SplitAndTrim(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")
|
||||
buffer.WriteString(prefix)
|
||||
buffer.WriteString(gstr.WordWrap(gstr.Trim(c.Description), maxLineChars, "\n"+prefix))
|
||||
for _, line := range gstr.SplitAndTrim(c.Description, "\n") {
|
||||
buffer.WriteString(prefix)
|
||||
buffer.WriteString(gstr.WordWrap(gstr.Trim(line), maxLineChars, "\n"+prefix))
|
||||
buffer.WriteString("\n")
|
||||
}
|
||||
buffer.WriteString("\n")
|
||||
}
|
||||
|
||||
|
135
os/gcmd/gcmd_z_unit_feature_object2_test.go
Normal file
135
os/gcmd/gcmd_z_unit_feature_object2_test.go
Normal file
@ -0,0 +1,135 @@
|
||||
// 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 gcmd_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcmd"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
)
|
||||
|
||||
type commandBuild struct {
|
||||
g.Meta `name:"build" root:"build" args:"true" brief:"{commandBuildBrief}" dc:"{commandBuildDc}" eg:"{commandBuildEg}" ad:"{commandBuildAd}"`
|
||||
nodeNameInConfigFile string // nodeNameInConfigFile is the node name for compiler configurations in configuration file.
|
||||
packedGoFileName string // packedGoFileName specifies the file name for packing common folders into one single go file.
|
||||
}
|
||||
|
||||
const (
|
||||
commandBuildBrief = `cross-building go project for lots of platforms`
|
||||
commandBuildEg = `
|
||||
gf build main.go
|
||||
gf build main.go --pack public,template
|
||||
gf build main.go --cgo
|
||||
gf build main.go -m none
|
||||
gf build main.go -n my-app -a all -s all
|
||||
gf build main.go -n my-app -a amd64,386 -s linux -p .
|
||||
gf build main.go -n my-app -v 1.0 -a amd64,386 -s linux,windows,darwin -p ./docker/bin
|
||||
`
|
||||
commandBuildDc = `
|
||||
The "build" command is most commonly used command, which is designed as a powerful wrapper for
|
||||
"go build" command for convenience cross-compiling usage.
|
||||
It provides much more features for building binary:
|
||||
1. Cross-Compiling for many platforms and architectures.
|
||||
2. Configuration file support for compiling.
|
||||
3. Build-In Variables.
|
||||
`
|
||||
commandBuildAd = `
|
||||
PLATFORMS
|
||||
darwin amd64,arm64
|
||||
freebsd 386,amd64,arm
|
||||
linux 386,amd64,arm,arm64,ppc64,ppc64le,mips,mipsle,mips64,mips64le
|
||||
netbsd 386,amd64,arm
|
||||
openbsd 386,amd64,arm
|
||||
windows 386,amd64
|
||||
`
|
||||
// https://golang.google.cn/doc/install/source
|
||||
commandBuildPlatforms = `
|
||||
darwin amd64
|
||||
darwin arm64
|
||||
ios amd64
|
||||
ios arm64
|
||||
freebsd 386
|
||||
freebsd amd64
|
||||
freebsd arm
|
||||
linux 386
|
||||
linux amd64
|
||||
linux arm
|
||||
linux arm64
|
||||
linux ppc64
|
||||
linux ppc64le
|
||||
linux mips
|
||||
linux mipsle
|
||||
linux mips64
|
||||
linux mips64le
|
||||
netbsd 386
|
||||
netbsd amd64
|
||||
netbsd arm
|
||||
openbsd 386
|
||||
openbsd amd64
|
||||
openbsd arm
|
||||
windows 386
|
||||
windows amd64
|
||||
android arm
|
||||
dragonfly amd64
|
||||
plan9 386
|
||||
plan9 amd64
|
||||
solaris amd64
|
||||
`
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(map[string]string{
|
||||
`commandBuildBrief`: commandBuildBrief,
|
||||
`commandBuildDc`: commandBuildDc,
|
||||
`commandBuildEg`: commandBuildEg,
|
||||
`commandBuildAd`: commandBuildAd,
|
||||
})
|
||||
}
|
||||
|
||||
type commandBuildInput struct {
|
||||
g.Meta `name:"build" config:"gfcli.build"`
|
||||
Name string `short:"n" name:"name" brief:"output binary name"`
|
||||
Version string `short:"v" name:"version" brief:"output binary version"`
|
||||
Arch string `short:"a" name:"arch" brief:"output binary architecture, multiple arch separated with ','"`
|
||||
System string `short:"s" name:"system" brief:"output binary system, multiple os separated with ','"`
|
||||
Output string `short:"o" name:"output" brief:"output binary path, used when building single binary file"`
|
||||
Path string `short:"p" name:"path" brief:"output binary directory path, default is './bin'" d:"./bin"`
|
||||
Extra string `short:"e" name:"extra" brief:"extra custom \"go build\" options"`
|
||||
Mod string `short:"m" name:"mod" brief:"like \"-mod\" option of \"go build\", use \"-m none\" to disable go module"`
|
||||
Cgo bool `short:"c" name:"cgo" brief:"enable or disable cgo feature, it's disabled in default" orphan:"true"`
|
||||
Pack string `name:"pack" brief:"pack specified folder into temporary go file before building and removes it after built"`
|
||||
}
|
||||
type commandBuildOutput struct{}
|
||||
|
||||
func (c commandBuild) Index(ctx context.Context, in commandBuildInput) (out *commandBuildOutput, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func TestNewFromObject(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var (
|
||||
ctx = gctx.New()
|
||||
)
|
||||
cmd, err := gcmd.NewFromObject(commandBuild{
|
||||
nodeNameInConfigFile: "gfcli.build",
|
||||
packedGoFileName: "build_pack_data.go",
|
||||
})
|
||||
t.AssertNil(err)
|
||||
|
||||
os.Args = []string{"build", "-h"}
|
||||
err = cmd.Run(ctx)
|
||||
t.AssertNil(err)
|
||||
})
|
||||
}
|
@ -8,9 +8,9 @@ package gstructs
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/utils"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
)
|
||||
|
||||
@ -18,10 +18,6 @@ const (
|
||||
jsonTagName = `json`
|
||||
)
|
||||
|
||||
var (
|
||||
tagMapRegex = regexp.MustCompile(`([\w\-]+):"(.+?)"`)
|
||||
)
|
||||
|
||||
// Tag returns the value associated with key in the tag string. If there is no
|
||||
// such key in the tag, Tag returns the empty string.
|
||||
func (f *Field) Tag(key string) string {
|
||||
@ -67,13 +63,10 @@ func (f *Field) TagStr() string {
|
||||
// TagMap returns all the tag of the field along with its value string as map.
|
||||
func (f *Field) TagMap() map[string]string {
|
||||
var (
|
||||
data = map[string]string{}
|
||||
match = tagMapRegex.FindAllStringSubmatch(f.TagStr(), -1)
|
||||
data = ParseTag(f.TagStr())
|
||||
)
|
||||
for _, m := range match {
|
||||
if len(m) == 3 {
|
||||
data[m[1]] = gtag.Parse(m[2])
|
||||
}
|
||||
for k, v := range data {
|
||||
data[k] = utils.StripSlashes(gtag.Parse(v))
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
@ -442,20 +442,7 @@ func AddSlashes(str string) string {
|
||||
|
||||
// StripSlashes un-quotes a quoted string by AddSlashes.
|
||||
func StripSlashes(str string) string {
|
||||
var buf bytes.Buffer
|
||||
l, skip := len(str), false
|
||||
for i, char := range str {
|
||||
if skip {
|
||||
skip = false
|
||||
} else if char == '\\' {
|
||||
if i+1 < l && str[i+1] == '\\' {
|
||||
skip = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
buf.WriteRune(char)
|
||||
}
|
||||
return buf.String()
|
||||
return utils.StripSlashes(str)
|
||||
}
|
||||
|
||||
// QuoteMeta returns a version of str with a backslash character (\)
|
||||
|
Loading…
Reference in New Issue
Block a user