Makefile 看这一篇就够

Makefile 看这一篇就够

makefile 是一个文本文件,以下是一个子命令,包含:

  • 名称:支持英文、数字、连字符"-"和下划线 " _"
  • 注释:使用 "#" 表示注释,不支持 /*...*/。推荐写在名称的上一行
  • 命令:任何可在 shell 执行的命令行语句。必须是\t 开头,否则报错 make: Nothing to be done for 'build'.
  • .PHONY:可选,命令声明了 .PHONY,执行时将不会输出具体命令到终端。在一些 CI 工具中可以起到过滤敏感信息的作用。
.PHONY: build
# 编译构建
build:
	go build ./...

变量定义和使用

  • 可直接赋值,也可以执行 shell 赋值。
  • 使用变量的方法是 $(VARIABLE_NAME)。
ENV_GROUP = dev
# 获取最新tag
GIT_TAG=$(shell git tag|grep "v*.[0-9]$$"|sort -r --version-sort|head -n1)
APP_GIT_COMMIT_ID=$(shell git rev-parse --short=8 HEAD)

# 使用变量$(VARIABLE_NAME)
GIT_TAG_COMMIT = $(GIT_TAG)-$(APP_GIT_COMMIT_ID)

多文件

  • 使用 include 引入子文件
include ./scripts/develop.mk
include ./scripts/deploy-local.mk
  • 判断文件存在则引入
#文件存在, 则引入
ifneq ($(wildcard ../scripts/Makefile),)
    include ../scripts/Makefile
endif

if-else判断

可以使用 ifeq ifneq

ifeq ($(NAMESPACE), test-1)
    ENV_GROUP = test-a
else ifeq ($(NAMESPACE), test-2)
    ENV_GROUP = test-a
endif

可以使用在命令中

.PHONY: api
# 由 proto 生成接口层代码
api:
ifneq ($(PROTOC_GEN_GO_VERSION), v1.28.1)
	go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1
else
	echo "ok"
endif

相同变量名,为不同命令导入不同值

使用 export 关键词,为命令传值,可多次传值。


IMAGE_NAME=dockerimg
IMAGE_TAG=dev-1


.PHONY: deploy-test1
# 构建、推送测试环境 1
deploy-test1: export IMAGE_NAME = dockerimg-test
deploy-test1: export IMAGE_TAG = test-1
deploy-test1:
	docker build ./ -f ./Dockerfile -t $(IMAGE_NAME):$(IMAGE_TAG)
	make push

.PHONY: deploy-test2
# 构建、推送测试环境 1
deploy-test2: export IMAGE_NAME = dockerimg-test
deploy-test2: export IMAGE_TAG = test-2
deploy-test2:
	docker build ./ -f ./Dockerfile -t $(IMAGE_NAME):$(IMAGE_TAG)
	make push

从命令行传递变量

上述例子中,定义的变量可以放在shell命令行中,输入完 make 和命令后,追加上变量可以起到传递命令的作用。

IMAGE_NAME=dockerimg
IMAGE_TAG=dev-1

.PHONY: deploy-test
# 构建测试环境,使用方式make deploy-test IMAGE_NAME=img-test-1 IMAGE_TAG=test-1
deploy-test:
	docker build ./ -f ./Dockerfile -t $(IMAGE_NAME):$(IMAGE_TAG)

比如 make deploy-test IMAGE_NAME=img-test-1 IMAGE_TAG=test-1

打印输出所有命令

默认情况下,输入make 执行的是第一个命令,可以通过修改.DEFAULT_GOAL 修改动作。以下是一个 help 命令,输出所有带注释的 make 子命令。

# show help
help:
	@echo ''
	@echo 'Usage:'
	@echo ' make [target]'
	@echo ''
	@echo 'Targets:'
	@awk '/^[a-zA-Z\-\_0-9]+:/ { \
	helpMessage = match(lastLine, /^# (.*)/); \
	    if (helpMessage) { \
	        helpCommand = substr($$1, 0, index($$1, ":")-1); \
	        helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
	        printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
	    } \
	} \
	{ lastLine = $$0 }' $(MAKEFILE_LIST)
# 默认 help
.DEFAULT_GOAL := help

输出如下:

$make               

Usage:
 make [target]

Targets:
init                   初始化项目工具和环境
config                 生成配置文件和枚举
api                    由 proto 生成接口层代码
generate               generate
gen                    generate 缩写
fmt                    fmt 格式化代码
lint                   lint 代码检查
build                  build 编译
all                    重新生产代码并编译
run                    run 本地编译 运行
sonar                  sonar
clean                  clean
help                   show help

Read more

golang proto api 校验国际化 protovalidate

golang proto api 校验国际化 protovalidate

众所周知,protobuf 原型文件扩展很多功能,比如生成 http 接口层代码,顺势就有了生成接口参数校验代码的需求。 早期可以使用https://github.com/bufbuild/protoc-gen-validate 来实现,通过生成特定的 go 代码的方式来实现校验。 github 中也提到目前趋于稳定,不会有更多新特性的支持,推荐大家使用新的版本 protovalidate,https://github.com/bufbuild/protovalidate 。该版本是protoc-gen-validate 的“精神继承者”。它不需要任何代码生成并支持自定义约束。 现在我们尝试新版本,并且增加国际化支持。 go get github.com/bufbuild/protovalidate-go import "github.com/bufbuild/protovalidate-go" syntax = "proto3"; package

By brian
git clone 复制一个整个仓库并推送到新地址

git clone 复制一个整个仓库并推送到新地址

要使用 git clone --bare 复制一个新的仓库并推送到远程仓库,可以按照以下步骤操作: 1. 克隆一个裸仓库 首先,使用 git clone --bare 命令克隆源仓库。假设源仓库的 URL 是 https://github.com/user/source-repo.git,你可以执行以下命令: bash复制 git clone --bare https://github.com/user/source-repo.git 这将创建一个新的裸仓库(没有工作区),通常会创建一个名为 source-repo.git 的目录。 2. 进入裸仓库目录 进入刚刚克隆的裸仓库目录: bash复制 cd source-repo.git 3. 添加新的远程仓库 接下来,

By brian
搜索引擎技巧不用多,学会 3 个加速 100% 找到目标

搜索引擎技巧不用多,学会 3 个加速 100% 找到目标

在搜索时使用英文关键词,提高结果质量。尽量使用 google.com 以下搜索引擎技巧在 google.com 进行测试,效果都很好,前三个非常常用且强烈推荐。 使用精确搜索 * 建议: 使用双引号 "" 搜索完全匹配的短语,避免无关结果。 * 示例: * "Java NullPointerException" fix * 场景: 找到错误信息的精确解决方案。 利用站内搜索 * 建议: 使用 site: 限制搜索范围到特定网站。 * 示例: * site:stackoverflow.com "TypeError: undefined is not a function" * 场景: 搜索 Stack Overflow、官方文档或技术博客的特定内容。 一些关键词 * 建议:

By brian
沪ICP备2022013452号-1