github.com/gogf/gf/v2@v2.7.4/os/gcmd/gcmd_z_unit_test.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  // go test *.go -bench=".*" -benchmem
     8  
     9  package gcmd_test
    10  
    11  import (
    12  	"context"
    13  	"fmt"
    14  	"os"
    15  	"strings"
    16  	"testing"
    17  
    18  	"github.com/gogf/gf/v2/errors/gcode"
    19  	"github.com/gogf/gf/v2/errors/gerror"
    20  	"github.com/gogf/gf/v2/frame/g"
    21  	"github.com/gogf/gf/v2/os/gcmd"
    22  	"github.com/gogf/gf/v2/os/gctx"
    23  	"github.com/gogf/gf/v2/os/genv"
    24  	"github.com/gogf/gf/v2/test/gtest"
    25  )
    26  
    27  func Test_Default(t *testing.T) {
    28  	gtest.C(t, func(t *gtest.T) {
    29  		gcmd.Init([]string{"gf", "--force", "remove", "-fq", "-p=www", "path", "-n", "root"}...)
    30  		t.Assert(len(gcmd.GetArgAll()), 2)
    31  		t.Assert(gcmd.GetArg(1), "path")
    32  		t.Assert(gcmd.GetArg(100, "test"), "test")
    33  		t.Assert(gcmd.GetOpt("force"), "remove")
    34  		t.Assert(gcmd.GetOpt("n"), "root")
    35  		t.Assert(gcmd.GetOpt("fq").IsNil(), false)
    36  		t.Assert(gcmd.GetOpt("p").IsNil(), false)
    37  		t.Assert(gcmd.GetOpt("none").IsNil(), true)
    38  		t.Assert(gcmd.GetOpt("none", "value"), "value")
    39  	})
    40  	gtest.C(t, func(t *gtest.T) {
    41  		gcmd.Init([]string{"gf", "gen", "-h"}...)
    42  		t.Assert(len(gcmd.GetArgAll()), 2)
    43  		t.Assert(gcmd.GetOpt("h"), "")
    44  		t.Assert(gcmd.GetOpt("h").IsNil(), false)
    45  	})
    46  }
    47  
    48  func Test_BuildOptions(t *testing.T) {
    49  	gtest.C(t, func(t *gtest.T) {
    50  		s := gcmd.BuildOptions(g.MapStrStr{
    51  			"n": "john",
    52  		})
    53  		t.Assert(s, "-n=john")
    54  	})
    55  
    56  	gtest.C(t, func(t *gtest.T) {
    57  		s := gcmd.BuildOptions(g.MapStrStr{
    58  			"n": "john",
    59  		}, "-test")
    60  		t.Assert(s, "-testn=john")
    61  	})
    62  
    63  	gtest.C(t, func(t *gtest.T) {
    64  		s := gcmd.BuildOptions(g.MapStrStr{
    65  			"n1": "john",
    66  			"n2": "huang",
    67  		})
    68  		t.Assert(strings.Contains(s, "-n1=john"), true)
    69  		t.Assert(strings.Contains(s, "-n2=huang"), true)
    70  	})
    71  }
    72  
    73  func Test_GetWithEnv(t *testing.T) {
    74  	gtest.C(t, func(t *gtest.T) {
    75  		genv.Set("TEST", "1")
    76  		defer genv.Remove("TEST")
    77  		t.Assert(gcmd.GetOptWithEnv("test"), 1)
    78  	})
    79  	gtest.C(t, func(t *gtest.T) {
    80  		genv.Set("TEST", "1")
    81  		defer genv.Remove("TEST")
    82  		gcmd.Init("-test", "2")
    83  		t.Assert(gcmd.GetOptWithEnv("test"), 2)
    84  	})
    85  }
    86  
    87  func Test_Command(t *testing.T) {
    88  	gtest.C(t, func(t *gtest.T) {
    89  		var (
    90  			ctx = gctx.New()
    91  			err error
    92  		)
    93  		commandRoot := &gcmd.Command{
    94  			Name: "gf",
    95  		}
    96  		// env
    97  		commandEnv := &gcmd.Command{
    98  			Name: "env",
    99  			Func: func(ctx context.Context, parser *gcmd.Parser) error {
   100  				fmt.Println("env")
   101  				return nil
   102  			},
   103  		}
   104  		// test
   105  		commandTest := &gcmd.Command{
   106  			Name:        "test",
   107  			Brief:       "test brief",
   108  			Description: "test description current Golang environment variables",
   109  			Examples: `
   110  gf get github.com/gogf/gf
   111  gf get github.com/gogf/gf@latest
   112  gf get github.com/gogf/gf@master
   113  gf get golang.org/x/sys
   114  `,
   115  			Arguments: []gcmd.Argument{
   116  				{
   117  					Name:   "my-option",
   118  					Short:  "o",
   119  					Brief:  "It's my custom option",
   120  					Orphan: true,
   121  				},
   122  				{
   123  					Name:   "another",
   124  					Short:  "a",
   125  					Brief:  "It's my another custom option",
   126  					Orphan: true,
   127  				},
   128  			},
   129  			Func: func(ctx context.Context, parser *gcmd.Parser) error {
   130  				fmt.Println("test")
   131  				return nil
   132  			},
   133  		}
   134  		err = commandRoot.AddCommand(
   135  			commandEnv,
   136  		)
   137  		if err != nil {
   138  			g.Log().Fatal(ctx, err)
   139  		}
   140  		err = commandRoot.AddObject(
   141  			commandTest,
   142  		)
   143  		if err != nil {
   144  			g.Log().Fatal(ctx, err)
   145  		}
   146  
   147  		if err = commandRoot.RunWithError(ctx); err != nil {
   148  			if gerror.Code(err) == gcode.CodeNotFound {
   149  				commandRoot.Print()
   150  			}
   151  		}
   152  	})
   153  }
   154  
   155  func Test_Command_Print(t *testing.T) {
   156  	gtest.C(t, func(t *gtest.T) {
   157  		var (
   158  			ctx = gctx.New()
   159  			err error
   160  		)
   161  		c := &gcmd.Command{
   162  			Name:        "gf",
   163  			Description: `GoFrame Command Line Interface, which is your helpmate for building GoFrame application with convenience.`,
   164  			Additional: `
   165  Use 'gf help COMMAND' or 'gf COMMAND -h' for detail about a command, which has '...' in the tail of their comments.`,
   166  		}
   167  		// env
   168  		commandEnv := &gcmd.Command{
   169  			Name:        "env",
   170  			Brief:       "show current Golang environment variables, long brief.long brief.long brief.long brief.long brief.long brief.long brief.long brief.",
   171  			Description: "show current Golang environment variables",
   172  			Func: func(ctx context.Context, parser *gcmd.Parser) error {
   173  				return nil
   174  			},
   175  		}
   176  		if err = c.AddCommand(commandEnv); err != nil {
   177  			g.Log().Fatal(ctx, err)
   178  		}
   179  		// get
   180  		commandGet := &gcmd.Command{
   181  			Name:        "get",
   182  			Brief:       "install or update GF to system in default...",
   183  			Description: "show current Golang environment variables",
   184  
   185  			Examples: `
   186  gf get github.com/gogf/gf
   187  gf get github.com/gogf/gf@latest
   188  gf get github.com/gogf/gf@master
   189  gf get golang.org/x/sys
   190  `,
   191  			Func: func(ctx context.Context, parser *gcmd.Parser) error {
   192  				return nil
   193  			},
   194  		}
   195  		if err = c.AddCommand(commandGet); err != nil {
   196  			g.Log().Fatal(ctx, err)
   197  		}
   198  		// build
   199  		//-n, --name       output binary name
   200  		//-v, --version    output binary version
   201  		//-a, --arch       output binary architecture, multiple arch separated with ','
   202  		//-s, --system     output binary system, multiple os separated with ','
   203  		//-o, --output     output binary path, used when building single binary file
   204  		//-p, --path       output binary directory path, default is './bin'
   205  		//-e, --extra      extra custom "go build" options
   206  		//-m, --mod        like "-mod" option of "go build", use "-m none" to disable go module
   207  		//-c, --cgo        enable or disable cgo feature, it's disabled in default
   208  
   209  		commandBuild := gcmd.Command{
   210  			Name:  "build",
   211  			Usage: "gf build FILE [OPTION]",
   212  			Brief: "cross-building go project for lots of platforms...",
   213  			Description: `
   214  The "build" command is most commonly used command, which is designed as a powerful wrapper for
   215  "go build" command for convenience cross-compiling usage.
   216  It provides much more features for building binary:
   217  1. Cross-Compiling for many platforms and architectures.
   218  2. Configuration file support for compiling.
   219  3. Build-In Variables.
   220  `,
   221  			Examples: `
   222  gf build main.go
   223  gf build main.go --swagger
   224  gf build main.go --pack public,template
   225  gf build main.go --cgo
   226  gf build main.go -m none 
   227  gf build main.go -n my-app -a all -s all
   228  gf build main.go -n my-app -a amd64,386 -s linux -p .
   229  gf build main.go -n my-app -v 1.0 -a amd64,386 -s linux,windows,darwin -p ./docker/bin
   230  `,
   231  			Func: func(ctx context.Context, parser *gcmd.Parser) error {
   232  				return nil
   233  			},
   234  		}
   235  		if err = c.AddCommand(&commandBuild); err != nil {
   236  			g.Log().Fatal(ctx, err)
   237  		}
   238  		_ = c.RunWithError(ctx)
   239  	})
   240  }
   241  
   242  func Test_Command_NotFound(t *testing.T) {
   243  	gtest.C(t, func(t *gtest.T) {
   244  		c0 := &gcmd.Command{
   245  			Name: "c0",
   246  		}
   247  		c1 := &gcmd.Command{
   248  			Name: "c1",
   249  			FuncWithValue: func(ctx context.Context, parser *gcmd.Parser) (interface{}, error) {
   250  				return nil, nil
   251  			},
   252  		}
   253  		c21 := &gcmd.Command{
   254  			Name: "c21",
   255  			FuncWithValue: func(ctx context.Context, parser *gcmd.Parser) (interface{}, error) {
   256  				return nil, nil
   257  			},
   258  		}
   259  		c22 := &gcmd.Command{
   260  			Name: "c22",
   261  			FuncWithValue: func(ctx context.Context, parser *gcmd.Parser) (interface{}, error) {
   262  				return nil, nil
   263  			},
   264  		}
   265  		t.AssertNil(c0.AddCommand(c1))
   266  		t.AssertNil(c1.AddCommand(c21, c22))
   267  
   268  		os.Args = []string{"c0", "c1", "c23", `--test="abc"`}
   269  		err := c0.RunWithError(gctx.New())
   270  		t.Assert(err.Error(), `command "c1 c23" not found for command "c0", command line: c0 c1 c23 --test="abc"`)
   271  	})
   272  }