# build-logic-maven-plugin
**Repository Path**: lmaos/build-logic-maven-plugin
## Basic Information
- **Project Name**: build-logic-maven-plugin
- **Description**: build-logic-maven-plugin
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-04-15
- **Last Updated**: 2026-04-15
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 逻辑插件
通过一套简洁统一的 XML DSL 语法,即可在 Maven 构建生命周期中完成:文件操作、目录管理、字符串处理、压缩、条件判断、循环、函数、HTTP 调用等一系列自动化逻辑,无需编写 Java 代码、无需依赖外部脚本。
***设计理念***
本插件基于极简、统一、无歧义的三大核心规则设计:
name:定义变量
用于声明一个变量(普通值、文件、字符串、集合、日期等)。
ref:引用变量
引用一个已经通过 name 定义的变量。
file:引用文件变量
专用于引用 定义的文件对象。
比如构建项目发布压缩包示范:
```xml
"${SCRIPT_DIR}/${APP_NAME}.log" 2>&1 &
]]>
${response}
上传成功
上传失败
app.zip 压缩失败
```
## 插件介绍
可以使用基本的逻辑表达式,来判断是否执行某个操作。所有逻辑需要写在 < main > main > 标签中。
常见属性:
- name: 定义变量名, 用于在后续逻辑中引用。
- test: 用于判断是否可以执行某个操作。test 接受简单判断逻辑表达式或布尔值。
- value: 用于设置变量的值。value 与 标签内容 不能同时使用,属于同值。
- ref: 用于引用其他变量的值。
- to: 用于将变量的值赋值给其他变量。
- format: 用于格式化变量的值。
- encoding: 编码格式。
- overwrite: 是否覆盖目标文件。
## 示范
```xml
${a}
```
## Maven 插件使用方法
## 中央仓库依赖
已发布到 Maven Central,可直接引用:
```xml
com.clmcat.maven.plugins
build-logic-maven-plugin
1.0.0
```
```xml
com.clmcat.maven.plugins
build-logic-maven-plugin
1.0.0
build-script
package
run
```
## 快速上手
最小可运行示例:
```xml
${message}
```
常用写法:
- `` / `` / ``:定义变量
- ``:输出日志
- `` / ``:读写文件
- `` / `` / `` / ``:条件、循环和函数
- ``、`` 这类带点号的标签表示同一个 action 的不同方法变体
使用时记住两点:
- 所有可执行逻辑都放进 ``
- 写文件默认受 `allowWriteDir` 限制,通常是 `${project.basedir}`
## 开发与测试
```bash
mvn test
```
如果只想跑新增的 action 层单元测试,可以执行:
```bash
mvn -Dtest=ActionXUtilsTest,DefaultActionFactoryTest,VariableActionTest,FunctionVariablesReferenceTest test
mvn -Dtest=RunBuildLogicMojoUsageTest test
mvn -Dtest=RunBuildLogicMojoBoundaryTest test
mvn -Dtest=RunBuildLogicMojoRegressionTest test
mvn -Dtest=RunBuildLogicMojoTest#testHttpMojoExecute test
```
`src/test/java/com/clmcat/maven/plugins/action` 下的单元测试主要覆盖:
- 基础工具方法与字符串处理
- factory 的标签绑定与属性校验
- 变量类型推断和作用域栈
插件层测试统一放在 `com.clmcat.plugins.test`,当前按三层组织:
- **使用方式测试**:验证 README 中常见 DSL 组合是否可直接执行
- **边界测试**:验证配置错误、空值、越界文件写入、未知集合等失败路径
- **最终回归测试**:验证方法调用解析、HTTP 响应变量、函数/作用域组合等历史易错点
## 执行模型与扩展方式
运行入口是 `com.clmcat.maven.plugins.RunBuildLogicMojo`,它会把 `` 作为 DSL 根节点,并注册当前支持的顶级标签。执行模型可以理解成:
1. XML 标签先映射成 `Action`
2. `Action` 在当前变量作用域内执行
3. 代码块或函数会压入新的作用域
4. 子标签由当前 `Action` 自己决定如何解析和执行
需要扩展 DSL 时,优先沿用现有两种模式:
- **点号标签扩展**:``、``、``、``,点号后半段会作为 `tagMethod`
- **结构化子标签扩展**:``、``、``、``
函数和代码块的变量作用域遵循当前实现:
- `` 是根作用域
- `` 定义函数,`` 在调用时创建新的函数作用域
- ``、``、`` 这类代码块会创建自己的局部作用域
- `return.xxx` 会写回调用方作用域
## 约束与错误处理
- 所有可执行逻辑都必须放在 `` 中;函数只能定义在根级或 `` 下
- 未注册的标签、未知属性、类型不匹配的属性值现在都会直接失败,而不是静默忽略
- `` 在没有 `ref` 时必须提供值;变量名只允许字母、数字、下划线和 `$`
- `foreach` 只支持 `Collection`、`Map`、数组、`File`(文件或目录)和 `0..9` 这种区间表达式
- 写文件、建目录、删除、生成 zip 都受 `allowWriteDir` 限制;默认安全目录是 `${project.basedir}`
- `${...}` 不只是字符串替换,还支持 Java 方法调用,例如 `${str.substring(int 0, int 5)}`
## 扩展 ${} 表达式
变量:逻辑创建的变量。
类型:Java数据类型,基本和部分数据类型支持简写。
方法:Java对象的方法。
值和引用变量名: 部分值可以直接传入,特殊对象值需要使用引用。
```xml
${变量名.方法(类型 值或变量名)}
```
例如:
```xml
hello world
${str}
${str.length()}
${str.toUpperCase()}
${str.substring(int 0, int 5)}
```
## 标签说明
### 通用属性 < XxxTag test="true/false" >
属性test: 所有标签都可以使用, 来判断是否可以执行某个操作。test 接受简单判断逻辑表达式或布尔值。
```xml
```
...
### < main >
主逻辑标签,所有逻辑都需要卸载这个标签中。
```xml
```
### < var >
用于定义一个变量。 所有变量的名字只可以包含字母、数字和下划线。
```xml
a=${a}
```
引用一个变量
```xml
b=${b}
```
### < mkdir />
创建目录
```xml
```
### < file />
文件变量定义
```xml
testFile=${testFile}
```
项目下面的文件
```xml
文件存在
文件不存在
```
属性test: 所有标签都可以使用, 来判断是否可以执行某个操作。test 接受简单判断逻辑表达式或布尔值。
#### < read />
读取文件内容,到某个变量里
```xml
testTxtFileRead=${testTxtFileRead}
```
#### < write />
写入文件, 默认存在则不覆盖, 直接写入值
```xml
在 内容中,可以包含任何字符。
]]>
```
追加写入文件, 直接追加写入值。
```xml
```
使用引用写入文件内容
1. 使用文件变量引用, 复制文件内容, 到目标文件。
```xml
```
2. 使用变量引用, 复制变量值, 到目标文件。
```xml
```
3. 使用 < read /> 标签, 复制文件内容, 到目标文件。
```xml
```
#### < delete >
删除文件或目录, 默认:只能删除 项目目录下的文件或目录, 不能删除其他目录下的文件或目录。
```xml
```
强制删除, 不限制。
force="true" 表示强制删除, 任意位置都可以删除, 慎重使用。
```xml
```
手动指定安全目录:
```xml
```
### < list >
集合变量定义
```xml
- 1
- 2
- 3
${item}
```
集合追加数据
```xml
- 4
- 5
${item}
```
集合存储文件数据
```xml
${item}
```
### < foreach >
便利集合或便利文件列表
1. 便利集合
```xml
- 4
- 5
${item}
```
2. 便利文件列表
```xml
file: ${item}
```
3. 循环次数
最终输出 0 ~ 9 共10个数
```xml
${item}
```
### < zip >
压缩文件或目录
1. 目录下面全部压缩到 zip 文件
```xml
```
2. 正则匹配文件
简单匹配: pattern="*.txt"
```xml
```
### < if >
条件判断
```xml
a is 10
a is 20
a is not 10 or 20
```
### < func > or < call >
函数与调用
1. 定义函数与调用
```xml
a=${a}
```
2.传递参数
```xml
a=${a}
```
###
创建日期时间变量
```xml
```
### < str >
字符串操作
属性说明:
| 属性 | 说明 | 是否必须 |
|-------------|-------------------------|------|
| name | 新变量或引用变量名 | 必填 |
| to | 新数据赋值的变量名,如果未填写则直接覆盖原变量 | 非必填 |
| params | 参数, 有写方法需要参数, 逗号分割 | 非必填 |
|
```
1. 截取字符串
params="start, end"
start: 截取开始位置, end: 截取结束位置, 包含 end 位置的字符。
name: 截取指定变量的字符串, 重新赋值给 name 变量。
```xml
```
2. 截取Value中的字符串并赋值给 name 变量。
```xml
```
3. 设置字符串
params="value"
name: 设置指定变量的字符串值。
```xml
hello world
```
4. < str.len >计算字符串长度, 并赋值给新的变量
计算传入字符串长度, 并赋值给新的变量 strLen
```xml
```
计算字符串变量长度, 赋值给新的变量 strLen
```xml
hello world
strLen=${strLen}
```
5. < str.split > 分割字符串得到字符串List
分割 value中的 字符串并设置到 list 中
```xml
${list}
```
分割某变量的字符串并赋值
```xml
hello,world
${list}
```
6. < str.ramdom > 字符串随机
| params参数 | 说明 | 是否必须 |
|----------|---------------| --- |
| params0 | min 字符串长度 | 必填写 |
| params1 | max 字符串长度 | 可选
| params2 | 使用随机的数据的分割方式。 | 可选 |
```xml
```
通过value的index随机,得到10个长度的随机字符串
```xml
```
通过value的index随机,得到10个长度的随机字符串,
超过 最终计算结果的字符串长度,会被切割。
```xml
```
7. 追加字符串
```xml
Hello
${str}
Hello
World
${str0}
Hello
World
${str}
```
---
## HTTP 请求
### < http > 发送HTTP请求
```xml
{"name": "zzxx"}
${response}
${response.code}
${response.message}
${response.headers.getHeader(String "Content-Type")}
```
直接返回响应对象
```xml
httpResult=${httpResult.code()}
httpResult=${httpResult.message()}
httpResult=${httpResult}
httpResult=${httpResult.content()}
```
直接读取文件的内容,二进制流上传数据。 content的包是application/octet-stream,byte[]类型。
```xml
${response}
${response.code}
${response.message}
${response.headers.getHeader("Content-Type")}
```
---
## 编码解码
| params参数 | 说明 | 是否必须 |
|----------|--------------|--------------|
| name | 变量名 | 必填 |
| ref | 引用的变量 | value 不存在时必填 |
| value | 值字符串,与ref互斥 | 非必填 |
| encoding | 编码 默认 UTF-8 | 非必填 |
### < base64.encode > 编码
```xml
${str}
hello world
${strEncode}
${strDecode}
```
### < base64.decode > 解码
```xml
${str}
${strDecode}
```