Apache Gump live r1939132 元数据与命令详解

详解 Apache Gump live r1939132 的元数据对象模型与命令体系:workspace/module/project/repository 四类 XML 的 DTD 属性表与实测校验行为、metadata/validate 校验工具链逐段解析、./gump 包装脚本与 bin/integrate.py 命令行选项实测回显,并如实记录 DTD 与实现不同步、check_env_pylib 的 Python 2 遗留缺陷等发现。

Apache GumpApache Gump2026/10/15

Apache Gump live r1939132 元数据与命令详解

目标:把 Gump 的两套核心语法讲透——元数据 XML(workspace/module/project/repository 四类对象,以官方 DTD 为准逐属性说明)与命令体系(./gump 包装脚本、bin/*.py 独立入口、metadata/validate 校验工具链),全部属性与回显以 r1939132 快照实测为准,如实记录 DTD 与实现之间已实测确认的不同步点;本文在 Ubuntu 22.04 + Python 3.10.12 上实测通过。

Gump 的全部行为由元数据驱动:workspace 回答「这一轮跑什么」,module/project 回答「项目怎么取、怎么建、谁依赖谁」,repository 回答「代码从哪来」。四类对象各有 DTD(metadata/dtd/),官方自带的校验脚本用 xmllint 强校验。命令体系分三层:Bash 包装脚本 ./gump(服务端视角的 run/test/validate)、Python 独立入口 bin/*.py(integrate/update/build 等)、以及被前两者调用的校验脚本。读懂这两套语法,就能给自己的项目写元数据并验证。

一、环境信息

  • 组件:Apache Gump live,SVN r1939132(2026-08-31 提交);元数据与源码同仓库经 svn:externals 检出
  • 参考系统:Ubuntu 22.04.5 LTS,Python 3.10.12,xmllint libxml 20913,xsltproc libxslt 10134(CentOS 8 + Python 3.6.8 实测结论一致,见第 2 篇)
  • 源码目录:/root/gump;元数据目录:/root/gump/metadata/

官方仓库自带的元数据规模(实时统计):

ls /root/gump/metadata/project/*.xml | wc -l
grep -c "<module " /root/gump/metadata/profile/gump.xml
grep -c "<project " /root/gump/metadata/profile/gump.xml
grep -c "<repository " /root/gump/metadata/profile/gump.xml
72
70
28
16

解读:metadata/project/ 下有 72 个项目定义文件;官方主 profile(profile/gump.xml)通过 href 引用聚合了 70 个 module、28 个直接 project、16 个 repository。本文的自定义示例沿用第 3 篇的 /root/gump-meta-test 工作区。

二、元数据对象模型总览

2.1 四类对象与职责

对象文件位置职责对应 DTD
workspace自定义(通常 metadata/<主机名>.xml)一轮运行的范围、产物目录、运行参数workspace.dtd
repositorymetadata/repository/*.xml代码托管源(GitBox/SVN/GitHub 等类型的站点定义)repository.dtd
modulemetadata/project/*.xml一个可检出的仓库单元,内含一至多个 projectproject.dtd
projectmodule 内的 <project> 元素构建与依赖的最小单位(buildable 单元)project.dtd

2.2 引用关系与解析顺序

实测确认的解析链:workspace 通过 <module href>/<repository href> 引入元数据文件;module 通过 <git repository="..."> 等元素的 repository 属性关联 repository 定义;project 通过 <depend project="..."> 的名称引用其他 project(跨模块亦可)。第 3 篇的加载自检输出即为证据——workspace 名称、模块、项目、依赖边全部还原。

2.3 DTD 文件与元素规模

ls /root/gump/metadata/dtd/
profile.dtd
project.dtd
README.txt
repository.dtd
workspace.dtd

project.dtd 是最大的一份,含 47 个元素(实测统计),覆盖 module/project 外层定义、8 种构建器、2 种依赖、产物与杂项元素,详见下文第四、五节。

三、workspace.xml 详解

3.1 DTD 属性表(实测取自 workspace.dtd)

<!ATTLIST workspace
  name    CDATA #REQUIRED
  VERSION CDATA #REQUIRED
  basedir CDATA #IMPLIED
  pkgdir  CDATA #IMPLIED
  logdir  CDATA #IMPLIED
  cvsdir  CDATA #IMPLIED
  jardir  CDATA #IMPLIED
  sync    CDATA #IMPLIED
  bootclass CDATA #IMPLIED
  makeCommand CDATA #IMPLIED
  mvnRepoProxyPort CDATA #IMPLIED>
属性必填含义实测说明
name是运行名出现在 Run GUID 中(第 3 篇实测 gump-ubuntu:mytest:20261015084708)
VERSION是workspace 语法版本见 3.2 大小写专项实测
basedir否源码检出根目录相对路径实测按 $GUMP_HOME 解析,产物落 /root/gump/work*/
pkgdir / jardir / logdir否包/Jar/日志目录logdir 即日志站生成位置
cvsdir否SCM 工作区实测 git 检出落在 workspace/cvs/<模块名>
sync / bootclass / makeCommand / mvnRepoProxyPort否同步开关/引导类路径/make 命令名/Maven 仓库代理端口本文未使用,低频维护属性

3.2 version 大小写专项实测(重要)

DTD 声明大写 VERSION(#REQUIRED),但官方样例与 Python 实现均用小写。两种写法的实测行为:

sed -e "2i\\
<!DOCTYPE workspace SYSTEM \"dtd/workspace.dtd\">" < /root/gump/metadata/minimal-workspace.xml > ws-check.xml
xmllint --valid --noout ws-check.xml 2>&1 | head -3
ws-check.xml:8: element workspace: validity error : Element workspace does not carry attribute VERSION
ws-check.xml:6: element workspace: validity error : No declaration for attribute version of element workspace
ws-check.xml:6: element workspace: validity error : Element workspace does not carry attribute VERSION

官方自带的 minimal-workspace.xml(用小写 version="0.4")按 DTD 严格校验不通过;而用大写 VERSION 的 workspace 能过 DTD,却会让 Python 端 getVersion() 读到 None,在第 3 篇实测中触发 bin/build.py 的 TypeError: '>=' not supported between instances of 'NoneType' and 'str'(runner.py 第 105 行)。结论:workspace 校验与 workspace 加载是两套规则,实践上遵循加载器——统一写小写 version="0.4",并接受它对 DTD 的既有偏差。

3.3 workspace 内元素

实测可用的子元素(均出现在官方样例与本文运行中):

  • <property name value>:传给构建的环境属性,官方样例内置 <property name="build.sysclasspath" value="only"/>;
  • <module href="...">、<repository href="...">:引入元数据文件,href 相对 workspace 文件所在目录解析(绝对路径实测会被重复拼接前缀,务必用相对路径);
  • <database database passwd driver jar>:服务端统计库配置(正式部署用;单机实验可省略,密码示例 passwd="q1w2e3r4")。

3.4 默认 workspace 约定与实测报错

./gump run 不带 -w 时按 metadata/<socket.gethostname()>.xml 找 workspace,实测(本机主机名 gump-centos):

RuntimeError:
  No workspace at /root/gump/metadata/gump-centos.xml!
  Maybe you need to check out the metadata from svn?
  See the file metadata/FILLME for more information...

该报错出自 cron/gump.py 第 352 行附近,可用环境变量 GUMP_WORKSPACE 或命令行 -w 覆盖(实现均已实测确认存在)。

四、module.xml 详解

4.1 module 外层定义与 SCM 元素

module 文件顶层是 <module name>,实测可用子元素:<url>、<description>、SCM 声明、以及一至多个 <project>。SCM 元素均来自 project.dtd(47 元素清单包含 cvs/svn/p4/git/hg),以本文实测用过的 git 为例,完整属性表:

<!ATTLIST git
  branch     CDATA #IMPLIED
  dir        CDATA #IMPLIED
  repository CDATA #IMPLIED
  debug      CDATA #IMPLIED
  verbose    CDATA #IMPLIED >
属性含义本文实测用法
repository关联 repository 定义的名称repository="myrepo"(第 3 篇真实拉取 commons-io.git 的关联方式)
dir仓库相对路径/名称dir="commons-io.git",更新器拼出 git clone .../commons-io.git
branch分支实测默认 master(更新命令 git clone --quiet --recursive --branch master ...)
debug / verbose输出开关未使用

其余 SCM 元素同理(hg 属性与 git 完全同名;svn/cvs/p4 各有 url/path 等差异属性)。svn 类型实测可用(官方大量使用),git 类型已在第 3 篇对 GitBox 真实验证。

4.2 一个完整 module 的结构(本文实测样本)

<module name="hello-gump">
  <url href="http://gump.apache.org"/>
  <description>Minimal Gump module for validation testing.</description>
  <git repository="myrepo" dir="hello-gump.git"/>
  <project name="hello-gump-core"> ... </project>
  <project name="hello-gump-test"> ... </project>
</module>

要点:<url> 是项目主页(出现在报告页链接里);<description> 原文出现在日志站项目页(第 3 篇 3.4 节实测提取到了这段文字);两个 <project> 的依赖关系构成聚合顺序(core 先于 test)。

五、project.xml 详解

5.1 project 元素实测属性表(取自 project.dtd)

<!ATTLIST project
  name    CDATA #REQUIRED
  bundle  CDATA #IMPLIED
  ...>

核心属性是 name(#REQUIRED,全局唯一的项目标识,被 <depend project="..."> 引用)。project 的内容元素分四类,以下属性表均从 project.dtd 实测摘录。

5.2 构建器元素(8 种)

元素关键属性(DTD 摘录)适用本文实测
anttarget、buildfile、basedirAnt 项目已用(<ant target="jar">),构建调用形如 java org.apache.tools.ant.Main
mavenpom、goal、basedirMaven 1未实测
mvn / mvn1 / mvn2 / mvn3mvn3: goal、profile、separateLocalRepository、timeout、buildfile、basedir、target、verbose、debugMaven 2/3mvn3 在官方元数据中广泛使用
mvn3installbasedir、file、packaging、version、artifactId把第三方包安装进 Maven 本地仓见 5.5 既有报错专项
gradle(见 DTD)Gradle 项目env.py 实测会探测 gradle --version
make / configure / scriptmake: target、basedir非 Java 项目env.py 实测探测 make

构建器可携带 <property name value>、<sysproperty>、<jvmarg> 子元素(.dtd 中均有声明)。

💡 技术拓展:ant 与 mvn3 的选择对比——

维度<ant><mvn3>
依赖解析交给 Ant classpath(配合 <depend> 注入 jar)Maven 自行解析 pom
离线友好高(jar 由上游 Gump 项目供给)低(需本地仓/代理,workspace 提供 mvnRepoProxyPort)
现代项目适配多数 Apache 项目已迁 Maven,build.xml 不复存在官方元数据主流写法

本文示例采用 <ant>(hello-gump 与 commons-io-live),为的是走通最小链路;接入现代项目时官方实践是 <mvn3> + mvn3install 安装预置件。

5.3 依赖元素

  • <depend project>:强依赖,被依赖项失败则本项目不构建(属性含 artifactId/groupId/id/ids,供 Maven 构件级依赖);
  • <option project>:软依赖,仅参与构建排序,不阻断(本文 hello-gump-test 对 junit 即用 option,实测运行不因 junit 缺失而报错)。

两者在依赖图中的实测语义已在第 3 篇加载自检中体现(hello-gump-test depends: ['hello-gump-core'])。

5.4 产物与杂项元素

元素用途实测说明
<jar name id>声明本项目产出的 jar,id 供下游 depend 引用commons-io-live 示例 jar name="commons-io-*.jar" id="commons-io"
<home nested>项目主目录(嵌套路径)已用
<package>Java 包前缀已用
<license name>许可证文件已用
<nag to from subject>失败通知邮件未实测(服务端邮件链路)
<javadoc> / <junitreport> / <report>文档与报告产物未实测
<noclasspath> / <work> / <pom> 等特殊构建语义见 project.dtd

5.5 官方元数据的既有 DTD 报错(如实记录)

官方 live 元数据自身有两处 DTD 不合规,两套系统(Ubuntu py3.10 / CentOS py3.6)实测回显逐字一致:

./tmp/./project/easymock.xml:30: element mvn3install: validity error : No declaration for attribute allowPropertyReferenceInVersion of element mvn3install
./tmp/./project/junit.xml:48: element mvn3: validity error : Element mvn3 content does not follow the DTD, expecting (property | depend | jvmarg)*, got (sysproperty )

解读:easymock 用到的 allowPropertyReferenceInVersion 属性确实不在 mvn3install 的 ATTLIST 里;junit 的 mvn3 内嵌 sysproperty 不符合 mvn3 内容模型(DTD 允许 property/depend/jvmarg)。这是 DTD 与实际用法脱节的直接证据——新增项目时不要模仿这两处写法。

六、repository.xml 详解

repository 定义托管站点,实测样本(第 3 篇真实使用):

<repository name="myrepo" type="git">
  <title>My Demo Repository</title>
  <home-page>http://gitbox.apache.org/repos/asf/</home-page>
  <url>http://gitbox.apache.org/repos/asf/</url>
  <redistributable/>
</repository>
项说明实测依据
type 属性仓库类型(git/svn 等),决定 SCM 元素拼 URL 的方式type="git" 实测拼出 http://gitbox.apache.org/repos/asf/commons-io.git
<url>仓库基址,module 的 dir 拼在其后commons-io-live 检出成功即验证
<home-page>展示用链接出现在报告页
<redistributable/>允许转发构件(Gump 构件再分发策略标记)官方仓库定义普遍携带

官方主 profile 关联的 16 个 repository(实测统计)覆盖 GitBox/SVN/GitHub 等站点,自定义 repository 时直接仿写官方文件最稳妥。

七、校验工具链详解:metadata/validate

./gump validate 实际执行 metadata/validate Bash 脚本,逐段解析(与 4.5/4.6 节实测行为对应):

  1. 临时目录与文件复制:把 repository/profile/project 三类 XML 复制进 ./tmp/(实测回显的报错路径前缀 ./tmp/./project/ 即来源于此),dtd/ 目录随行;
  2. DOCTYPE 注入:对每个文件用 sed 注入 <!DOCTYPE ... SYSTEM "dtd/xxx.dtd">(官方元数据文件本体不带 DOCTYPE),随后 xmllint --valid 逐个强校验;repository/profile/project 三段各自循环,失败的打印 validity error 与行号;
  3. 外部项目段:xsltproc ./tools/externals.xslt ./profile/gump.xml 枚举需远程拉取校验的外部文件再逐个 xmllint——实测当前快照该输出为 0 行(官方 profile 未登记外部校验项),该段静默通过。

全程实测耗时 0.8s(72 个本地文件 + 三段循环)。校验通过判据:除既有 2 处报错外无新增 validity error 行。该脚本不校验 workspace.xml(workspace 的校验方式见 3.2 节手工 DOCTYPE 法)。

八、命令详解

8.1 ./gump 包装脚本(Bash 层)

实测命令表(./gump help 输出与源码核对一致):

命令作用依赖检查(实测)
run完整运行(cron 链路)GUMP_HOME、JAVA_HOME、python、pkill;并检查 python 库 rdflib、MySQLdb
test单元测试GUMP_HOME、python
validate元数据 DTD 校验xmllint、xsltproc、curl
site / site-publishForrest 文档构建 / SSH 发布forrest(本文未使用,帮助原文:Use Apache Forrest to build the documentation.)
help帮助无

另实测确认一个未列入帮助的隐藏命令 experimental-tests(源码 case 分支存在)。

已知缺陷(实测确认):check_env_pylib 是 Python 2 语法——它生成临时文件 pycmd.tmp.py,内容为:

try:
  import rdflib
except:
  print "error"

在 Python 3 下执行时必然报错(Ubuntu 3.10.12 实测回显):

  File "/root/gump/pycmd.tmp.py", line 4
    print "error"
    ^^^^^^^^^^^^^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?

因此 ./gump run 在 Python 3 上的库预检环节是坏的(报错后脚本继续走主流程)。绕过方式:直接调 bin/integrate.py(第 3 篇已验证完整可用)。

8.2 Python 优先级:cron/gump.sh

服务端启动脚本实测按 python3 优先选择解释器:

export GUMP_PYTHON="`which python3`"

取不到时回退 python,两者皆无则报 No Python (python3 nor python) found in path.(源码第 45-49 行)。Ubuntu 22.04 天然满足;CentOS 8 需先补 python 软链(第 2 篇)。

8.3 bin/*.py 独立入口与命令行选项

bin/integrate.py、bin/update.py、bin/build.py 等共用 gump/core/commandLine.py 的 handleArgv。实测 -h 完整回显(integrate/build 相同):

Usage: python gump.core.commandLine.py -w {workspaceFile} [OPTION] [PROJECT]

Mandatory arguments to long options are mandatory for short options too.

Startup:
  -V,  --version           display the version of Apache Gump(TM) and exit.
  -h,  --help              print this help.
  -w,  --workspace         use this workspace for Gump.

General:
  -v,  --verbose           verbose logging.
  -d,  --debug             debug logging.

 Not relevent to all scripts:
  -O,  --official          Full run, publishing notifications, etc.
  -D,  --dated             Dated log files.
  -c,  --cache             Use local cache (do not download over HTTP).
  -t,  --text              Use text not xdocs.
  -X,  --xdocs             Output xdocs, not XHTML.

For bug reports use JIRA: http://issues.apache.org/.
For suggestions: <general@gump.apache.org/>.

-V 实测回显(横幅即版本展示):

     _____
    |   __|_ Apache_ ___
    |  |  | | |     | . |
   |_____|___|_|_|_|  _|
                    |_|     ~ v. 2.3 ~

实测选项行为备注:

  • -w 必须是第一个参数(handleArgv 仅对 argv[1] 做 workspace 识别,实测 -X -w <file> 报 No workspace defined with -w.);
  • 帮助文本写 -X, --xdocs,但解析分支实测只注册了小写 -x(大写 -X 被当作项目表达式吞掉)——帮助文本与实现不一致,用小写 -x;
  • 位置参数是项目表达式:all 或单个项目名(实测两者均有效)。

8.4 各入口适用性实测结论(r1939132 快照)

入口Python 3 实测结果建议
bin/integrate.py完整可用,离线退出码 0,产出 HTML/RSS/Atom首选(官方服务端同款链路)
bin/update.py / bin/build.py初始化阶段 RuntimeError: Not Implemented on TextResolver: getFile.(RSS 联合分发器时序缺陷,py3.10 与 py3.6 复现一致)避免独立调用,能力由 integrate 覆盖
./gump validate / ./gump test正常元数据工作与开发自测用
./gump run库预检的 py2 语法报错后继续,可用 -w 正常驱动可用但建议直连 integrate

8.5 运行日志的固定格式(实测样本)

./gump run 与 cron 链路产生的运行日志(实测回显节选):

- GUMP run by Python : '3.6.8 ...'
- GUMP run by Gump   : 2.0.2-alpha-0003
- GUMP run on OS     : 'posix'
- GUMP run in env    :
      GUMP_HOME -> [/root/gump]
      JAVA_HOME -> [/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-4.el8_5.x86_64]
      ...

版本双轨:命令行横幅是 v. 2.3(python/gump/core/config.py 的 setting.VERSION),cron 链路自报 2.0.2-alpha-0003(cron/gump.py 的 GUMP_VERSION)——两处指同一份代码的内部版本串,阅读日志时注意区分。

九、常见问题(FAQ)

Q1:写新项目元数据应该抄哪个官方文件? 选与目标项目同构建器的:Ant 项目抄 metadata/project/ant.xml,Maven 项目抄 metadata/project/easymock.xml(注意规避 5.5 节两处既有报错写法)。本文自定义样本(repository + module 双文件)也可直接作为模板。

Q2:workspace 校验总报 workspace 不携带 VERSION 属性? DTD 要求大写、样例用小写是快照内的既知偏差(3.2 节实测复现)。给 workspace 做严格 DTD 校验时临时用大写,运行时统一小写 version="0.4";或如官方现状一样只校验 repository/profile/project 三类。

Q3:<depend> 与 <option> 到底差在哪? <depend> 决定「构建不了」(被依赖项失败则跳过本项目),<option> 只决定「构建顺序」。测试框架类(junit)等可选增强用 option,库依赖用 depend——本文两处实测行为与此一致。

Q4:为什么 -X 没生效? 解析器只认小写 -x(8.3 节实测),帮助文本的大写写法与实现不符。参数顺序上 -w 必须放在第一个位置参数之前。

Q5:validate 报 easymock/junit 的 error,我需要修吗? 那是官方元数据的既有问题(5.5 节),不属于你的安装或修改。提交元数据变更时保证自己新增的文件无新增 validity error 即可。

Q6:哪里能看到这轮运行的完整环境与版本? 跑一次 ./gump run(或 cron 链路)看运行日志头部:GUMP 版本(2.0.2-alpha-0003)、Python 版本、JAVA_HOME 与全部环境变量逐行列出(8.5 节实测样本);HTML 报告的 index.html 也会记录 Run GUID 与 Gump Version 2.3。

十、参考链接

  1. 官方元数据对象模型(对象/属性权威描述):https://gump.apache.org/metadata/index.html
  2. workspace 元素文档:https://gump.apache.org/metadata/workspace.html
  3. project/module/repository DTD 原文(随源码检出):https://svn.apache.org/repos/asf/gump/live/metadata/dtd/
  4. 校验脚本与外部项目转换表(随源码检出):https://svn.apache.org/repos/asf/gump/live/metadata/validate
  5. Python Gump 命令行文档:https://gump.apache.org/python/usage.html
  6. 官方 vmgump 实例(元数据实践样例库):http://vmgump.apache.org/