voidint / gbb Goto Github PK
View Code? Open in Web Editor NEWGo project compilation assistant written in golang.
License: Apache License 2.0
Go project compilation assistant written in golang.
License: Apache License 2.0
gbb在运行过程中会改变工作目录chdir
,那么在程序运行完毕后,需要将工作目录重置为初始的工作目录。
比如,键盘输入的go build
无法被正确读取到,暂时只能使用下划线_
代替空格。
假设当前为Linux amd64
平台,GOPATH
下github.com/voidint/gbb/cmd/test
目录下仅包含一个名为main_windows.go
的源代码文件,使用gbb编译整个项目,会发生报错: build constraints exclude all Go files in xxxxxx
。
当前,在gbb.json
中配置了go build/install
作为编译工具,那么将会编译项目根目录下所有go package
,应该允许用户指定是否仅编译main package
。
$ gbb --debug --config ../mygbb.json
{
"version": "0.0.1",
"tool": "go install",
"package": "main",
"variables": [
{
"variable": "Date",
"value": "{{.date}}"
},
{
"variable": "Commit",
"value": "{{.gitCommit}}"
}
]
}
如上,{{.date}}
、{{.gitCommit}}
都是内建表达式,这些表达式的逻辑是内建的,或者说逻辑都是硬编码的。应该支持通过执行命令来获得结果,比如👇
{
"variable": "Commit",
"value": "${git rev-parse HEAD}"
}
通过执行${}
内的命令来获得最终的值。
在MacOS下,将gbb.json的内容改成这样:
{
"version": "`.3.0",
"tool": "gb build",
"package": "build",
"variables": [
{
"variable": "Date",
"value": "{{.Date}}"
},
{
"variable": "Commit",
"value": "{{.GitCommit}}"
}
]
}
再执行gbb --debug
,将出现以下内容:
malformed semantic version%
类似这样的错误输出,不明确到底是gbb在调用其他工具时报错,还是gbb本身报错。
$ gbb --debug
exit status 128
当前,version
由gbb init
生成(默认gbb版本号)更加合适。如果哪天需要支持多版本,再打开此项。
刚看到这个工具,之前我也遇到过类似的问题,我在 idcos/cloudcli 中用 makefile 的方式来处理的。
其实就是改下默认的编译命令,编译时动态赋值变量,比如(编译是加入当前的 revision number):
gb build -ldflags "-X main.build=git rev-parse HEAD
"
golang 中 gb 这个工具的目的是管理golang 的工程,还可以安装,卸载,升级第三方包等。
gbb 这个工具的目的是类似的,还是只是为了编译。如果只是编译,其实可以用
alias gbb='gb build -ldflags "-X main.build=git rev-parse HEAD
"' 之类的一行脚本就行。
total 8240
-rw-r--r-- 1 voidint staff 634B 9 11 21:58 Dockerfile
-rw-r--r-- 1 voidint staff 11K 12 17 2016 LICENSE
-rw-r--r-- 1 voidint staff 13K 9 11 21:59 README.md
drwxr-xr-x 4 voidint staff 136B 9 11 21:58 build
drwxr-xr-x 10 voidint staff 340B 9 11 21:58 cmd
drwxr-xr-x 4 voidint staff 136B 9 11 21:58 config
-rwxr-xr-x 1 voidint staff 4.0M 9 19 14:09 gbb
-rw-r--r-- 1 voidint staff 455B 9 11 22:08 gbb.json
-rw-r--r-- 1 voidint staff 181B 12 17 2016 main.go
lrwxr-xr-x 1 voidint staff 24B 9 13 13:35 ngrok -> /Users/voidint/bin/ngrok
drwxr-xr-x 8 voidint staff 272B 9 11 21:58 tool
lrwxr-xr-x 1 voidint staff 18B 9 19 13:59 tty -> /Users/voidint/tty
lrwxr-xr-x 1 voidint staff 19B 9 13 13:52 tty2 -> /Users/voidint/tty2
drwxr-xr-x 10 voidint staff 340B 9 19 13:28 util
drwxr-xr-x 10 voidint staff 340B 9 11 21:58 variable
drwxr-xr-x 4 voidint staff 136B 9 3 2017 vendor
以上面这个工程目录为例,要求做到如下几点:
ngrok
。-a
的命令行选项,则需要对链接的源目录及其子孙目录进行编译。{
"version": "0.2.0",
"tool": "go build",
"package": "github.com/voidint/gbb/build",
"variables": [
{
"variable": "Date",
"value": "{{.date}}"
},
{
"variable": "Commit",
"value": "{{.gitCommit}}"
}
]
}
对于以上{{.date}}
、{{.gitCommit}}
这类表达式的求值过程并没有在debug信息中输出。在没有debug信息情况下,如果在变量表达式求值的过程中发生错误,错误的定位将比较困难。
{
"version": "0.5.0",
"tool": "go install -v -ldflags '-s -w'",
"importpath": "github.com/voidint/gbb/build",
"variables": [
{
"variable": "Author",
"value": "voidint"
}
]
}
对于变量表达式的求值结果,不应该返回invalid express
的错误,而应该原样返回voidint
。
以下描述都有一个这样的前提:gbb.json
中的tool
属性指定的是go_build
或者go_install
。
./github.com/voidint/test
├── gbb.json
└── main.go
对于这样目录形式的项目,那么在项目根目录(test
)下执行gbb
是可以编译成功的。
如果换成👇
./github.com/voidint/test
├── cmd
│ ├── cmd1
│ │ └── main.go
│ ├── cmd2
│ │ └── main.go
│ └── cmd3
│ └── main.go
└── gbb.json
这样的目录结构,在根目录(test
)下执行gbb
是没法直接编译的。今后将设法支持这种目录结构的编译,达到与gb
相同的体验。
在ignore目录列表中的目录将被跳过,不会被编译。
比如,go build -gcflags='-N -l'
,支持gbb --raw "-gcflags='-N -l'"
形式传入参数。
package
-->importpath
Copyright (c) 2016, 2018, voidint. All rights reserved.
{
"version": "0.5.0",
"tool": "go build -ldflags='-s -w' -gcflags='-N -l'",
"importpath": "github.com/voidint/gbb/build",
"variables": [
{
"variable": "Branch",
"value": "$(git branch | grep '*' | awk {'print $2'})"
}
]
}
对于git branch | grep '*' | awk {'print $2'}
这种由多个命令组合而成的复杂命令表达式,显然无法直接使用exec.Command()来获得最终结果。而通过shell来执行此类复杂命令,却可以极大简化整个表达式求值过程。
{{.date}}
-->{{.Date}}
{{.gitCommit}}
-->{{.GitCommit}}
build
子命令,将现有的gbb编译功能代码转移到build
子命令下。gbb
)情况下,则等价于调用gbb build
。保持用户使用习惯不变。{
"version": "0.4.0",
"tool": "go build -gcflags='-N -l'",
"importpath": "github.com/voidint/gbb/build",
"variables": [
{
"variable": "Date",
"value": "{{.Date}}"
},
{
"variable": "Commit",
"value": "{{.GitCommit}}"
}
]
}
若使用以上的配置文件,那么无法进行正常的编译。
strings.Fields("go build -gcflags='-N -l'")
将拆分成go
、build
、-gcflags='-N
、-l'
,与预期不符。
函数tool.buildDir
的实现中,需要在os.Chdir()
函数之后增加defer
操作,用于切换回原始目录。
增加原始的Unix风格的命令行选项-D
和-c
,分别用于开启调试模式
以及指定配置文件路径
。
{
"version": "0.0.1",
"tool": "gb build",
"package": "build",
"variables": [
{
"variable": "Date",
"value": "{{.date}}"
},
{
"variable": "Commit",
"value": "{{.gitCommit}}"
}
]
}
以上gbb.json
中的package
和variables
作为可选配置项,若没有这两项内容,那么gbb就是一个单纯的辅助编译工具。
gbb具有一键编译项目目录下所有入口程序的能力,如果手工执行go build/install
去编译issue#4中所提到的这类项目,那会有多么繁琐。
假设待编译的项目结构类似这样
./go
└── cmd
├── cmd1
│ └── main.go
├── cmd2
│ └── main.go
└── cmd3
└── main.go
并且在gbb.json
中指定的tool
是go build
,那么编译后必然在每个cmd子目录下留下一个可执行文件。原生的go clean
命令仅支持清除当前目录下的编译产物,gbb clean
将遍历所有的子命令目录并清除编译产物。
gbb clean
命令将支持go clean
命令的所有命令行选项:
The -i flag causes clean to remove the corresponding installed
archive or binary (what 'go install' would create).The -n flag causes clean to print the remove commands it would execute,
but not run them.The -r flag causes clean to be applied recursively to all the
dependencies of the packages named by the import paths.The -x flag causes clean to print remove commands as it executes them.
go build -ldflags '-w' -ldflags '-X "github.com/voidint/gbb/build.Date=2017-04-25T16:37:18+08:00" -X "github.com/voidint/gbb/build.Commit=9b1921adb355700fd522c1c24a1f1e2a9279e3f5"'
转化为
go build -ldflags '-X "github.com/voidint/gbb/build.Date=2017-04-25T16:37:18+08:00" -X "github.com/voidint/gbb/build.Commit=9b1921adb355700fd522c1c24a1f1e2a9279e3f5" -w'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.