Apache Gump live r1939132 快速入门与集成示例
基于实测快照 Apache Gump live r1939132 的快速入门:从编写最小 module/project/repository 元数据、DTD 校验、Python 加载自检,到离线 integrate 生成 HTML/RSS 报告,再到真实 git 检出 commons-io 并构建的全流程,所有命令与回显均在 Ubuntu 22.04 + Python 3.10.12 实测通过。
Apache Gump live r1939132 快速入门与集成示例
目标:在一台装好 Gump(第 1 篇方案 A/B 均可)的机器上,从零写出第一批自定义元数据,用官方工具完成 DTD 校验与 Python 加载自检,跑通一次离线集成并产出 HTML/RSS 报告,最后把元数据指向真实 Git 仓库体验完整「更新→构建→报告」流水线;本文全部命令与回显均在 Apache Gump live r1939132 + Ubuntu 22.04.5 LTS + Python 3.10.12 实测通过。
先建立心智模型:Gump 的输入只有两样——workspace(描述这一轮跑什么、在哪跑)和 module/project 元数据(描述聚合哪些仓库、每个项目的构建方式与依赖);输出也主要两样——日志站 HTML 与 RSS/Atom 联合分发。bin/integrate.py 是把这两头串起来的执行器,它会依次执行环境检查、元数据加载、SCM 更新、逐项目构建、依赖图统计与文档生成。理解了这一点,下面的每个步骤就都是在「喂元数据、读输出」。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS,x86_64
- Python:3.10.12;SVN:1.14.1;xmllint:libxml 20913;xsltproc:libxslt 10134
- JDK:OpenJDK 11.0.32.1;Ant:1.10.12
- 组件:Apache Gump live,SVN r1939132(2026-08-31 提交),内部版本串 2.3
- 安装方式:第 1 篇方案 A + B,源码位于
/root/gump - 实验目录:元数据工作区
/root/gump-meta-test(下文第 2 步创建)
进入环境前先确认三件事(实时回显):
cd /root/gump && ./gump help | head -3
_____
| __|_ Apache_ ___
| | | | | | . |
python3 --version && svn --version --quiet
Python 3.10.12
1.14.1
echo "GUMP_HOME=$GUMP_HOME"; hostname -s
GUMP_HOME=/root/gump
gump-ubuntu
💡 技术拓展:本文所有实测在两种入口上做过对比——
入口 实测结果 适用 bin/integrate.py(集成运行器)离线运行退出码 0,完整产出报告 本文采用 bin/update.py/bin/build.py(独立运行器)初始化阶段崩溃 Not Implemented on TextResolver: getFile不可用(r1939132 已知缺陷) 官方服务端跑的正是 integrate(cron/gump.py 调
python/gump/integrate.py),独立 update/build 入口在当前快照的 Python 3 运行时下不可用,本文统一采用bin/integrate.py。
二、10 分钟跑通第一个集成
本节四步走:建目录与元数据 → 官方 DTD 校验 → Python 加载自检 → 离线集成出报告。全程不联网(SCM 更新一步关闭)。
2.1 第 1 步:搭建独立元数据工作区
不在官方 metadata/ 里直接改动,而是在 /root/gump-meta-test 建独立工作区,只引用官方 DTD 与校验脚本:
mkdir -p /root/gump-meta-test/{project,repository,profile,tmp}
cp -r /root/gump/metadata/dtd /root/gump-meta-test/
cp /root/gump/metadata/validate /root/gump-meta-test/
mkdir -p /root/gump-meta-test/tools
cp /root/gump/metadata/tools/*.xslt /root/gump-meta-test/tools/
三个核心文件的职责:repository/ 定义代码托管源,project/ 定义模块与项目(一个 module 是一个仓库单元,内含一至多个 project),dtd/ 是校验依据。
写入第一个仓库定义 /root/gump-meta-test/repository/myrepo.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<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>
写入第一个模块 /root/gump-meta-test/project/hello-gump.xml,包含两个项目和一个 core → test 依赖:
<?xml version="1.0" ?>
<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">
<package>org.example.hellogump</package>
<ant target="jar">
<property name="debug" value="on"/>
</ant>
<depend project="xml-xerces"/>
<home nested="dist"/>
<jar name="dist/hello-gump-core.jar" id="hello-gump-core"/>
<license name="LICENSE.txt"/>
</project>
<project name="hello-gump-test">
<package>org.example.hellogump.test</package>
<ant target="test"/>
<depend project="hello-gump-core"/>
<option project="junit"/>
</project>
</module>
逐段解读:<git repository="myrepo" dir="hello-gump.git"/> 声明该模块由 myrepo 仓库的 hello-gump.git 检出;<ant target="jar"> 声明用 Ant 目标 jar 构建,可带 <property>;<depend> 是强依赖(被依赖项目失败则本项不构建),<option> 是软依赖(仅做顺序排序);<jar id> 给产出的构件命名,供下游 <depend project="..."/> 引用。完整元素表见第 4 篇。
2.2 第 2 步:官方 DTD 校验
直接复用官方校验脚本(它逐个用 xmllint 校验 repository/profile/project 三类文件):
cd /root/gump-meta-test && bash validate 2>&1 | head -8
======== Processing Repositories ============
======== Processing Profiles ============
======== Processing Local Projects ============
======== Processing External Projects ============
本地项目阶段没有输出任何 validity error,即 myrepo.xml 与 hello-gump.xml 都通过校验(脚本对通过者静默、对失败者打印行号与原因)。
反向验证——故意写一个非法元素 <bogus-element value="x"/> 再校验:
sed 's|<depend project="xml-xerces"/>|<depend project="xml-xerces"/>\n <bogus-element value="x"/>|' project/hello-gump.xml > project/bad.xml && cp project/bad.xml project/hello-gump.xml && bash validate 2>&1 | grep -c "validity error"
3
xmllint 报出的 3 条 validity error 均指向 <bogus-element>(元素未声明及连带的项目内容校验失败),删除该元素恢复原文件后校验归零。这证明校验链对自定义元数据真实有效。
2.3 第 3 步:Python 加载自检
DTD 校验只证明「格式合法」,不证明「能被 Gump 读进内存」。用仓库自带的 WorkspaceLoader 写一个 10 行的自检脚本 /root/load-test.py:
import sys, os
sys.path.insert(0, os.path.abspath("python"))
sys.path.insert(0, os.path.abspath("."))
from gump.core.gumpinit import gumpinit
from gump.core.loader.loader import WorkspaceLoader
gumpinit()
wsfile = sys.argv[1]
ws = WorkspaceLoader(False).load(wsfile)
print("WORKSPACE name:", ws.getName())
mods = list(ws.getModules())
print("MODULES:", [m.getName() for m in mods])
projs = list(ws.getProjects())
for p in projs:
print("PROJECT:", p.getName(), "| depends:",
[d.getProject().getName() for d in p.directDependencies.depends])
print("LOAD_OK")
同时写入对应 workspace /root/gump-meta-test/my-workspace.xml(注意 version 属性,大小写坑见 4.1 节):
<?xml version="1.0"?>
<workspace
name="mytest"
basedir="work/workspace"
pkgdir="work/packages"
jardir="work/jars"
logdir="work/logs"
version="0.4">
<property name="build.sysclasspath" value="only"/>
<module href="project/hello-gump.xml"/>
<repository href="repository/myrepo.xml"/>
</workspace>
执行自检:
cd /root/gump && python3 /root/load-test.py /root/gump-meta-test/my-workspace.xml 2>&1 | tail -5
WORKSPACE name: mytest
MODULES: ['hello-gump']
PROJECT: hello-gump-core | depends: []
PROJECT: hello-gump-test | depends: ['hello-gump-core']
LOAD_OK
验证点:workspace 名称、模块列表、两个项目的依赖边全部按元数据还原,说明元数据已被 Gump 对象模型完整解析。
2.4 第 4 步:离线集成,产出报告
GUMP_WORK_OFFLINE=true 关闭 SCM 更新(hello-gump.git 本就不存在),让流水线走完「加载→构建尝试→统计→文档→联合分发」全链:
cd /root/gump
export PYTHONPATH=/root/gump/python:/root/gump GUMP_HOME=/root/gump
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 GUMP_WORK_OFFLINE=true
python3 bin/integrate.py -w /root/gump-meta-test/my-workspace.xml all > /tmp/integ.log 2>&1
echo "EXIT=$?"
EXIT=0
运行末尾的完整回显:
Document run using [XDocDocumenter]
Document run using [TextDocumenter]
Syndicate run using [<gump.actor.syndication.rss.RSSSyndicator object at 0x7a3b031886d0>]
Syndicate run using [<gump.actor.syndication.atom.AtomSyndicator object at 0x7a3b03188670>]
Wipe Directory ['/root/gump/work/workspace/mvnlocalrepo']
Synchronize work->log, and clean-up...
Wipe Directory ['/root/gump/work/workspace/xdocs-work']
Gump Integration complete. Exit code [0=SUCCESS] : 0
关键解读:Unable to register RDF Describer : cannot import name 'TYPE' from 'rdflib' 出现在日志中(含 1 处 Traceback)——这是 rdflib 新版 API 不兼容所致,Gump 打印警告后跳过该描述器,不影响退出码 0,如实记录。
产出的日志站结构:
ls /root/gump/work/logs/
atom.xml
buildLog.html
context.html
css
diffsLog.html
favicon.ico
gump_icons
gump_repo
gump_work
hello-gump
images
index.html
module_fixes.html
module_todos.html
notesLog.html
packages.html
project_fixes.html
project_prereqs.html
project_todos.html
repositories.html
运行首页记录的运行标识(实时提取):
Apache Gump(TM) Run GUID gump-ubuntu:mytest:20261015084708
Gump Version 2.3
两个项目各有一套 logs/hello-gump/<项目名>/ 报告(含 rss.xml、atom.xml、状态详情),project_prereqs.html 汇总了依赖前置图。到这一步,元数据 → 校验 → 加载 → 集成 → 报告的最小闭环已经全部走通。
三、集成真实项目:从 GitBox 实时检出 commons-io
本节把元数据指向真实存在的仓库,验证 SCM 更新与构建尝试两个阶段。选择 commons-io 是因为它体量适中且发布在 GitBox。
3.1 指向真实仓库的元数据
新增模块 /root/gump-meta-test/project/commons-io-live.xml:
<?xml version="1.0" ?>
<module name="commons-io-live">
<url href="https://commons.apache.org/proper/commons-io/"/>
<description>Live update test against commons-io git.</description>
<git repository="myrepo" dir="commons-io.git"/>
<project name="commons-io-live">
<package>org.apache.commons.io</package>
<ant target="jar"/>
<home nested="target"/>
<jar name="commons-io-*.jar" id="commons-io"/>
</project>
</module>
对应 workspace /root/gump-meta-test/ws-live.xml(basedir 等相对路径实测落在 $GUMP_HOME 下而非 workspace 文件旁,产物出现在 /root/gump/work-live/):
<?xml version="1.0"?>
<workspace
name="wslive"
basedir="work-live/workspace"
pkgdir="work-live/packages"
jardir="work-live/jars"
logdir="work-live/logs"
version="0.4">
<property name="build.sysclasspath" value="only"/>
<module href="project/commons-io-live.xml"/>
<repository href="repository/myrepo.xml"/>
</workspace>
3.2 跑完整集成(在线)
这次不设 GUMP_WORK_OFFLINE,让更新阶段真实执行 Git 操作:
cd /root/gump
export PYTHONPATH=/root/gump/python:/root/gump GUMP_HOME=/root/gump
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
python3 bin/integrate.py -w /root/gump-meta-test/ws-live.xml commons-io-live > /tmp/integ-live.log 2>&1
echo "EXIT=$?"
EXIT=0
3.3 更新阶段实测:真实 Git 检出成功
模块级更新报告 work-live/logs/commons-io-live/gump_work/update_commons-io-live.html 的关键内容(实时提取):
Details State: Success For: Module: commons-io-live
Working Directory: /root/gump/work-live/workspace/cvs/commons-io-live
Exit Code: 0 Elapsed Time: 2 secs
Command Line: git fetch --quiet --no-tags origin +refs/heads/master:refs/remotes/origin/master
首次运行(目录为空时)执行的是完整克隆,命令为 git clone --quiet --recursive --branch master http://gitbox.apache.org/repos/asf/commons-io.git,实测 State: Success。检出的真实源码:
ls /root/gump/work-live/workspace/commons-io-live | head -5
CODE_OF_CONDUCT.md
CONTRIBUTING.md
LICENSE.txt
NOTICE.txt
ls /root/gump/work-live/workspace/commons-io-live/build.xml 2>&1
ls: cannot access '/root/gump/work-live/workspace/commons-io-live/build.xml': No such file or directory
更新阶段结论:Gump 的 Git 更新器对 GitBox 仓库真实可用(clone 与后续 fetch 均退出码 0);同时如实记录一个发现——当前 commons-io 主干只有 Maven 的 pom.xml,没有 build.xml,Gump 元数据里按旧式 <ant> 构建会注定失败,这正是下一阶段实测到的结果。
3.4 构建阶段实测:失败也是流水线的正常输出
项目级构建报告 gump_work/build_commons-io-live_commons-io-live.html 实时提取:
Details State: Failed For: Project: commons-io-live
Working Directory: /root/gump/work-live/workspace/commons-io-live
Exit Code: 1
构建输出文件 work-live/workspace/tmp/build_commons-io-live_commons-io-live.txt 的全部内容:
Error: Could not find or load main class org.apache.tools.ant.Main
Caused by: java.lang.ClassNotFoundException: org.apache.tools.ant.Main
两层原因叠加:Gump 以 java org.apache.tools.ant.Main 方式调起 Ant,本环境 Ant 类路径未被解析;且该项目本无 build.xml。项目状态如实落盘(项目详情页 index.html 提取):
Project : commons-io-live
State Current State: Failed
Reason: Build Failed
模块级状态仍为 Success(SCM 检出成功),项目级 Failed(构建失败)——这正是 Gump 的设计语义:模块状态只反映源码获取,项目状态反映构建,聚合报告把两者分开呈现。
3.5 联合分发产物实测
运行结束后,模块日志目录同时生成 RSS 与 Atom:
ls /root/gump/work-live/logs/commons-io-live/*.xml
/root/gump/work-live/logs/commons-io-live/atom.xml
/root/gump/work-live/logs/commons-io-live/rss.xml
head -c 280 /root/gump/work-live/logs/commons-io-live/rss.xml
<rss version="2.0" xmlns:gump="http://gump.apache.org/" xmlns:admin="http://webns.net/mvcb/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"> <channel> <title>Apache Gump(TM):
另有 changes_to_commons-io-live.txt 记录本次更新的源码变更清单。整套「HTML 报告 + RSS/Atom + 变更清单」就是 Gump 对外联合分发的标准产物,订阅方按 URL 轮询即可获知每次聚合运行的结果。
四、快速上手中的实测要点
4.1 workspace 的 version 大小写坑
workspace.dtd 声明的是大写属性,而官方样例与 Python 加载器都用小写,实测现象完全一致:
- 用大写
VERSION="0.4"写 workspace:DTD 校验通过,但 Python 加载后getVersion()为 None,bin/build.py在 runner.py 第 105 行抛TypeError: '>=' not supported between instances of 'NoneType' and 'str'(Python 2 时代 None 可比较,Python 3 报错); - 用小写
version="0.4":加载正常,integrate 退出码 0。
结论与做法:统一用小写 version="0.4",与官方 metadata/minimal-workspace.xml 保持一致;这正是 r1939132 快照里 DTD 与实现不同步的现状,遵循实现即可。
4.2 命令行参数顺序
bin/integrate.py 的 -w 解析只识别紧跟位置参数的形态(handleArgv 中 -w/--workspace 作为首参处理),实测 -X -w <file> 会报 No workspace defined with -w。习惯写法固定为:
python3 bin/integrate.py -w <workspace 文件> <项目表达式>
项目表达式实测可用 all(全部)或单个项目名(如 commons-io-live)。
4.3 依赖在元数据里不声明就等于不存在
hello-gump 元数据里 <depend project="xml-xerces"/> 引用的项目既不在官方 profile 关联范围内、也没在本工作区定义,integrate 运行实测会按「不存在的依赖」处理并继续(该依赖边只参与排序,不触发构建)。首次写元数据的建议:先把 <depend> 清单写真实存在的项目,再逐步扩展,避免把排序关系写空。
五、技术拓展与选型说明
💡 技术拓展:Gump 与常规 CI(Jenkins/GitHub Actions)的定位差异——
维度 Apache Gump 常规 CI 调度单位 跨仓库依赖图(模块/项目) 单仓库流水线 元数据 独立 XML,仓库与项目分离声明 每仓库一份配置 价值 提前发现上游改动破坏下游 保障自身分支质量 报告形态 HTML 日志站 + RSS/Atom 订阅 Web UI + 通知 本文选用 Gump live r1939132 的
bin/integrate.py:它与环境检查、元数据校验、真实 SCM 更新、联合分发四个环节都打通,且是官方服务端同款入口。
六、常见问题(FAQ)
Q1:离线 integrate 的退出码 0 但日志里有 Traceback,算成功吗?
算。退出码 0 表示流水线各阶段完成;日志里的 Traceback 是 RDF 描述器导入失败(rdflib API 变更),该描述器被跳过,其余功能不受影响。项目构建失败也不会改变整合运行的退出码——看结果要读 logs/index.html 与各项目状态页。
Q2:为什么我的项目全部 Failed with reason Build Failed?
大概率是元数据声明了 <ant> 但项目里没有 build.xml,或本机 Ant 未随 Gump 的调用方式正确解析(本文 3.4 节即实测到了 ClassNotFoundException: org.apache.tools.ant.Main)。先确认源码树里的构建文件与元数据声明一致,再排查 java org.apache.tools.ant.Main 能否手工执行。
Q3:产物目录总变来变去?
workspace 的 basedir/logdir 等相对路径实测按 $GUMP_HOME 解析。固定写法:要么给绝对路径,要么认清产物落在 /root/gump/work*/ 下再到日志站里找 HTML。
Q4:怎么只跑一个项目?
命令行最后的项目表达式控制范围:all 跑全部,写单个项目名(如 commons-io-live)则只跑该项目及其依赖链(实测有效)。
Q5:Python 3.6(CentOS 8)也能照本文操作吗?
能。第 2 篇已实测同一套流程在 Python 3.6.8 下结果一致(单测 6/6、离线 integrate 退出码 0),仅需先按该篇 4.6 节补 python 软链。
七、参考链接
- 官方元数据对象模型:https://gump.apache.org/metadata/index.html
- 官方 workspace XML 说明:https://gump.apache.org/metadata/workspace.html
- Python Gump 命令用法:https://gump.apache.org/python/usage.html
- 官方运行示例脚本:https://svn.apache.org/repos/asf/gump/live/demo-gump-run
- 官方 vmgump 运行实例(真实运行报告样例):http://vmgump.apache.org/