首页 > 后端开发 > Golang > 一个golang常见库cobra

一个golang常见库cobra

藏色散人
发布: 2021-05-13 11:53:28
转载
2621 人浏览过

下面由golang教程栏目给大家介绍一个golang常见库cobra,希望对需要的朋友有所帮助!

cobra  是 go 语言的一个库,可以用于编写命令行工具。通常我们可以看到git pull  、docker container start  、apt install 等等这样命令,都可以很容易用corba来实现,另外,go 语言是很容易编译成一个二进制文件,本文将实现一个简单的命令行工具。

具体写一个例子, 设计一个命令叫blog, 有四个子命令

1

2

3

4

 blog new [post-name] :创建一篇新的blog

 blog list   :列出当前有哪些文章

 blog delete [post-name]: 删除某一篇文章

 blog edit [post-name]:编辑某一篇文章

登录后复制

计划有以下几个步骤

  • 创建模块
  • 用cobra的命令行,创建命令行入口
  • 用cobra的命令行,创建子命令
  • 编写功能逻辑

创建模块

1

2

$ go mod init github.com/shalk/blog

go: creating new go.mod: module github.com/shalk/blog

登录后复制

创建命令行入口

说到命令行,可能会想到bash的getopt 或者 java 的jcommand,可以解析各种风格的命令行,但是通常这些命令行都有固定的写法,这个写法一般还记不住要找一个模板参考以下。cobra除了可以解析命令行之外,还提供了命令行,可以生成模板。先安装这个命令行, 并且把库的依赖加到go.mod里

1

$ go get -u github.com/spf13/cobra/cobra

登录后复制

cobra会安装到$GOPATHbin 目录下,注意环境变量中把它加入PATH中

1

2

3

$ cobra init --pkg-name github.com/shalk/blog -a shalk -l mit

Your Cobra applicaton is ready at

D:\code\github.com\shalk\blog

登录后复制

目录结构如下:

1

2

3

4

5

6

./cmd

./cmd/root.go

./go.mod

./go.sum

./LICENSE

./main.go

登录后复制

编译一下

1

go build  -o blog .

登录后复制

执行一下

1

2

3

4

5

6

7

$blog -h

A longer description that spans multiple lines and likely contains

examples and usage of using your application. For example:

 

Cobra is a CLI library for Go that empowers applications.

This application is a tool to generate the needed files

to quickly create a Cobra application.

登录后复制

命令行就创建好了,看上去一行代码也不用写,由于随着了解的深入,后面需要调整生成的代码,还是要了解一下cobra代码的套路。

cobra代码的套路

有三个概念,command、flag和args  ,例如:

1

go get -u test.com/a/b

登录后复制

这里 get 就是commond(这里比较特殊), -u 就是flag, test.com/a/b 就是args

那么命令行就是有三部分构成,所以需要定义好这个

  • 命令自身的一些基本信息,用command表示,具体对象是 cobra.Command
  • 命令的一些标致或者选项,用flag表示,具体对象是 flag.FlagSet
  • 最后的参数,用args表示,通常是[]string

还有一个概念是子命令,比如get就是go的子命令,这是一个树状结构的关系。

我可以使用go命令,也可以使用 go get命令

例如:  root.go,定义了root命令,另外在init里面 定义了flag,如果它本身有具体执行,就填充Run字段。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

// rootCmd represents the base command when called without any subcommands

var rootCmd = &cobra.Command{

    Use:   "blog",

    Short: "A brief description of your application",

    Long: `A longer description that spans multiple lines and likely contains

examples and usage of using your application. For example:

 

Cobra is a CLI library for Go that empowers applications.

This application is a tool to generate the needed files

to quickly create a Cobra application.`,

    // Uncomment the following line if your bare application

    // has an action associated with it:

    //  Run: func(cmd *cobra.Command, args []string) { },

}

 

// Execute adds all child commands to the root command and sets flags appropriately.

// This is called by main.main(). It only needs to happen once to the rootCmd.

func Execute() {

    if err := rootCmd.Execute(); err != nil {

        fmt.Println(err)

        os.Exit(1)

    }

}

 

func init() {

    cobra.OnInitialize(initConfig)

 

    // Here you will define your flags and configuration settings.

    // Cobra supports persistent flags, which, if defined here,

    // will be global for your application.

 

    rootCmd.PersistentFlags().StringVar(&cfgFile, "config""""config file (default is $HOME/.blog.yaml)")

 

    // Cobra also supports local flags, which will only run

    // when this action is called directly.

    rootCmd.Flags().BoolP("toggle""t", false, "Help message for toggle")

 

}

登录后复制

如果需要子命令,就需要在init 里,给 rootCmd.AddCommand() 其他的command,其他的子命令通常也会单独用一个文件编写,并且有一个全局变量,让rootCmd可以add它

创建子命令

1

2

3

4

5

6

7

8

9

10

11

D:\code\github.com\shalk\blog>cobra add  new

new created at D:\code\github.com\shalk\blog

 

D:\code\github.com\shalk\blog>cobra add  delete

delete created at D:\code\github.com\shalk\blog

 

D:\code\github.com\shalk\blog>cobra add  list

list created at D:\code\github.com\shalk\blog

 

D:\code\github.com\shalk\blog>cobra add  edit

edit created at D:\code\github.com\shalk\blog

登录后复制

cmd 目录下增加了 new.go, delete.go,list.go,edit.go

增加功能代码

new.go

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

var newCmd = &cobra.Command{

    Use:   "new",

    Short: "create new post",

    Long:  `create new post `,

    Args: func(cmd *cobra.Command, args []string) error {

        if len(args) != 1 {

            return errors.New("requires a color argument")

        }

        return nil

    },

    Run: func(cmd *cobra.Command, args []string) {

        fileName := "posts/" + args[0]

        err := os.Mkdir("posts", 644)

        if err != nil {

            log.Fatal(err)

        }

        _, err = os.Stat( fileName)

        if os.IsNotExist(err) {

            file, err := os.Create(fileName)

            if err != nil {

                log.Fatal(err)

            }

            log.Printf("create file %s", fileName)

            defer file.Close()

        else {

        }

    },

}

登录后复制

list.go

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

var listCmd = &cobra.Command{

    Use:   "list",

    Short: "list all blog in posts",

    Long: `list all blog in posts `,

    Run: func(cmd *cobra.Command, args []string) {

        _, err := os.Stat("posts")

        if os.IsNotExist(err) {

            log.Fatal("posts dir is not exits")

        }

        dirs, err := ioutil.ReadDir("posts")

        if err != nil {

            log.Fatal("read posts dir fail")

        }

        fmt.Println("------------------")

        for _, dir := range dirs {

            fmt.Printf(" %s\n", dir.Name() )

        }

        fmt.Println("------------------")

        fmt.Printf("total: %d blog\n", len(dirs))

 

    },

}

登录后复制

delete.go

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

var deleteCmd = &cobra.Command{

    Use:   "delete",

    Short: "delete a post",

    Long: `delete a post`,

    Args: func(cmd *cobra.Command, args []string) error {

        if len(args) != 1 {

            return errors.New("requires a color argument")

        }

        if strings.Contains(args[0],"/") || strings.Contains(args[0],"..") {

            return errors.New("posts name should not contain / or .. ")

        }

        return nil

    },

    Run: func(cmd *cobra.Command, args []string) {

        fileName := "./posts/" +  args[0]

        stat, err := os.Stat(fileName)

        if os.IsNotExist(err) {

            log.Fatalf("post %s is not exist", fileName)

        }

        if stat.IsDir() {

            log.Fatalf("%s is dir ,can not be deleted", fileName)

        }

        err = os.Remove(fileName)

        if err != nil {

            log.Fatalf("delete %s fail, err %v", fileName, err)

        else {

            log.Printf("delete post %s success", fileName)

        }

    },

}

登录后复制

edit.go 这个有一点麻烦,因为如果调用一个程序比如vim 打开文件,并且golang程序本身要退出,需要detach。暂时放一下(TODO)

编译测试

我是window测试,linux 更简单一点

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

PS D:\code\github.com\shalk\blog> go build -o blog.exe .

PS D:\code\github.com\shalk\blog> .\blog.exe list

------------------

------------------

total: 0 blog

PS D:\code\github.com\shalk\blog> .\blog.exe new blog1.md

2020/07/26 22:37:15 create file posts/blog1.md

PS D:\code\github.com\shalk\blog> .\blog.exe new blog2.md

2020/07/26 22:37:18 create file posts/blog2.md

PS D:\code\github.com\shalk\blog> .\blog.exe new blog3.md

2020/07/26 22:37:20 create file posts/blog3.md

PS D:\code\github.com\shalk\blog> .\blog list

------------------

 blog1.md

 blog2.md

 blog3.md

------------------

total: 3 blog

PS D:\code\github.com\shalk\blog> .\blog delete blog1.md

2020/07/26 22:37:37 delete post ./posts/blog1.md success

PS D:\code\github.com\shalk\blog> .\blog list

------------------

 blog2.md

 blog3.md

------------------

total: 2 blog

PS D:\code\github.com\shalk\blog> ls .\posts\

 

 

    目录: D:\code\github.com\shalk\blog\posts

 

 

Mode                LastWriteTime         Length Name

----                -------------         ------ ----

-a----        2020/7/26     22:37              0 blog2.md

-a----        2020/7/26     22:37              0 blog3.md

 

 

PS D:\code\github.com\shalk\blog>

登录后复制

小结

cobra 是一个高效的命令行解析库,利用cobra的脚手架,可以快速的实现一个命令行工具。如果需要更细致的控制,可以参考cobra的官方文档。

以上是一个golang常见库cobra的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
来源:cnblogs.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板