前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记一次对Makefile的重构

记一次对Makefile的重构

作者头像
LA0WAN9
发布2021-12-14 09:07:32
3910
发布2021-12-14 09:07:32
举报
文章被收录于专栏:火丁笔记

如果你不了解 Makefile 的话,那么推荐看看阮一峰的文章「Make 命令教程」。本文通过一个重构的例子带你写出味道更好的 Makefile,让我们开始吧!

假设有一个名为 foo 的项目,用 golang 开发,在 docker 上部署,其 Makefile 如下:

代码语言:javascript
复制
APP = $(shell basename ${CURDIR})
TAG = $(shell git log --pretty=format:"%cd.%h" --date=short -1)

.PHONY: build
build:
	go build -ldflags "-X 'main.version=${TAG}'" -o ./tmp/${APP} .

.PHONY: docker-config
docker-config: env
	TAG=${TAG} docker-compose config

.PHONY: docker-build
docker-build: env
	TAG=${TAG} docker-compose build

.PHONY: docker-push
docker-push: env
	TAG=${TAG} docker-compose push

.PHONY: docker-up
docker-up: env
	TAG=${TAG} docker-compose up

.PHONY: docker-down
docker-down:
	TAG=${TAG} docker-compose down

看上去很简洁,唯一需要说明的是在操作 docker-compose 的时候,传递了一个名为 TAG 的环境变量,表示项目当前所属的标签,看一下对应的 docker-compose.yml 文件:

代码语言:javascript
复制
version: "3.0"
services:
  server:
    image: docker.domain.com/foo:${TAG}
    build:
      context: .
      dockerfile: build/docker/Dockerfile
    ports:
      - "9090:9090"
      - "6060:6060"

此时出现了一个有待改进的地方:ports 信息重复,看一下对应的 config.toml 文件:

代码语言:javascript
复制
[rpc]
port = 9090

[debug]
port = 6060

其中,rpc 端口 9090,debug 端口 6060 最初是在 config.toml 文件里配置的,但是在 docker-compose.yml 文件又重复了一次,假设要修改的话,就需要修改多个地方。

此时我们很容易想到的解决方案是把端口信息也通过环境变量传递,就像 TAG 变量那样,确定了解决方案,让我们再看一下对应的 docker-compose.yml 文件:

代码语言:javascript
复制
version: "3.0"
services:
  server:
    image: docker.domain.com/${APP}:${TAG}
    build:
      context: .
      dockerfile: build/docker/Dockerfile
    ports:
      - "${RPC_PORT}:${RPC_PORT}"
      - "${DEBUG_PORT}:${DEBUG_PORT}"

让我们再看看对应的 Makefile 文件,其中用 dasel 来解析配置文件:

代码语言:javascript
复制
APP = $(shell basename ${CURDIR})
TAG = $(shell git log --pretty=format:"%cd.%h" --date=short -1)
RPC_PORT   = $(shell dasel -f configs/production.toml rpc.port)
DEBUG_PORT = $(shell dasel -f configs/production.toml debug.port)

.PHONY: build
build:
	go build -ldflags "-X 'main.version=${TAG}'" -o ./tmp/${APP} .

.PHONY: docker-config
docker-config: env
	APP=${APP} TAG=${TAG} RPC_PORT=${RPC_PORT} DEBUG_PORT=${DEBUG_PORT} docker-compose config

.PHONY: docker-build
docker-build: env
	APP=${APP} TAG=${TAG} RPC_PORT=${RPC_PORT} DEBUG_PORT=${DEBUG_PORT} docker-compose build

.PHONY: docker-push
docker-push: env
	APP=${APP} TAG=${TAG} RPC_PORT=${RPC_PORT} DEBUG_PORT=${DEBUG_PORT} docker-compose push

.PHONY: docker-up
docker-up: env
	APP=${APP} TAG=${TAG} RPC_PORT=${RPC_PORT} DEBUG_PORT=${DEBUG_PORT} docker-compose up

.PHONY: docker-down
docker-down:
	APP=${APP} TAG=${TAG} RPC_PORT=${RPC_PORT} DEBUG_PORT=${DEBUG_PORT} docker-compose down

不得不说,长长的环境变量实在是太丑了,好在 docker-compose 支持 .env 文件,于是我们可以把环境变量写入 .env 文件,然后让 docker-compose 命令从其中取数据:

代码语言:javascript
复制
APP = $(shell basename ${CURDIR})
TAG = $(shell git log --pretty=format:"%cd.%h" --date=short -1)
RPC_PORT   = $(shell dasel -f configs/production.toml rpc.port)
DEBUG_PORT = $(shell dasel -f configs/production.toml debug.port)

.PHONY: env
env: build
	echo "APP=${APP}" > .env; \
		echo "TAG=${TAG}" >> .env; \
		echo "RPC_PORT=${RPC_PORT}" >> .env; \
		echo "DEBUG_PORT=${DEBUG_PORT}" >> .env

.PHONY: build
build:
	go build -ldflags "-X 'main.version=${TAG}'" -o ./tmp/${APP} .

.PHONY: docker-config
docker-config: env
	docker-compose config

.PHONY: docker-build
docker-build: env
	docker-compose build

.PHONY: docker-push
docker-push: env
	docker-compose push

.PHONY: docker-up
docker-up: env
	docker-compose up

.PHONY: docker-down
docker-down: env
	docker-compose down

在 Makefile 里,我们定义了一个 env 操作,并把它作为所有 docker-compose 操作的前置操作来执行,终于不用再写长长的环境变量了,不过记得把 .env 写到 .gitignore 里!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档