Apache Rat 0.18 排除规则与输出格式详解
Apache Rat 0.18 排除规则与输出格式详解:--input-exclude/--input-exclude-file/--input-exclude-std 标准集合、多值参数 -- 分隔陷阱、--output-style 四种报告样式、--output-file、--edit-license 自动补头(--dry-run/--edit-overwrite)、--counter-max 阈值控制,全部实测
Apache Rat 0.18 排除规则与输出格式详解
目标:详解 Apache Rat 0.18 独立 CLI(
java -jar)的三大实战专题——排除规则体系(--input-exclude/--input-exclude-file/--input-exclude-std)、输出控制(--output-file/--output-style四样式)、自动补许可证头(--edit-license系列)与计数阈值(--counter-max),并沉淀多值参数--分隔陷阱、新旧参数对照等实测坑点;全部命令与回显均在 Ubuntu 22.04 + OpenJDK 17(java 17.0.20.1)环境实测通过,实测日期 2026-10-15。
一、环境信息
- 操作系统:Ubuntu 22.04(x86_64)
- JDK:OpenJDK 17.0.20.1(
apt安装openjdk-17-jdk-headless) - Apache Rat:apache-rat-0.18(2026-03-20 发布,Apache Creadur 项目)
- Rat 主程序:
/opt/rat/apache-rat-0.18/apache-rat-0.18.jar(7,479,290 字节;下载与校验方式见系列篇《Apache Rat 0.18 介绍与 CLI 审计实战》第三章,本篇所有命令以/opt为工作目录) - 示例树一:
/opt/demo-src(5 个文件:带 Apache 2.0 头的src/Main.java、src/Utils.java;无头的src/Legacy.java、resources/config.xml;无头的README.txt) - 示例树二:
/opt/demo-src3(含pom.xml、target/classes/Foo.class、.git/config的 Maven/Git 混合树,2.3 节构造) - 排除文件:
/opt/excludes.txt(2.2 节构造)
为方便独立复跑,先给示例树一的完整构造命令(审计判定与下方回显一一对应):
mkdir -p /opt/demo-src/src /opt/demo-src/resources
cat > /opt/demo-src/src/Main.java <<'JAVA'
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
public class Main {
public static void main(String[] args) {
System.out.println("demo");
}
}
JAVA
cat > /opt/demo-src/src/Utils.java <<'JAVA'
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
public class Utils {
}
JAVA
cat > /opt/demo-src/src/Legacy.java <<'JAVA'
// Legacy code without any license header.
public class Legacy {
}
JAVA
cat > /opt/demo-src/resources/config.xml <<'XML'
<?xml version="1.0"?>
<config>
<name>demo</name>
</config>
XML
cat > /opt/demo-src/README.txt <<'TXT'
Demo project for Apache Rat audit walkthrough.
Plain text without any license header.
TXT
验证:
find /opt/demo-src -type f | sort
/opt/demo-src/README.txt
/opt/demo-src/resources/config.xml
/opt/demo-src/src/Legacy.java
/opt/demo-src/src/Main.java
/opt/demo-src/src/Utils.java
💡 说明:本篇全部命令在
/opt工作目录下执行,jar 以相对路径rat/apache-rat-0.18/apache-rat-0.18.jar引用(与实测一致),等价于绝对路径java -jar /opt/rat/apache-rat-0.18/apache-rat-0.18.jar。报告整体结构与计数器含义的逐段解读见系列篇《Apache Rat 0.18 介绍与 CLI 审计实战》第四章;本篇聚焦"怎么排除、怎么控制输出"。
二、排除体系详解
0.18 的 0 配置默认不做任何排除——pom.xml、target/、.git/、隐藏文件全部进入报告(2.3 节实测复现)。排除体系由三个核心参数构成:--input-exclude(逐条模式)、--input-exclude-file(模式文件)、--input-exclude-std(内置标准集合)。本节逐一实测。
2.1 --input-exclude:Ant 模式匹配规则
--help 原文:
--input-exclude <Expression> Excludes files matching <Expression>. Multiple values may be
specified. Note that '--' or a following option is required when
using this parameter.
<Expression> 的官方定义(--help Argument Types 节原文):
<Expression>
A file matching pattern usually of the form used in Ant build files and '.gitignore' files (see
https://ant.apache.org/manual/dirtasks.html#patterns for examples). Regular expression patterns may be
specified by surrounding the pattern with '%regex[' and ']'. For example '%regex[[A-Z].*]' would match files
and directories that start with uppercase latin letters.
即表达式默认按 Ant/gitignore 风格的目录模式解析,也可用 %regex[...] 包裹切换为正则。
💡 技术拓展:RAT 排除表达式存在两种写法体系,对比——
写法 原理/语法要点 适用场景 Ant 模式(默认) *匹配单层、**跨任意层级、?匹配单字符,与 Ant/.gitignore习惯一致排除构建产物、SCM 目录等常规场景 %regex[...]正则以 %regex[开头、]结尾,内部为正则表达式Ant 模式表达不了的结构(如"首字母大写开头") 本文全部采用 Ant 模式:语义直观、与官方标准集合内部模式一致,且已实测验证层级规则。
实测一:单星 *.xml 不命中子目录。
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --input-exclude '*.xml' -- demo-src; echo $?
结果:报告与完全不加排除逐行一致——Standards: 4、! Unapproved: 2,/resources/config.xml 仍为 S 且 unapproved。即 *.xml 只能匹配当前层,匹配不到 resources/ 子目录里的文件;且不匹配的模式不报任何错,只是静默不生效(另一个 CI 静默坑)。
实测二:双星 **/*.xml 命中任意层级。
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --input-exclude '**/*.xml' -- demo-src > /tmp/audit4.out 2>/tmp/audit4.err; echo $?
1
Counters 段完整实测(对比不加排除时的 Approved 2/Standards 4/Unapproved 2/Ignored 0):
Approved: 2 A count of approved licenses.
Archives: 0 A count of archive files.
Binaries: 0 A count of binary files.
Document types: 3 A count of distinct document types.
Ignored: 1 A count of ignored files.
License categories: 2 A count of distinct license categories.
License names: 2 A count of distinct license names.
Notices: 1 A count of notice files.
Standards: 3 A count of standard files.
! Unapproved: 1 A count of unapproved licenses.
Unknown: 1 A count of unknown file types.
Detail 段中 config.xml 的状态变化(实测节选):
/resources/config.xml
I application/xml
结论(全部实测):
- 被排除文件从
S(Standard)变为I(Ignored),Ignored 计数 0→1,且该文件不再做许可证判定; - 排除生效后
! Unapproved从 2 降为 1(只剩src/Legacy.java),但退出码仍为 1——UNAPPROVED 默认范围[0,0],1 个也超限; - 层级写法对照:
*.xml不命中(Standards 仍 4)、**/*.xml命中(Standards 4→3)。跨目录排除必须写**/前缀。
2.2 --input-exclude-file:批量排除文件
模式多了以后写成文件便于版本化管理。--help 原文:Reads <Expression> entries from a file. Entries will be excluded from processing.(一行一条模式)。
构造排除文件(两行,一条跨目录 XML、一条精确文件路径):
cat > /opt/excludes.txt <<'TXT'
**/*.xml
src/Legacy.java
TXT
实测内容:
**/*.xml
src/Legacy.java
执行(-- demo-src 中 Legacy.java 按相对扫描根的路径 src/Legacy.java 匹配):
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --input-exclude-file /opt/excludes.txt -- demo-src > /tmp/audit5.out 2>/tmp/audit5.err; echo $?
0
Counters 段完整实测:
Approved: 2 A count of approved licenses.
Archives: 0 A count of archive files.
Binaries: 0 A count of binary files.
Document types: 3 A count of distinct document types.
Ignored: 2 A count of ignored files.
License categories: 1 A count of distinct license categories.
License names: 1 A count of distinct license names.
Notices: 1 A count of notice files.
Standards: 2 A count of standard files.
Unapproved: 0 A count of unapproved licenses.
Unknown: 0 A count of unknown file types.
Detail 段中两个被排除文件均为 I(实测节选):
/resources/config.xml
I application/xml
/src/Legacy.java
I text/x-java-source
验证:Unapproved 归零、退出码 0("全部批准/排除"场景);报告里也不再出现 Files with unapproved licenses 区段。这份 excludes.txt 同时是第六章"全批准 → exit 0"实测的输入。
2.3 --input-exclude-std:标准排除集合(默认不启用!)
--help 原文:
--input-exclude-std <StandardCollection> Excludes files defined in standard collections based on commonly
occurring groups. Excludes any path matcher actions but DOES NOT
exclude any file processor actions. Multiple values may be
specified. Note that '--' or a following option is required when
using this parameter.
先实测 0 配置默认行为。构造一棵 Maven/Git 混合树:
mkdir -p /opt/demo-src3/src /opt/demo-src3/target/classes /opt/demo-src3/.git
cat > /opt/demo-src3/pom.xml <<'XML'
<?xml version="1.0"?>
<project>
<modelVersion>4.0.0</modelVersion>
</project>
XML
cat > /opt/demo-src3/src/Bar.java <<'JAVA'
public class Bar {
}
JAVA
cat > /opt/demo-src3/target/classes/Foo.class <<'BIN'
placeholder
BIN
cat > /opt/demo-src3/.git/config <<'GIT'
[core]
GIT
裸跑(不带任何排除):
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar -- demo-src3 2>/dev/null | grep -E '^!? /|Standards:|Unapproved:'
关键行实测:
/pom.xml
/src/Bar.java
/target/classes/Foo.class
/.git
I application/octet-stream (directory)
! /pom.xml
S application/xml ISO-8859-2
! /target/classes/Foo.class
S text/plain UTF-8
即 pom.xml、target/、.git/ 全部进报告(Standards: 3)——.git 目录本身被识别为 I application/octet-stream (directory) 忽略类型,但其内容文件(如 pom.xml)仍被逐个审计并判 unapproved。
加标准集合后再跑:
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --input-exclude-std MAVEN --input-exclude-std GIT -- demo-src3 2>/dev/null | grep -E '^!? /|Standards:|Unapproved:'
结果实测:pom.xml 与 target/ 从报告消失、.git/ 变为 I(ignored),报告中仅剩 src/Bar.java 一个标准文件并判 unapproved。
⚠️ 注意:0.18 的 0 配置默认行为 = 不过滤任何文件,标准排除必须手动开启。旧版(如 0.16)默认自带大量排除,按旧教程迁移到 0.18 的脚本会突然"多报"一大堆构建产物与 SCM 文件,这是版本迁移最常见的不适。
<StandardCollection> 全部 25 个取值(--help 原文逐项,模式列为该集合的 File patterns 原文,处理器列对应原文 Provides a file processor: true/false):
| 取值 | 说明(--help 原文意译) | 关键模式(原文节选) | 处理器 |
|---|---|---|---|
| ALL | 全部标准排除合并 | 见下方原文清单 | true |
| GIT | Git 产生的文件与目录,同时处理 .gitignore 与全局 gitignore | **/.git/**, **/.gitignore | true |
| MAVEN | Maven 构建体系产生的文件与目录 | **/MANIFEST.MF, **/target/**, **/.mvn/** 等 8 条 | false |
| GRADLE | Gradle 构建体系产生的文件与目录 | **/.kotlin/**, **/.gradle/**, **/build/** | false |
| CVS | CVS 产生的文件与目录 | **/CVS/**, **/.cvsignore 等 | true |
| SUBVERSION | Subversion 产生的文件与目录 | **/.svn/** | false |
| MERCURIAL | Mercurial 产生的文件与目录 | **/.hg/**, **/.hgignore | true |
| BAZAAR | Bazaar 产生的文件与目录 | **/.bzr/**, **/.bzrignore | true |
| DARCS | DARCS 产生的文件与目录 | **/_darcs/** 等 4 条 | false |
| ARCH | ARCH 源码控制工具产生的文件与目录 | **/.arch-ids/** | false |
| BITKEEPER | Bitkeeper 产生的文件与目录 | **/BitKeeper/**, **/ChangeSet/** | false |
| MKS | MKS 产生的文件与目录 | **/project.pj | false |
| RCS | RCS 产生的文件与目录 | **/RCS/** | false |
| SCCS | SCCS 产生的文件与目录 | **/SCCS/** | false |
| VSS | Visual Source Safe 产生的文件与目录 | **/vssver.scc | false |
| SURROUND_SCM | Surround SCM 产生的文件与目录 | **/.MySCMServerInfo | false |
| SERENA_DIMENSIONS_10 | Serena Dimensions V10 产生的文件与目录 | **/.metadata/** | false |
| ECLIPSE | Eclipse IDE 产生的文件与目录 | **/.project, **/.classpath, **/.settings/** 等 | false |
| IDEA | IDEA IDE 产生的文件与目录 | **/*.iws, **/*.iml, **/*.ipr, **/.idea/** | false |
| MAC | Mac 上的 .DS_Store 文件 | **/.DS_Store | false |
| MISC | 编辑器等遗留的杂项文件 | **/*~, **/%*%, **/.#*, **/._*, **/#*# | false |
| HIDDEN_DIR | 以 . 开头的隐藏目录 | <none>(path matcher 类型) | false |
| HIDDEN_FILE | 以 . 开头的隐藏文件 | <none>(path matcher 类型) | false |
| STANDARD_PATTERNS | 公认应忽略模式的集合 | 60+ 条合并清单 | true |
| STANDARD_SCMS | 各 SCM 排除的标准合并 | 40+ 条合并清单 | true |
MAVEN 与 GIT 集合的完整模式原文(其余集合可用 --help 查看):
<MAVEN>
File patterns: **/MANIFEST.MF, **/pom.xml.releaseBackup, **/build.log, **/target/**, **/.repository, **/.mvn/**,
**/cobertura.ser, **/release.properties
<GIT>
File patterns: **/.git/**, **/.gitignore
💡 说明:
GIT集合原文特别标注会 同时处理.gitignore文件内容(以及全局 gitignore,除非设置环境变量RAT_NO_GIT_GLOBAL_IGNORE)——即项目自己的.gitignore里写的忽略规则会被 RAT 采纳;而MAVEN/GRADLE是纯模式匹配(Provides a file processor: false),不读任何忽略文件。--help里Provides a file processor的含义即"会解析配套 ignore 文件"。
推荐组合:一般项目直接 --input-exclude-std GIT --input-exclude-std MAVEN(或 Gradle 项目换 GRADLE);想一步到位(含 IDE、Mac、编辑器杂项、隐藏文件等 25 类全部)用 --input-exclude-std ALL。ALL 集合的模式清单原文如下(逐字):
<ALL>
File patterns: **/MANIFEST.MF, **/ChangeSet/**, **/TAGS/**, **/pom.xml.releaseBackup, **/*.old, **/*.ipr,
**/.del-*, **/*$, **/.settings/**, **/BitKeeper/**, **/CVS.adm/**, **/*.so, **/*.rej, **/.classpath,
**/.bzr/**, **/*.elc, **/._*, **/*~, **/*.iml, **/build.log, **/.mvn/**, **/.svn/**, **/.hgignore,
**/project.pj, **/build/**, **/-darcs-backup*, **/.metadata/**, **/*.ln, **/.project, **/cvslog.*,
**/.make.state, **/core, **/.factorypath, **/CVS/**, **/.idea/**, **/%*%, **/.git/**, **/_$*, **/.checkstyle,
**/.hg/**, **/*.BAK, **/.bzrignore, **/.arch-ids/**, **/.externalToolBuilders/**, **/release.properties,
**/*.o, **/SCCS/**, **/,*, **/bin/**, **/*.Z, **/.#*, **/vssver.scc, **/#*#, **/*.a, **/*.iws, **/target/**,
**/.kotlin/**, **/RCS/**, **/*.bak, **/.gradle/**, **/*.orig, **/.darcs-temp-mail, **/.nse_depinfo,
**/RCSLOG/**, **/*.exe, **/tags/**, **/.gitignore, **/#*, **/*.obj, **/.MySCMServerInfo, **/.repository,
**/_darcs/**, **/cobertura.ser, **/.darcsrepo/**, **/.DS_Store, **/.cvsignore
选型解读:ALL 覆盖最全但会连带排除 **/build/**、**/bin/** 这类可能与自有源码目录重名的路径,源码树目录结构特殊的项目建议按需组合(GIT+MAVEN/GIT+GRADLE 起步,缺什么补什么),不要无脑 ALL。
2.4 其余输入侧参数速查
以下参数均摘自 --help 原文,默认值如实标注(多值参数同样受第三章 -- 陷阱约束):
| 参数 | 说明(--help 原文要点) | 默认/备注 |
|---|---|---|
--input-include <Expression> | 包含匹配文件,覆盖排除规则 | 多值,须 -- 分隔 |
--input-include-file <File> | 从文件读取包含模式,覆盖排除 | 单文件 |
--input-include-std <StandardCollection> | 按标准集合包含 | 多值,须 -- 分隔 |
--input-exclude-parsed-scm <StandardCollection> | 解析 SCM 排除文件(如 .gitignore)中的条目并排除 | 多值,须 -- 分隔 |
--input-exclude-size <Integer> | 排除小于指定字节数的文件 | 单值整数 |
--input-source <File> | 从文件读取待处理文件名清单(/ 分隔,相对路径基于该文件所在目录) | 多值,须 -- 分隔 |
--config <File> | 系统配置文件(可替代大量命令行参数),多值 | 须 -- 分隔 |
--configuration-no-defaults | 忽略默认配置 | 0.18 新名(旧名 --no-default-licenses 已废弃) |
--log-level <LogLevel> | 日志级别 DEBUG/INFO/WARN/ERROR/OFF | 默认 WARN |
三、多值参数 -- 分隔陷阱(实测)
0.18 有一个影响所有多值参数的语法约定,--help 原文反复强调:
Note that '--' or a following option is required when using this parameter.
即:--input-exclude、--input-exclude-std、--input-include、--config、--counter-max、--counter-min 等多值参数,后面必须用 -- 终止选项区,才能接扫描目标。漏写时目标路径会被当成该参数的下一个值。实测复现:
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --input-exclude '*.xml' demo-src 2>&1 | head -5; echo $?
stderr 实测:
ERROR: No directories or files specified for scanning. Did you forget to close a multi-argument option?
同时 stdout 打印整份 usage。退出码 0——demo-src 被当成了第二个排除表达式,什么都没扫,但 CI 看到的是"成功"。废弃别名 -e '*.xml' demo-src 同样中招。
正确写法(加 --):
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --input-exclude '*.xml' -- demo-src; echo $?
1
退出码 1 = 正常执行审计且发现 1 个 unapproved(2.1 节实测二),命令确实跑了。
⚠️ 注意:这是 CI 静默失败的最高频坑——错误只出现在 stderr 一行
ERROR: No directories or files specified for scanning. Did you forget to close a multi-argument option?,退出码却是 0。接入 CI 时按系列篇第五章的方案对 stderr 措辞做显式检查。
验证方法:任何多值参数后,肉眼确认命令里有 -- 且 -- 之后第一个 token 就是扫描目标。
四、输出控制
0.18 的输出由 --output-file(写到哪)与 --output-style(什么样式)两个参数控制,另有 --output-archive/--output-standard 控制归档与标准文件的报告粒度。
4.1 --output-file:报告写入文件
--help 原文:Define the output file where to write a report to. (Default value = System.out)。
实测(沿用 2.2 节的排除文件):
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --input-exclude-file /opt/excludes.txt --output-file /tmp/report.txt -- demo-src; echo $?
wc -l /tmp/report.txt
0
76
控制台此时只剩 INFO 横幅与计数块(实测节选):
INFO: Apache Creadur RAT 0.18 (Apache Software Foundation)
INFO: RAT summary:
INFO: Approved: 2
INFO: Unapproved: 0
完整 plain 报告写入 /tmp/report.txt(76 行),报告结构与 2.2 节终端输出的默认报告完全一致(Summary/Counters → Licenses detected → License Categories detected → Document Types detected → Detail)。验证:
head -3 /tmp/report.txt
grep -c 'INFO: RAT summary' /tmp/report.txt
*****************************************************
Summary
*****************************************************
0
(报告文件内不含 INFO: RAT summary: 计数块——该块只打在控制台 stdout,用于脚本快速取数;文件内是纯报告。)
4.2 --output-style:四种报告样式实测
--help 原文定义:
<StyleSheet>
Either an external xsl file or one of the internal named sheets. Internal sheets are:
plain-rat: The default style.
missing-headers: Produces a report of files that are missing headers.
unapproved-licenses: Produces a report of the files with unapproved licenses.
xml: Produces output in pretty-printed XML.
四种内置样式逐一实测对比(示例树一,均加 --input-exclude '**/*.xml' -- 以聚焦差异):
| 样式 | 内容形态 | 实测结果 |
|---|---|---|
plain-rat(默认) | 完整六区段报告(Counters/Licenses/Categories/Types/Unapproved 清单/Detail) | 2.1 节实测的默认输出即此样式 |
missing-headers | 仅缺头文件清单 + 计数块 | 见下方回显 |
unapproved-licenses | 仅 unapproved 文件清单 + 计数块 | 见下方回显 |
xml | <rat-report> 机读 XML | 见 4.3 节 |
missing-headers 实测回显:
Files with missing headers:
/resources/config.xml
/src/Legacy.java
unapproved-licenses 实测回显:
Files with unapproved licenses:
/resources/config.xml
/src/Legacy.java
(两者均后跟 INFO: RAT summary: 计数行。)对应命令:
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --output-style missing-headers --input-exclude '**/*.xml' -- demo-src
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --output-style unapproved-licenses --input-exclude '**/*.xml' -- demo-src
选型解读:plain-rat 适合人看全貌;missing-headers/unapproved-licenses 适合报告正文只关心"要补头的文件名单"的场景(两者在本示例树中结果相同,因为未被识别的文件既是 missing 又是 unapproved;当树里存在已被识别但未获批许可证族时两者才有差异);xml 适合程序化消费(4.3 节)。
4.3 xml 样式与 CI 机读
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --output-style xml --input-exclude '**/*.xml' -- demo-src 2>/dev/null | head -6
头部实测(该回显对应会话启用了 **/*.xml 排除,故 config.xml/Legacy.java 的 type 为 IGNORED;不带排除时它们为 STANDARD 并带许可证判定子元素——type 值与排除规则联动,可对照 2.1 节):
<rat-report timestamp="2026-10-14T16:51:23Z">
<version product="Apache Creadur RAT" vendor="Apache Software Foundation" version="0.18"/>
<resource encoding="ISO-8859-1" mediaType="text/plain" name="/README.txt" type="NOTICE"/>
<resource isDirectory="false" mediaType="application/xml" name="/resources/config.xml" type="IGNORED"/>
<resource isDirectory="false" mediaType="text/x-java-source" name="/src/Legacy.java" type="IGNORED"/>
<resource isDirectory="false" mediaType="text/x-java-source" name="/src/Main.java" type="STANDARD">
<license approval="true" family="AL " id="AL2.0" name="Apache License 2.0"/>
</resource>
文档尾部含 <statistics> 块,逐计数器输出 <statistic ... count="N" ... name="Unapproved"/> 形式的条目,便于 CI 工具(XML 解析/断言)机读取数。
废弃写法对照:-x 输出同样的 <rat-report> 并打实测 WARN:
WARN: Option [-x, --xml] used. Deprecated for removal since 0.17: Use --output-style with the 'xml' argument instead.
4.4 --output-archive 与 --output-standard:报告粒度
--help 原文的 <ProcessingType> 定义(两个参数共用):
<ProcessingType>
Specifies how to process file types. Valid values are:
NOTIFICATION: List file as present
PRESENCE: List any licenses found
ABSENCE: List licenses found and any unknown licences
| 参数 | 作用对象 | 默认值(--help 原文) |
|---|---|---|
--output-archive <ProcessingType> | ARCHIVE 类型(jar/war 等)的报告粒度 | NOTIFICATION |
--output-standard <ProcessingType> | STANDARD 类型(普通文本文件)的报告粒度 | ABSENCE |
实测验证(jar 归档升档):对 --output-archive PRESENCE -- demo.jar,jar 内逐条目带许可证判定(Standards: 5、Unapproved: 3、退出码 1;完整报告实测见系列篇第六章)。要点:默认 NOTIFICATION 下归档条目只"列出存在",看不到条目内的许可证判定行——审计含构建产物的归档时记得升档。
五、自动补许可证头(--edit-license 系列)
RAT 不止能"报问题",还能直接给无头文件补 Apache-2.0 许可证头。四个参数协作(--help 原文要点):
--edit-license:给未知许可证且不在排除清单的文件加 Apache-2.0 头;默认生成 .new 新文件,不改动原文件;--edit-overwrite:强制直接覆写源文件(仅与--edit-license连用有效);--edit-copyright <arg>:自定义版权行,如Copyright 2008 Foo(仅与--edit-license连用有效);--dry-run:只生成报告、不落任何修改。
5.1 --dry-run:预览不落盘
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --edit-license --dry-run -- demo-src; echo $?
head -2 demo-src/src/Legacy.java
head -2 实测(原文件未被动过):
// Legacy code without any license header.
public class Legacy {
验证:find /opt/demo-src -name '*.new' | wc -l 输出 0——dry-run 不产生任何文件修改,适合先预览"将会补头哪些文件"(报告的 Files with unapproved licenses 清单即补头目标)。
5.2 默认行为:生成 .new 副本
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --edit-license -- demo-src
find demo-src -type f | sort
实测(新增 2 个 .new 文件,原文件保持不动):
demo-src/README.txt
demo-src/resources/config.xml
demo-src/resources/config.xml.new
demo-src/src/Legacy.java
demo-src/src/Legacy.java.new
demo-src/src/Main.java
demo-src/src/Utils.java
Legacy.java.new 实际头部(实测逐字,标准 21 行 Apache-2.0 头 + 空行 + 原代码首行):
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// Legacy code without any license header.
config.xml.new 对 XML 文件自动改用 <!-- ... --> 注释包裹许可证文本,并保留首行 <?xml version="1.0"?>(实测确认)。
5.3 --edit-overwrite 原地覆写与 --edit-copyright 自定义版权行
先恢复示例树(删掉 .new 副本或按 1. 章命令重建),再执行带自定义版权行的原地覆写:
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --edit-license --edit-overwrite --edit-copyright 'Copyright 2026 DemoCorp' -- demo-src
head -20 demo-src/src/Legacy.java
find demo-src -name '*.new' | wc -l
Legacy.java 覆写后头部实测:
/*
* Copyright 2026 DemoCorp
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
find 计数实测:
0
(无 .new 残留副本。)覆写后再对全树审计一次,实测 Approved: 4、Unapproved: 0——补头闭环验证通过。
⚠️ 注意:
--edit-overwrite直接改写源文件,务必在版本管理(git)干净工作区下执行,确认 diff 无误再提交;首次尝试建议先--dry-run或用默认.new副本模式,人工比对后再覆写。
六、计数阈值与退出码控制
RAT 0.18 的退出码由"计数器范围检查"驱动:任何 CounterPattern 超出允许范围即报 ERROR: Unexpected count for UNAPPROVED, limit is [0,0]. Count: N(N 为实际计数)并附 RatDocumentAnalysisException: Issues with UNAPPROVED,以退出码 1 结束。--counter-max/--counter-min 就是调节这个范围的旋钮。
6.1 CounterPattern 默认范围总表
<CounterPattern> 官方定义(--help 原文逐字,格式为 前缀:数值,如 UNAPPROVED:5):
<CounterPattern>
A pattern comprising one of the following prefixes followed by a colon and a count (e.g. UNAPPROVED:5). Prefixes
are
APPROVED: A count of approved licenses. Default range [0, unlimited]
ARCHIVES: A count of archive files. Default range [0, unlimited]
BINARIES: A count of binary files. Default range [0, unlimited]
DOCUMENT_TYPES: A count of distinct document types. Default range [1, unlimited]
IGNORED: A count of ignored files. Default range [0, unlimited]
LICENSE_CATEGORIES: A count of distinct license categories. Default range [1, unlimited]
LICENSE_NAMES: A count of distinct license names. Default range [1, unlimited]
NOTICES: A count of notice files. Default range [0, unlimited]
STANDARDS: A count of standard files. Default range [1, unlimited]
UNAPPROVED: A count of unapproved licenses. Default range [0, 0]
UNKNOWN: A count of unknown file types. Default range [0, unlimited]
解读:11 个前缀与报告 Counters 段一一对应。唯一"收紧"的是 UNAPPROVED,默认范围 [0,0]——任何未批准文件都超限、任何未批准都让退出码变 1;其余下限为 1 的四项(DOCUMENT_TYPES/LICENSE_CATEGORIES/LICENSE_NAMES/STANDARDS)意味着"扫描结果为空"也会报错(防止误扫空目录静默通过)。-1 表示不设限(原文:A value of '-1' specifies an unlimited number)。
6.2 --counter-max:CI 放行阈值实测
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --counter-max UNAPPROVED:5 -- demo-src; echo $?
0
同一棵树(Unapproved 实测仍为 2,报告照常列出两个 unapproved 文件),把 UNAPPROVED 上限放宽到 5 后退出码从 1 变 0。语义:--counter-max UNAPPROVED:<n> 即"允许最多 n 个未批准文件"的 CI 放行阈值;配套的 --counter-min(原文:The minimum number for the specified counter. Multiple values may be specified.)用于收紧下限(例如要求至少检出若干许可类别,防止排除规则误配导致空扫)。两个参数均为多值,受第三章 -- 陷阱约束。
6.3 退出码决策速查
| 目标 | 配置 | 退出码行为(实测) |
|---|---|---|
| 严格门禁:1 个 unapproved 都不留 | 默认(UNAPPROVED [0,0]) | unapproved≥1 → 1;=0 → 0 |
| 宽限期:允许最多 n 个 | --counter-max UNAPPROVED:n | unapproved>n → 1;≤n → 0 |
| 排除后全批准 | --input-exclude-file <file> -- | 0(2.2 节实测) |
| 空扫防护 | 默认(STANDARDS 等下限 1) | 扫描结果为空 → 1 |
参数拼错/漏 --/无参 | 无法配置 | 恒为 0(须 stderr 兜底,见系列篇第五章) |
七、--help-licenses 与许可类别速查
--help-licenses 打印 RAT 内置注册的全部许可证与匹配器信息(--help 原文:Print information about registered licenses.),实测可用,输出包含 AL1.0、AL2.0 等注册许可证条目及其 matcher 细节:
cd /opt && java -jar rat/apache-rat-0.18/apache-rat-0.18.jar --help-licenses | head -20
(输出为长清单,首屏即见 AL 系条目;完整内容以实际运行为准。)
结合本系列实测报告,报告里出现的许可类别标记速查:
| 报告标记 | 含义 | 出现位置 |
|---|---|---|
AL | Apache License 2.0 所在许可证家族(family)缩写 | License Categories detected 段、Detail 判定行第一列 |
AL2.0 | 许可证 ID(license ID),对应 Apache License 2.0 | Detail 判定行第二列 |
????? | 未知许可证家族的 5 问号占位 | 同上(未识别文件) |
Unknown license | 未知许可证名称 | Licenses detected 段 |
三层概念区分(由实测报告归纳):**许可证家族(family)**是一组相关许可证的归类(用于 approved/denied 策略),**许可证(license)**是具体的一种许可文本(如 AL2.0),未识别统一落 ?????/Unknown license。定制批准范围用 --license-families-approved/--license-families-denied(家族级)与 --licenses-approved/--licenses-denied(许可证级),均为多值参数(受第三章 -- 约束),详见 --help 原文。
八、新旧参数对照(0.17 起废弃)
0.17 起 CLI 参数体系改版,旧参数统一带 [Deprecated for removal since 0.17] 标注,0.18 中仍可用但每次使用打 WARN(实测样例,-x 的):
WARN: Option [-x, --xml] used. Deprecated for removal since 0.17: Use --output-style with the 'xml' argument instead.
完整对照表(新名均摘自 --help 原文的废弃提示):
| 旧参数(deprecated) | 新参数(0.18 推荐) |
|---|---|
-e,--exclude <Expression> | --input-exclude <Expression> |
-E,--exclude-file <File> | --input-exclude-file <File> |
--include <Expression> | --input-include <Expression> |
--includes-file <File> | --input-include-file <File> |
-o,--out <File> | --output-file <File> |
-x,--xml | --output-style xml |
-s,--stylesheet <StyleSheet> | --output-style <StyleSheet> |
-A,--addLicense / -a | --edit-license |
-c,--copyright <arg> | --edit-copyright <arg> |
-f,--force | --edit-overwrite |
-d,--dir <DirOrArchive> | 标准 -- 结束符(0.18 直接以 -- <目标> 传扫描目标) |
--licenses <File> | --config <File> |
--no-default-licenses | --configuration-no-defaults |
--list-families <LicenseFilter> | --output-families <LicenseFilter> |
--list-licenses <LicenseFilter> | --output-licenses <LicenseFilter> |
--scan-hidden-directories | --input-include-std HIDDEN_DIR |
迁移建议:旧脚本在新版本上先原样跑通(WARN 不影响功能与退出码),再按表逐项改名;改名时注意新参数多为多值参数,务必检查 -- 分隔(第三章)。验证迁移正确性:新命令 stderr 中不应再出现 WARN: Option [...] used. Deprecated for removal since 0.17 字样,grep -c 'WARN: Option' /tmp/rat.err 应为 0。
九、常见问题(FAQ)
Q1:明明写了排除,Unapproved 计数没降?
两种可能:一是模式层级不对——*.xml 匹配不到子目录文件,需 **/*.xml(2.1 节实测对比);二是模式根本没匹配上任何文件——RAT 对不匹配的模式不报错、静默不生效。验证方法:看 Detail 段目标文件是否已变为 I(Ignored)类型;没有就说明模式没命中。
Q2:被排除的文件从报告里消失了吗?
没有。被排除文件仍在 Detail 段中列出,类型码从 S 变为 I,Ignored 计数增加(2.1/2.2 节实测),只是不再做许可证判定、不计入 unapproved。想让文件彻底不出现,需要用 --input-include 反向圈定要审计的范围。
Q3:--input-exclude-std GIT 会读取项目的 .gitignore 吗?
会。--help 原文:GIT 集合 also processes files listed in '.gitignore' and (unless RAT_NO_GIT_GLOBAL_IGNORE is specified) the global gitignore——项目 .gitignore 与全局 gitignore 中声明的忽略项都会被 RAT 采纳;设置环境变量 RAT_NO_GIT_GLOBAL_IGNORE 可关掉全局 gitignore 的读取。
Q4:0 配置下为什么连 pom.xml、target/、.git/ 都报 unapproved?
0.18 默认不做任何标准排除(2.3 节实测:三者全部进报告),这是与旧版的显著行为差异。按需开启 --input-exclude-std MAVEN、--input-exclude-std GIT(Gradle 项目用 GRADLE),或 --input-exclude-std ALL 一步到位。
Q5:多个排除条件怎么组合?顺序有影响吗?
多值参数可重复出现(如 --input-exclude-std MAVEN --input-exclude-std GIT,2.3 节实测),--input-include 系列会覆盖排除规则(--help 原文:Will override excluded files)。组合语义为"先排除、后包含",包含优先级更高。
Q6:旧脚本里的 -e/-E/-x/-o 还能用吗?
能用。0.18 对废弃参数仅打 WARN: Option [...] used. Deprecated for removal since 0.17(实测),功能与退出码不变;但随时可能在后续版本移除,建议按第八章对照表尽快迁移到新名。
十、参考链接
- Apache Rat 0.18 官方分发目录:https://dlcdn.apache.org/creadur/apache-rat-0.18/
- Apache Rat 0.18 裸 jar(Maven Central):https://repo1.maven.org/maven2/org/apache/rat/apache-rat/0.18/apache-rat-0.18.jar
- Apache Creadur 项目与 Rat 文档站:https://creadur.apache.org/rat/
- Ant 目录模式语法(
<Expression>默认语法的官方参考,--help原文引用):https://ant.apache.org/manual/dirtasks.html#patterns - 系列篇:《Apache Rat 0.18 介绍与 CLI 审计实战》(安装、首次审计、报告解读、退出码语义与 CI 规避、jar 解包审计)