Earthly项目中的函数(Functions)功能详解
什么是Earthly函数
Earthly函数(Functions)是一种可重用的构建指令集合,它允许开发者将常用的构建步骤封装起来,在多个目标(Targets)或其他函数中调用。这种机制类似于传统编程语言中的函数概念,能够显著提高构建脚本的模块化和可维护性。
在Earthly 0.7版本之前,这一功能被称为UDCs(User Defined Commands),现已统一更名为Functions。
函数的核心特性
Earthly函数具有几个关键特性:
- 环境继承:函数会继承调用者的构建上下文和构建环境
- 上下文共享:函数中的
COPY
操作会使用调用者Earthfile所在目录作为源目录 - 状态传递:函数可以访问调用者之前步骤创建的文件和依赖项,函数执行产生的文件变更也会传递回调用者
函数定义与使用
基本语法
函数定义与常规目标类似,但有两点区别:
- 函数名必须使用全大写的蛇形命名法(ALL_UPPERCASE_SNAKE_CASE)
- 函数体必须以
FUNCTION
关键字开头
MY_COPY_FUNCTION:
FUNCTION
ARG src
ARG dest=./
ARG recursive=false
RUN cp $(if $recursive = "true"; then printf -- -r; fi) "$src" "$dest"
函数调用
在目标中使用DO
指令调用函数:
build:
FROM alpine:3.18
WORKDIR /function-example
RUN echo "hello" >./foo
DO +MY_COPY_FUNCTION --src=./foo --dest=./bar
RUN cat ./bar # 输出"hello"
参数传递
函数创建自己的ARG
作用域,与调用者隔离。需要显式传递参数:
build:
ARG var=value-in-build
# 输出"something-else"(使用函数默认值)
DO +PRINT_VAR
# 输出"value-in-build"(传递调用者参数)
DO +PRINT_VAR --var=$var
PRINT_VAR:
FUNCTION
ARG var=something-else
RUN echo "$var"
作用域规则
- 全局参数继承:函数会继承所在Earthfile中
base
目标定义的全局导入和全局参数 - 环境隔离:函数参数作用域与调用者隔离,必须显式传递
VERSION 0.8
ARG --global a_global_var=value-in-global
build:
# 输出"value-in-global"
DO +PRINT_GLOBAL_VAR
PRINT_GLOBAL_VAR:
FUNCTION
RUN echo "$a_global_var"
函数与目标的对比
| 特性 | 目标(Targets) | 函数(Functions) | |------|--------------|----------------| | 表示一组Earthly命令 | ✅ | ✅ | | 可引用其他目标 | ✅ | ✅ | | 可引用其他函数 | ✅ | ✅ | | 构建上下文 | Earthfile所在目录 | 继承自调用者 | | 未指定FROM
时的构建环境 | 继承自自身Earthfile的base目标 | 继承自调用者 | | IMPORT
语句 | 继承自自身Earthfile的base目标 | 继承自自身Earthfile的base目标 | | ARG
作用域 | 创建独立作用域 | 创建独立作用域 | | 需要显式传递ARG
| ✅ | ✅ | | 全局ARG
上下文 | 继承自自身Earthfile的base目标 | 继承自自身Earthfile的base目标 | | 可输出制品 | ✅ | ❌(可通过SAVE ARTIFACT
但由调用者实际输出) | | 可输出镜像 | ✅ | ❌(可通过SAVE IMAGE
但由调用者实际输出) | | 可通过CLI调用 | ✅ | ❌ | | 可与IMPORT
结合使用 | ✅(如FROM some-import+my-target
) | ✅(如DO some-import+MY_FUNCTION
) | | 可引用它的命令 | FROM
, BUILD
, COPY
等 | DO
|
最佳实践
- 命名规范:使用全大写的蛇形命名法,使函数与目标在视觉上容易区分
- 功能单一:每个函数应该只完成一个明确的、小的功能单元
- 参数设计:合理设计参数,使函数具有足够的灵活性
- 文档注释:为函数添加清晰的注释,说明其用途和参数含义
- 避免副作用:函数应尽量减少对调用者环境的意外修改
实际应用场景
- 文件操作封装:如示例中的文件复制功能
- 通用构建步骤:如设置环境变量、安装依赖等重复操作
- 复杂逻辑封装:将条件判断、循环等复杂逻辑封装成函数
- 跨项目复用:通过
IMPORT
机制在不同项目间共享常用函数
Earthly函数为构建流程提供了强大的抽象能力,使构建脚本更加模块化、可维护。合理使用函数可以显著减少重复代码,提高构建脚本的质量和开发效率。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考