乐趣区

关于golang:bgo-具备扩展性的-go-程序构建工具

bgo v0.3.0+

前言

咱们曾经在 bgo: 让构建 go 程序更容易 中介绍了 bgo 的根本能力。

通过几天的迭代,初步感觉到比较稳定了,因而发了 0.3.0 版本,作为是春节前的划断。

新版本有了

节后嘛,得益于 cmdr 原有的 Aliases 性能的降级(元旦时遇到很多意外,都是忙乱惹的祸),bgo 向着 不仅只是个 main 包批量构建器 迈出了一小步:

咱们通过 Aliases 的形式提供了预建的 check-code-quanlities 性能。

这是 v0.3.1+ 之后提供的新性能。

check-code-qualities 性能

这个性能是须要第三方工具的。以后须要 golint 和 gocyclo 在场,此外也须要 gofmt 工具。前两者须要提前装置:

go install golang.org/x/lint/golint
go install github.com/fzipp/gocyclo

当上述工具无效时,bgo 能够代为行使上述工具提供的质量检查性能:

bgo check-code-quanlities
bgo chk
# Or
bgo chk ./...

这个命令顺次执行 gofmt, golint 以及 gocyclo 工具,对你的以后文件夹以及上级进行代码品质检测。

你能够附带参数如 ./... 或者其它指定的文件夹偏移。

Homebrew

brew 版本预建了装置脚本,你须要更新 hedzr/brew Tap 而后 reinstall bgo。

因为 brew 通过 update 命令来更新它本人以及所有的 taps,因而其效率可能太低下。我感觉,一个变通的办法是:

brew untap hedzr/brew
brew tap hedzr/brew

brew 当初会装置预置配置文件到 /usr/local/etc/bgo/。

后文咱们会介绍其它环境应该怎么办。

注释

下面提到的性能,是依赖于 cmdr 的 Aliases 能力。因而咱们对此有必要进行解释。

bgo 新版本的装置

首先来讲,当初 bgo 的 release 下载包中携带了一个 etc/bgo 子目录,你须要将其挪动为 $HOME/.bgo 目录:

wget https://github.com/hedzr/bgo/releases/download/v0.3.3/bgo-darwin-amd64.tgz
tar -xf bgo-darwin-amd64.tgz
mv bin/bgo /usr/local/bin/bgo
mv etc/bgo ~/.bgo

# 如果应用 zsh 环境,从新生成主动实现脚本
bgo gen sh --zsh

当初在 $HOME/.bgo 目录蕴含了预建 aliases 命令的定义。

具体来讲,它($HOME/.bgo/conf.d/80.aliases.yml)是这样的:

app:

  aliases:
    # group:                                  # group-name (optional). such as: "别名".
    commands:
      # - title: list
      #   short-name: ls
      #   # aliases: []
      #   # name: ""
      #   invoke-sh: ls -la -G                # for macOS, -G = --color; for linux: -G = --no-group
      #   # invoke: "another cmdr command"
      #   # invoke-proc: "..." # same with invoke-sh
      #   desc: list the current directory

      - title: check-code-qualities
        short-name: chk
        # aliases: [check]
        # name: ""# group:""
        # hidden: false
        invoke-sh: |
          echo "Command hit: {{.Cmd.GetDottedNamePath}}"
          echo "fmt {{.ArgsString}}"
          gofmt -l -s -w {{range .Args}}{{.}}{{end}}
          echo "lint {{.ArgsString}}"
          golint {{.ArgsString}}
          echo "cyclo ."
          gocyclo -top 20 .
        # invoke: "another cmdr command"
        # invoke-proc: "..." # same with invoke-sh
        shell: /usr/bin/env bash  # optional, default is /bin/bash
        desc: pre-options before releasing. typically fmt,lint,cyclo,...

想必我无需额定解释了。

正式发版时这个文件具备更多命令别名定义

这里提供了一套裁减机制(通过 shell 脚本片段),你能够持续裁减你本人的特定命令,透过 bgo 的命令零碎来进一步简化构建前后的各种工作。

在下面的 yaml 代码中,解除 title: list 所在的 map 的正文即可使能一条 list 命令,这是 ls 的同义词。它当然没有实际意义,其目标在于向你解释怎么增加本人的另一条命令(或者另 n 条)。

建设多级子命令零碎

在 cmdr 的 examples/fluent) 的附带的配置文件 91.cmd-aliases.yml 中,为你展现了如何通过 Aliases 能力构建本人的子命令零碎:

app:

  aliases:
    group:                                  # group-name (optional). such as: "别名".
    commands:
      - title: list
        short-name: ls
        # aliases: []
        # name: ""
        invoke-sh: ls -la -G                # for macOS, -G = --color; for linux: -G = --no-group
        # invoke: "another cmdr command"
        # invoke-proc: "..." # same with invoke-sh
        desc: list the current directory
      - title: pwd
        invoke-sh: pwd
        desc: print the current directory
      - title: services
        desc: "the service commands and options"
        subcmds:
          - title: ls
            invoke: /server/list            # invoke a command from the command tree in this app
            invoke-proc:                    # invoke the external commands (via: executable)
            invoke-sh:                      # invoke the external commands (via: shell)
            shell: /bin/bash                # or /usr/bin/env bash|zsh|...
            desc: list the services
          - title: start
            flags: []
            desc: start a service
          - title: stop
            flags: []
            desc: stop a service
          - title: git-version
            invoke-proc: git describe --tags --abbrev=0
            desc: print the git version
            group: Proc
          - title: git-revision
            invoke-proc: git rev-parse --short HEAD
            desc: print the git revision
            group: Proc
          - title: kx1
            invoke: /kb
            desc: invoke /kb command
            group: Internal
          - title: kx2
            invoke: ../.././//kb --size 32mb   # allow related path to seek a cmdr-command, and the ugly path is allowed (multiple slashes, ...)
            desc: invoke /kb command
            group: Internal
          - title: kx3
            invoke: /kb --size 2kb
            desc: invoke /kb command
            group: Internal
        flags:
          - title: name
            default: noname
            type: string          # bool, string, duration, int, uint, ...
            group:
            toggle-group:
            desc: specify the name of a service

不仅如此,甚至于你还能为子命令提供专属的 flag 选项。

应用标记(Flag)选项

因为 invoke, invoke-proc, invoke-sh 字段都反对模板开展,所以你能够通过模板语法提取到某个 flag 的理论值,理论值是指用户在命令行输出的,又或是该 flag 的默认值。

一个示例的 aliases 定义能够是这样:

      - title: echo
        invoke-sh: |
          # pwd
          echo "{{$flg := index .Cmd.Flags 0}}{{$dpath :=$flg.GetDottedNamePath}} {{$fullpath := .Store.Wrap $dpath}} {{$fullpath}} | {{.Store.GetString $fullpath}}"
        desc: print the name
        flags:
          - title: name
            default:              # default value
            type: string          # bool, string, duration, int, uint, ...
            group:
            toggle-group:
            desc: specify the name to be printed

该模板字符串序列简直等价于 Golang 代码:

flg := obj.Cmd.Flags[0]
dpath := flg.GetDottedNamePath()
fullpath := obj.Store.Wrap(dpath)
stringVal := obj.Store.GetString(dpath) // 从 cmdr Option Store 中抽出该选项的理论值,以字符串的模式

模板从上下文变量环境 obj 中失去命中的子命令 echo,即 obj.Cmd;相似的,obj.Store 取得 cmdr Option Store 的实例,而后是一系列 cmdr 接口调用,从而取得 cmdr 解决命令行参数后设置到 Option Store 中的 --name 的理论值。

其运行的成果相似于:

$ bgo echo --name watching
  app.echo.name | watching

其中,echo 子命令的残缺的门路为 app.echoapp 是隐含的前缀,cmdr 应用这样的隐含的前缀来构筑一个名字空间,而 Store.Wrap() 正是为了给个别门路附上这样的前缀。

更新你的主动实现脚本

在裁减了你的 aliases 之后,你须要更新主动实现脚本来反馈变动。是的,Aliases 们是齐全融入 bgo 命令零碎中的,因而从新生成一次主动实现脚本,即可将 aliases 们纳入到主动实现的提醒列表中。

一个示意图如上。

大节

有了下面介绍的这些信息,你将能够在不用批改 bgo 源代码的状况下,自行裁减 bgo 了。

你能够尝试:

  • 增加 cov(coverage)命令,简短快捷地做笼罩测试
  • bench
  • 减少前置脚本以便做资源文件打包
  • 等等

在新版本中,散发包中曾经蕴含了 coverage 命令定义,无妨比照一下。

或者间接浏览 repo 中的配置文件定义 ci/etc/bgo/conf.d/80.aliases.yml

bgo 心愿做的是将一直反复的简短的命令行缩短到一个或者两个子命令的水平,让每次工作在 6-8 击键之内。这比你充分利用 zsh 的主动实现以及高低翻页等性能还要有用得多。

具备 Aliases 交融能力后,当初说一句 bgo: 富于扩展性的 go 程序构建工具 大概勉强也能算作是货真价实了。

其实,咱们尚未介绍由 cmdr 反对的 Extensions 个性,它容许你在特定的文件夹中寄存一系列的文件夹和脚本文件,并将其融入既有的命令零碎中,如同下面 Aliases 个性借助于 YAML 配置文件所做的那样。

Cmdr 所提供的 Extensions,Aliases,以及 Addons 等内部扩大能力,一个次要的激发就来自于 git aliases,以及还在互联网之前的一些 DOS 应用程序的特色。

亲自复现出本人记忆中的那样的成果,必定是对一个 developer 的最好的奖赏,养在深闺也无所谓了,我曾经失去了我要的贬责。

题外话

我始终想要复刻一份 LIST 进去。只是始终没有精力入手。

LIST.COM 是已故的 Vernon D. Buerg 所开发的 DOS shareware。这个工具是我做反向 TWAY 的时候的无力工具之一,恩,它倒不是亲自做反向的,只是一个文件列表器而已。

对于 bgo 的配置文件

反对多种格局

同样是源自 cmdr 提供的反对,bgo 可能自动识别 json,toml 和 yml(或 yaml)后缀。

也就是说,在 一个工作目录中,存在 .bgo.yml 或者 .bgo.toml 都是能够的。只管咱们的示例中总是应用 yaml 向你解说如何编写,但将其扭转为不同的文件格式可能一样地失效。而 bgo 或者说 cmdr 则会主动加载它们。

配置文件夹

你曾经留神到,咱们在 $HOME/.bgo 下提供了 bgo.yml,并且其中的子目录 conf.d 中提供了 80.aliases.yml。

依照 cmdr 的约定,一个配置文件目录中肯定要有同名(即 bgo)的配置文件,至于后缀应该是 .json.toml.yml.yaml 中的一个。cmdr 的配置文件被分为三种类型:primary,secondary 以及 alternative。

对于 bgo 来说,$HOME/.bgo 是 primary 配置文件组的一个可能的地位,bgo 和 cmdr 会主动搜查若干预约义的地位(包含 /usr/local/etc/bgo 以及 $HOME/.bgo)来试图加载 primary 配置文件,而后将其 conf.d 作为监督文件夹,并加载其中的任何 .json.toml.yml.yaml。

所以,混用不同的配置文件格式也无所谓。

conf.d 主动配置文件夹

在主配置文件的目录里,conf.d 子目录是被监督的,这外面的任何配置文件都可能被主动重载。当然,对于 bgo 来说主动重载毫无意义。

然而你能够在这个文件夹外面增加一系列的配置文件,例如 alias-001.yml, alias-002.yml。这种构造对于 ci 操作或者说 devops 操作会是很不便的,你无需搜索枯肠去编排脚本想一个 yaml 中增加一大段 yaml 片段,还要保障它们的嵌入地位适当,缩进档次适当。间接新增一个 yml 好了。

辅助配置文件

至于当前工作目录下的 .bgo.yml,是作为 Alternative/Secondary 配置文件组的身份被载入的。

依照 cmdr 的约定,如果 .bgo.yml 被作为 Alternative 配置文件加载,则这个配置文件不含有子文件夹监督,并且能够开启主动配置文件回写性能。不过这个性能在 bgo 中并没有关上,因为回写性能会抹去配置文件中的正文局部,这可能往往并不是你所想要的。

之所以身份不定,是因而 cmdr 反对同时从 Primary/Seconary/Alternative 三个地位载入三组配置并合并到一起。只管咱们没有专门阐明,bgo 在这里留有很多裁减的可能性。

bgo init 时改用不同格局

应用上面的语法,能够建设不同的配置文件格式:

bgo init --output=.bgo.yml
bgo init --output=.bgo.yaml
bgo init --output=.bgo.json
bgo init --output=.bgo.toml

输入文件名的后缀名决定了初始化操作将扫描后果存储为那一种配置文件格式。

后记

bgo 目前存在的问题:

  • 没有 Windows 零碎下的无力测试,因而不太确定配置文件的加载地位是否能被无效辨认。
  • 配置文件中的 bash shell 可能会在 windows 中改为 powershell 还是 cmd?我不太晓得,或者须要少许调整能力工作。

    • FEEL FREE TO ISSUE ME

上次说到,这次是忽然动念,间接就做的。而后找空去看了看 goxc,哎唷我去

看了,人家罗唆都停更了。

登时感觉前途喵喵啊。

为什么我感觉 go build 穿插编译并没有那么 simple 呢,或者说麻烦的很吧。唉,不论了,反正 bgo 就是这么个工具了。

REFs

  • 我的项目:https://github.com/hedzr/bgo
  • 依赖:https://github.com/hedzr/cmdr
  • 配置文件示例:https://github.com/hedzr/bgo/blob/master/.bgo.yaml
  • go.dev: 这里
  • Docker Hub:hedzr/bgo – Docker Image – Docker Hub

🔚

退出移动版