在项目开发中,一个项目几乎都是由多个开发者共同完成的。对于一个大型项目,共同开发者的数量可能达到十几个、几十个、甚至更多。这么多开发者,每天都在提交代码,每天都在重复执行:静态代检查、代码编译、镜像构建、单元测试、Protobuf文件编译等操作。如果没有一个统一、高效的项目管理,你很可能会面临以下 2 个核心难题:
- 执行结果不一致带来一些潜在的问题和沟通成本:不同开发者,相同的操作每个人执行的命令和结果都是不一样的。不一致的结果,可能会程序运行结果不一致,并带来一些沟通成本;
- 执行效率低下:一些操作需要执行复杂的命令,如果手动操作,效率低下,而且容易犯错;
- 不知道如何操作:一个项目,尤其是大型项目,通常包含各种操作项,其中不乏一些复杂的操作项(操作流程多、单项操作命令复杂等),如果不能有效规整这些操作项,对于一个新开发者,甚至经常操作的开发者,经常会出现不知道如何操作,要翻阅操作笔记的难境,这会拖累你的开发效率和开发体验。
那么,如何解决以上问题呢?答案是我们要选择一个合适的源码管理方式。在项目开发中,我们通常可以选择以下 3 种源码管理方式:
- 手动管理:没啥可说的,就是手撸命令,来执行各类操作,例如:
# 运行 air 工具,热加载源码,编译并运行。有没有感觉命令敲的手累?
air -build.cmd=make build BINS=onex-onex-usercenter -build.bin=_output/platforms/linux/amd64/onex-onex-usercenter- Shell 脚本管理:编写 Shell 脚本来完成源码管理任务。例如,项目开发中,根目录下的 build.sh脚本。或者你自己封装的其他 Shell 脚本:
# 添加 golangci-lint bash 自动补全脚本
./scripts/add-completion.sh golangci-lint bash - Makefile 管理:使用 Makefile 脚本来管理你的源码。例如:
make build不同的源码管理方式,使用的场景、优缺点都是不一样的。这里整理如下:
通过上面的对比,你应该不难知道最佳的项目管理方式其实是:Makefile 管理。OneX 项目有 12w 行代码、近 29 个服务,但整个项目操作、管理非常便捷高效,其中核心原因便是采用了 Makefile 的管理方式。以下是 OneX 项目的 Makefile 功能列表:
$ make help
Usage:
make <TARGETS> <OPTIONS>
Targets:
Generate
gen Generate CI-related files. Generate all files by specifying `A=1`.
gen-k8s Generate all necessary kubernetes related files, such as deepcopy files
protoc Generate api proto files.
ca Generate CA files for all onex components.
Build
build Build source code for host platform.
build.multiarch Build source code for multiple platforms. See option PLATFORMS.
image Build docker images for host arch.
image.multiarch Build docker images for multiple platforms. See option PLATFORMS.
push Build docker images for host arch and push images to registry.
push.multiarch Build docker images for multiple platforms and push images to registry.
Deploy
deploy Build docker images for host arch, and deploy it in kind cluster.
docker-install Deploy onex with docker.
docker-uninstall Deploy onex with docker.
sbs-install Deploy onex step by step.
sbs-uninstall Deploy onex step by step.
Clean
clean Remove all artifacts that are created by building and generaters.
Test
test Run unit test.
cover Run unit test and get test coverage.
Lint and Verify
lint Run CI-related linters. Run all linters by specifying `A=1`.
apidiff Run the go-apidiff to verify any API differences compared with origin/master.
Hack and Tools
format Run CI-related formaters. Run all formaters by specifying `A=1`.
format.protobuf Lint protobuf files.
add-copyright Ensures source code files have copyright license headers.
swagger Generate and aggregate swagger document.
serve-swagger Serve swagger spec and docs at 65534.
install-tools Install CI-related tools. Install all tools by specifying `A=1`.
release Publish a release on the release branch.
targets Show all Sub-makefile targets.
help Display this help info.
Options:
DBG Whether to generate debug symbols. Default is 0.
BINS The binaries to build. Default is all of cmd.
This option is available when using: make build/build.multiarch
Example: make build BINS="onex-apiserver onex-miner-controller"
IMAGES Backend images to make. Default is all of cmd starting with onex-.
This option is available when using: make image/image.multiarch/push/push.multiarch
Example: make image.multiarch IMAGES="onex-apiserver onex-miner-controller"
DEPLOYS Deploy all configured services.
REGISTRY_PREFIX Docker registry prefix. Default is superproj.
Example: make push REGISTRY_PREFIX=ccr.ccs.tencentyun.com/superproj VERSION=v0.1.0
PLATFORMS The multiple platforms to build. Default is linux_amd64 and linux_arm64.
This option is available when using: make build.multiarch/image.multiarch/push.multiarch
Example: make image.multiarch IMAGES="onex-apiserver onex-miner-controller" PLATFORMS="linux_amd64 linux_arm64"
PLATFORMS The multiple platforms to build. Default is linux_amd64 and linux_arm64.
This option is available when using: make build.multiarch/image.multiarch/push.multiarch
MULTISTAGE Set to 1 to build docker images using multi-stage builds. Default is 0.
VERSION The version information compiled into binaries.
The default is obtained from gsemver or git.
ALL When Set to 1, it signifies performing a thorough operation.
Such as clean all generated files, install all supported tools, generate all files, and so on.
V Set to 1 enable verbose build. Default is 0.可以看到,OneX 的 Makefile 结构化的内置了丰富的管理项。这些管理项目,都可以通过 Makefile 规则便捷的执行。而且所有开发者执行的都是同一个 Makefile 规则,运行结果也是一致的。通过 Makefile 来管理你的项目,可以大大的提高开发的效率、降低开发难度。