Repository navigation
Releases
code-association 0.10.0
code-association 0.10.0
跨程序变更影响扫描工具(Java / Maven 多模块仓库):分析一次提交改动了哪些类、方法、
SQL、MQ 消息结构,并推导出对其他模块 / 服务的连带影响与风险等级。
这一版有两件新东西:设置页可以把设置项 + 全部代码源导出成一个文件,搬到另一台机器上导入回来;
证据面板不再只贴引用行上下 3 行,而是把引用行所在的整个方法 / 类型 / XML 元素 / SQL 语句展开。
同时修好两处「读不到、读不全」的问题:大变更上影响清单过多会让整次分析在最后一步失败,
历史报告的证据链则整段显示「源码不可用」。
新增:配置导入导出
换机器以前要分两步:先用「代码源导入导出」搬代码源,再手工重配 AI 接口与 GitLab 令牌——
只带走代码源的话,另一半配置没人记得,新机器上第一件事就是「AI 审核怎么不生效」。
现在设置页的「配置导入导出」卡片把 AI 审核设置、GitLab 令牌与全部代码源装进同一个文件
(kind=code-association.config、version=1),导出与导入各一个接口。
- 密钥默认不进文件。 「包含密钥」默认不勾,此时文件里没有
ai.apiKey与gitlab.token;
只有显式勾选或?secrets=1才写入,导出响应带Cache-Control: no-store。 - 导入不会清空本机密钥。 文件里没写的字段保持本机现值——一份不含密钥的备份被导回来,
不该顺手把令牌清空。 - 部分成功是常态,仍是 HTTP 200。 设置项按
ai/gitlab分组独立校验、独立应用,
失败的一组记入settings.errors(带section与中文reason),其余分组与代码源照常生效;
只有kind不认识、version比 1 新才回 400。 - 也接受 5.9 的代码源导出文件(
kind=code-association.sources),此时只处理代码源。
新增:证据链展开引用行所在的整段代码
证据行与路径跳点下方原来固定贴引用行上下各 3 行:够看清一个条件,却常常把方法签名和结尾切在
窗口外,读者仍然要回仓库确认「这是哪个方法」。现在 GET /api/analyses/{id}/code 支持
mode=block(界面固定传),片段按代码块边界取整块:
- Java / JS / TS 等花括号语言取最近的方法体 / 类型体 / 初始化块;
if/for/try这类
控制块继续向外扩,lambda 与匿名类也继续向外;字符串、注释、文本块里的花括号不参与配对。 - MyBatis mapper / XML 取包含引用行的元素(通常是一整条
<select>),根元素不选。 .sql按分号切语句,字符串与注释里的分号不算。- 没有块边界的
.properties/.yml退化为上下各 10 行。 - 超过 160 行的块只展示引用行附近,并注明「共 N 行,展示第 a–b 行」。
片段上方新增一行小字说明范围(「方法 · 第 27–30 行」「元素 select · 第 5–20 行」);
原来的 note 继续只承担「分析版本不在本地仓库」「文件只到第 N 行」这类异常说明。
修复:跨程序影响过多时,分析不再在最后一步失败
一次 2880 个文件、20052 项变更的分析产出 67 万条跨程序影响,report_json 序列化成单个字符串时
撞上 Jackson 的 2 GiB 文本缓冲上限,整次分析在跑完 107 秒后被标记失败、报告全丢。现在影响清单
按风险保留前 N 条(code-association.max-report-impacts,默认 5000,名额按对比程序公平分配),
计数仍按全量;报告新增 impactsTotal / impactsShown / impactsTruncated / impactsNote,
审核页明确写出「共多少处、列表保留多少处」。同一批影响不再序列化两遍(peers[].impacts 不再进
JSON),契约地图的模块关系边也按程序去重。
修复:历史报告的证据链不再整段显示「源码不可用」
报告里的 peerSourceId 是 long,本程序内部影响落库后是 0 而不是 null;前端把 0 当成
对比程序 id 传给源码接口,服务端按「这次分析里没有该对比程序」拒绝。现在 0 与空值同义
(读本程序源码),历史报告里也能直接展开方法。
下载
| 文件 | 说明 |
|---|---|
code-association-0.10.0.jar |
可执行 jar 单文件,应用内「自动更新」用的就是它 |
code-association-0.10.0.zip |
Windows 推荐(自带解压即可,保留 CRLF) |
code-association-0.10.0.tar.gz |
Linux / macOS 推荐 |
两个压缩包内容完全一致,均包含:可执行 jar、start.sh / stop.sh、
start.bat / stop.bat / start.ps1 / stop.ps1、application.yml 示例配置、
README.md、docs/ 与 INSTALL.md。
运行
Linux / macOS
tar -xzf code-association-0.10.0.tar.gz # 或 unzip code-association-0.10.0.zip
cd code-association-0.10.0
chmod +x start.sh stop.sh
./start.sh # 默认 http://127.0.0.1:9996
./stop.shWindows
:: 解压 zip,进入解压目录
start.bat :: 默认 http://127.0.0.1:9996
stop.bat需要 JDK 21+。详见包内 INSTALL.md。
升级说明
从 0.3.0 起可以直接用应用内更新:设置 → 版本与更新 → 应用更新 → 按提示重启。
0.6.0 起换完 jar 会自己重启(auto-restart 默认开),失败自动回滚到备份 jar;
更早的版本换完只会提示你自己执行 stop.sh / start.sh。
本版新增一个配置项 code-association.max-report-impacts(默认 5000,0 或负数表示不截断),
其余配置与历史报告不受影响;被旧缺陷挡住的分析重新发起一次即可。
code-association 0.9.2
code-association 0.9.2
跨程序变更影响扫描工具(Java / Maven 多模块仓库):分析一次提交改动了哪些类、方法、
SQL、MQ 消息结构,并推导出对其他模块 / 服务的连带影响与风险等级。
这一版修好「勾选仓库首次提交就分析失败」:选中的最旧提交没有父提交时,基线按空树处理,
首次提交照常进入评审,不再整次分析报错。
修复:勾选仓库首次提交不再导致分析失败
「提交范围」模式勾选提交时,基线固定取「最旧那个选中提交的父提交」。仓库的首次提交没有父提交,
于是整次分析直接报「选中的提交 xxx 是仓库的第一个提交,没有可比对的父提交」,首次提交因此
完全无法评审——而 GIT_DIFF 把首次提交当作目标时一直是按空树处理的。
现在勾选路径与 GIT_DIFF 一致:基线为空树,首次提交里的内容相对空树都是新增,rangeNote
会注明「最早提交没有父提交,基线为空树」。同时勾选首次提交与其后的提交时,diff 仍只包含
这些提交碰过的文件,中间提交不会混进来。
下载
| 文件 | 说明 |
|---|---|
code-association-0.9.2.jar |
可执行 jar 单文件,应用内「自动更新」用的就是它 |
code-association-0.9.2.zip |
Windows 推荐(自带解压即可,保留 CRLF) |
code-association-0.9.2.tar.gz |
Linux / macOS 推荐 |
两个压缩包内容完全一致,均包含:可执行 jar、start.sh / stop.sh、
start.bat / stop.bat / start.ps1 / stop.ps1、application.yml 示例配置、
README.md、docs/ 与 INSTALL.md。
运行
Linux / macOS
tar -xzf code-association-0.9.2.tar.gz # 或 unzip code-association-0.9.2.zip
cd code-association-0.9.2
chmod +x start.sh stop.sh
./start.sh # 默认 http://127.0.0.1:9996
./stop.shWindows
:: 解压 zip,进入解压目录
start.bat :: 默认 http://127.0.0.1:9996
stop.bat需要 JDK 21+。详见包内 INSTALL.md。
升级说明
从 0.3.0 起可以直接用应用内更新:设置 → 版本与更新 → 应用更新 → 按提示重启。
0.6.0 起换完 jar 会自己重启(auto-restart 默认开),失败自动回滚到备份 jar;
更早的版本换完只会提示你自己执行 stop.sh / start.sh。
本版只有分析行为修复,没有新增配置项;已有配置与历史报告不受影响。被这个缺陷挡住的分析
(勾选了仓库首次提交的那次)重新发起一次即可。
code-association 0.9.1
code-association 0.9.1
跨程序变更影响扫描工具(Java / Maven 多模块仓库):分析一次提交改动了哪些类、方法、
SQL、MQ 消息结构,并推导出对其他模块 / 服务的连带影响与风险等级。
这一版修好「分析卡在 96%」:AI 评审段有了总时间预算并按阶段推进进度;「影响审核」页
合并成一处影响清单,每条证据直接贴出引用行上下 3 行源码;远程代码源名称统一为程序名。
修复:分析不再「卡在 96%」
96% 是 AI 评审段的进度。以前整段只写一次 96%,之后最多十几次串行模型调用没有任何更新,
看起来和卡死一样。现在 AI 段按阶段上报:生成评审要点 → 逐条评审意见 → 分块 i/n →
重定位意见 i/n → 反思意见 → 整理意见,百分比在 96..99 之间推进;100% 仍只由报告落库写入。
新增:AI 段总时间预算
code-association.ai.total-budget-seconds(只写在 application.yml)限制摘要 + 最多十几次评论
调用的总耗时;不写时按 timeout-seconds × 3 推导并夹在 90..900 秒。每次调用把单次超时收缩到
剩余预算内,耗尽后停止剩余调用并保留已生成部分。传输层同时限制整次交换(含 body 读取):
上游发完响应头再停写 body 时,不再能永久挂住一次分析。
预算耗尽只影响这次解释,影响清单、路径与风险结论不变;reviewError 与 reviewStats.notes
会说明「超出时间预算,已保留已生成的部分」。
改进:影响审核页只剩一处影响清单
「对其他程序的影响」不再单独占一张全宽卡:发现列表标题下用一行汇总 pill(每个程序:契约数 /
影响处数),逐条影响只在列表里出现一次;右侧证据面板在未选中发现时展示完整契约命中与对方使用点,
选中后切换为逐跳证据链,并保留「契约命中」按钮回到默认态。两栏在 ≤1180px 折成单列。
新增:证据直接贴出引用行源码
复核页与影响详情页的每条证据、每一跳下方,内联引用行上下各 3 行源码(引用行高亮、超长行截断)。
本程序按报告记录的 head commit 读取,对比程序按分析时记录的 peer commit;纯目录或旧提交已丢失时
退回当前工作区并在片段下注明。GET /api/analyses/{id}/code 只允许读取报告引用过的文件。
改进:远程代码源名称统一为程序名
远程仓库名称取 URL 最后一段(程序名),与本地目录名一致;owner / group 仍在位置里显示。
升级后首次启动只改写「仍等于旧 owner/repo 推导值」的记录,手工命名与本地代码源保持不变。
两个 group 下的同名程序会显示同一个名称,用位置区分。
修复:侧栏选中代码源的图标不再消失
active 行只把条目主图标染成白色;代码源那枚 22px 品牌磁贴固定用 --primary-700,
浅色与深色主题下都可见。
下载
| 文件 | 说明 |
|---|---|
code-association-0.9.1.jar |
可执行 jar 单文件,应用内「自动更新」用的就是它 |
code-association-0.9.1.zip |
Windows 推荐(自带解压即可,保留 CRLF) |
code-association-0.9.1.tar.gz |
Linux / macOS 推荐 |
两个压缩包内容完全一致,均包含:可执行 jar、start.sh / stop.sh、
start.bat / stop.bat / start.ps1 / stop.ps1、application.yml 示例配置、
README.md、docs/ 与 INSTALL.md。
运行
Linux / macOS
tar -xzf code-association-0.9.1.tar.gz # 或 unzip code-association-0.9.1.zip
cd code-association-0.9.1
chmod +x start.sh stop.sh
./start.sh # 默认 http://127.0.0.1:9996
./stop.shWindows
:: 解压 zip,进入解压目录
start.bat :: 默认 http://127.0.0.1:9996
stop.bat需要 JDK 21+。详见包内 INSTALL.md。
升级说明
从 0.3.0 起可以直接用应用内更新:设置 → 版本与更新 → 应用更新 → 按提示重启。
0.6.0 起换完 jar 会自己重启(auto-restart 默认开),失败自动回滚到备份 jar;
更早的版本换完只会提示你自己执行 stop.sh / start.sh。
本版新增可选的 code-association.ai.total-budget-seconds;已有配置与报告不受影响。
远程代码源的名称会在启动时自动收敛为程序名(只改仍等于旧推导值的记录,手工命名不动)。
历史报告不会重写——要看到新的复核页与证据源码,请重新分析一次;旧报告仍可打开,
源码片段会退回当前工作区并在片段下方注明。
code-association 0.9.0
code-association 0.9.0
跨程序变更影响扫描工具(Java / Maven 多模块仓库):分析一次提交改动了哪些类、方法、
SQL、MQ 消息结构,并推导出对其他模块 / 服务的连带影响与风险等级。
这一版新增 GitLab 私有仓库令牌设置,并重做左侧导航与总览影响卡;接口向后兼容。
新增:设置页配置 GitLab 个人访问令牌
私有 GitLab 仓库不再必须先导出 GITLAB_TOKEN 再重启。设置页新增「GitLab 私有仓库」卡片:
粘贴个人访问令牌(PAT,scope 至少 read_repository)保存即生效,克隆、fetch、列分支都使用它;
只对来源类型 GITLAB 生效,GITHUB / GIT / LOCAL_* 不会附加。
令牌存 {data-dir}/gitlab-settings.json(原子写、POSIX 600),GET/PUT /api/gitlab 只回显掩码;
代码源「凭据环境变量」有值时优先,否则回退到设置页令牌或 yml 的 code-association.gitlab.token
(默认读 GITLAB_TOKEN)。自建 GitLab 的 http:// 与 https:// 地址都支持。
改进:单侧栏,默认收起
原来 68px 图标栏 + 268px 文字菜单合成一条 288px 紫色侧栏:展开显示图标 + 标签 + 搜索 +
代码源/状态/最近分析,收起只剩 72px 图标列。默认收起;展开后写入 localStorage 的
ca.nav,下次保持。折叠/展开按钮都在侧栏顶部,状态与 aria-expanded 同步。
改进:总览影响卡合并
「其他程序的待处理影响」与「对其他程序的影响」合并为一张卡:先给每个对比程序一枚
契约数 / 影响处数汇总 pill,再按风险列出前 6 条影响并标注待复核 / 已确认 / 已忽略;
完整的契约命中、使用点与逐跳传播仍在「影响审核」页。
改进:只保留一个添加入口
去掉「代码源」分组标题里重复的加号,只保留侧栏顶部页面标题旁的添加按钮。
下载
| 文件 | 说明 |
|---|---|
code-association-0.9.0.jar |
可执行 jar 单文件,应用内「自动更新」用的就是它 |
code-association-0.9.0.zip |
Windows 推荐(自带解压即可,保留 CRLF) |
code-association-0.9.0.tar.gz |
Linux / macOS 推荐 |
两个压缩包内容完全一致,均包含:可执行 jar、start.sh / stop.sh、
start.bat / stop.bat / start.ps1 / stop.ps1、application.yml 示例配置、
README.md、docs/ 与 INSTALL.md。
运行
Linux / macOS
tar -xzf code-association-0.9.0.tar.gz # 或 unzip code-association-0.9.0.zip
cd code-association-0.9.0
chmod +x start.sh stop.sh
./start.sh # 默认 http://127.0.0.1:9996
./stop.shWindows
:: 解压 zip,进入解压目录
start.bat :: 默认 http://127.0.0.1:9996
stop.bat需要 JDK 21+。详见包内 INSTALL.md。
升级说明
从 0.3.0 起可以直接用应用内更新:设置 → 版本与更新 → 应用更新 → 按提示重启。
0.6.0 起换完 jar 会自己重启(auto-restart 默认开),失败自动回滚到备份 jar;
更早的版本换完只会提示你自己执行 stop.sh / start.sh。
本版新增 code-association.gitlab.token 配置(默认读 GITLAB_TOKEN),已有配置不受影响;
设置页令牌保存在数据目录的 gitlab-settings.json,删除该文件重启即可回退到 yml / 环境变量。
历史报告不会重写——请重新分析一次,新的侧栏、总览与 GitLab 令牌才会生效。
code-association 0.8.0
code-association 0.8.0
跨程序变更影响扫描工具(Java / Maven 多模块仓库):分析一次提交改动了哪些类、方法、
SQL、MQ 消息结构,并推导出对其他模块 / 服务的连带影响与风险等级。
这一版新增两个能力并修掉一类数据库误报。接口向后兼容,AI 相关新增配置项默认开启。
新增:AI 逐条评审意见(行号由本机算)
AI 审核在整段摘要之外新增逐条意见:每条带严重级、类别、标题、正文、建议、代码引用与
文件:行。模型只逐字引用代码,行号由三层定位在本机算出——hunk 文本匹配 → 整文件扫描
→ 模型重定位;三层都失败就丢弃并计数,不猜位置。
误报由两层过滤控制:确定性过滤(送审文件、证据编号、行号范围、白名单、相似评论合并、
上限截断)之后,可选的反思模型只删除与代码事实矛盾的评论;反思失败或解析失败时保留全部。
每一步都有 token 预算:最多 20 个文件、单文件约 4000 tokens、单 chunk 约 8000 tokens、
每 chunk 最多 10 条评论、反思输入约 12000 tokens。
设置页新增「生成逐条评审意见」「每条分析最多评论」「用反思模型过滤误报」三项;
报告新增 ai.comments / ai.reviewStats / ai.reviewError,分析页与 Markdown 导出同步展示。
新增:提交范围改为勾选要分析的提交
「提交范围」不再要求先填一对起止提交:选择分支,可用 since / until 日期缩小范围,
从最新的 100 个提交里勾选本次要分析的那些。接口 GET /api/sources/{id}/commits 新增
since / until 可选参数,响应带 more;换分支或改日期后,不在新列表里的勾选会自动取消。
修复:删除写语句不再被当成「删除数据库字段」
删掉一条 mapper 写语句(或从 SET / INSERT 列清单里去掉某列)时,本程序只是停止写入
该列,列本身仍在数据库里,对方的 SELECT 不会失败。此前它被当成列删除,命中了所有读该列
的对方程序(例如 AuthMapper.getRightLogList 读 igm_card_right_log.error_reason),
是明确误报。现在停止写入某列只计入「对对方不可观察的变更」,不生成跨程序影响。
字段删除只认迁移脚本里显式的 ALTER TABLE ... DROP COLUMN(或列重命名的旧列名);
只是 CREATE TABLE 快照里不再列出该列(改列清单、删建表脚本)不再按删除传播,只计数。
真正的列删除仍会命中对方读方、写方与映射方。
下载
| 文件 | 说明 |
|---|---|
code-association-0.8.0.jar |
可执行 jar 单文件,应用内「自动更新」用的就是它 |
code-association-0.8.0.zip |
Windows 推荐(自带解压即可,保留 CRLF) |
code-association-0.8.0.tar.gz |
Linux / macOS 推荐 |
两个压缩包内容完全一致,均包含:可执行 jar、start.sh / stop.sh、
start.bat / stop.bat / start.ps1 / stop.ps1、application.yml 示例配置、
README.md、docs/ 与 INSTALL.md。
运行
Linux / macOS
tar -xzf code-association-0.8.0.tar.gz # 或 unzip code-association-0.8.0.zip
cd code-association-0.8.0
chmod +x start.sh stop.sh
./start.sh # 默认 http://127.0.0.1:9996
./stop.shWindows
:: 解压 zip,进入解压目录
start.bat :: 默认 http://127.0.0.1:9996
stop.bat需要 JDK 21+。详见包内 INSTALL.md。
升级说明
从 0.3.0 起可以直接用应用内更新:设置 → 版本与更新 → 应用更新 → 按提示重启。
0.6.0 起换完 jar 会自己重启(auto-restart 默认开),失败自动回滚到备份 jar;
更早的版本换完只会提示你自己执行 stop.sh / start.sh。
本版 AI 相关新增 comments / max-comments / reflection 三个配置项,默认开启;
关闭「生成逐条评审意见」即回到只发送分析摘要的模式。历史报告不会重写——请重新分析一次,
逐条评审意见与新的数据库字段删除判定才会出现在报告里。
code-association 0.7.1
code-association 0.7.1
跨程序变更影响扫描工具(Java / Maven 多模块仓库):分析一次提交改动了哪些类、方法、
SQL、MQ 消息结构,并推导出对其他模块 / 服务的连带影响与风险等级。
这一版只修一个误报,不改接口、配置与更新机制。
修复:删除实体字段不再被算成数据库列变化
当本程序删除/修改一个 JPA 实体字段,而对比程序也映射同一列时,0.7.0 会把该命中从
共享的列节点继续传播,把对方所有读该列的 SQL(例如 MyBatis 的
ElectricDeviceMapper.getSwitchDevices)报成 HIGH 的 DATA 影响。实体字段删除并不
改变数据库列,对方的 SQL 与自己的映射都不会坏——这是误报。
现在这类命中只保留为低置信度映射提示:
- 仍然报告「对比程序也映射了同一列」,写入报告说明与计数,避免悄悄丢掉;
- 不再生成跨程序影响项,也不会把该列的其他读写代码拉进影响路径;
- 如果双方通过 Maven 依赖共用同一个模型类,字段删除仍可能造成编译失败,
这种情况请按「Maven 依赖」契约单独确认。
真正的数据库列变化(迁移脚本里的 DROP COLUMN)不受影响:对方读、写、映射该列
的代码仍会正常命中。
下载
| 文件 | 说明 |
|---|---|
code-association-0.7.1.jar |
可执行 jar 单文件,应用内「自动更新」用的就是它 |
code-association-0.7.1.zip |
Windows 推荐(自带解压即可,保留 CRLF) |
code-association-0.7.1.tar.gz |
Linux / macOS 推荐 |
两个压缩包内容完全一致,均包含:可执行 jar、start.sh / stop.sh、
start.bat / stop.bat / start.ps1 / stop.ps1、application.yml 示例配置、
README.md、docs/ 与 INSTALL.md。
运行
Linux / macOS
tar -xzf code-association-0.7.1.tar.gz # 或 unzip code-association-0.7.1.zip
cd code-association-0.7.1
chmod +x start.sh stop.sh
./start.sh # 默认 http://127.0.0.1:9996
./stop.shWindows
:: 解压 zip,进入解压目录
start.bat :: 默认 http://127.0.0.1:9996
stop.bat需要 JDK 21+。详见包内 INSTALL.md。
升级说明
从 0.3.0 起可以直接用应用内更新:设置 → 版本与更新 → 应用更新 → 按提示重启。
0.6.0 起换完 jar 会自己重启(auto-restart 默认开),失败自动回滚到备份 jar;
更早的版本换完只会提示你自己执行 stop.sh / start.sh。
本版不改接口、配置与更新机制;历史报告不会重写——请重新分析一次,0.7.0 里那条
「实体字段删除 → 对方 mapper 读列」的误报不会再出现。
code-association 0.7.0
code-association 0.7.0
跨程序变更影响扫描工具(Java / Maven 多模块仓库):分析一次提交改动了哪些类、方法、
SQL、MQ 消息结构,并推导出对其他模块 / 服务的连带影响与风险等级。
这一版有两个主题。日志可运维:应用日志按天滚动、保留 7 天,关键节点改成可检索的
结构化事件行,进程原始输出单独收集。数据库影响判断继续收紧:一条 ALTER 的多个
动作分别报告;表重命名按旧表名命中;NOT NULL 且无默认值的列开始命中省略它的
INSERT,不再只算「盲区」。
本次重点:日志可运维
- 应用日志统一写到
logs/:code-association.log是 INFO 及以上的完整时间线,
code-association-error.log只收 ERROR,archive/*.log.gz是滚动归档。
目录由code-association.log-dir决定(默认./logs,环境变量LOG_DIR可覆盖),
与数据目录.code-association/分开,日志随时可清空。 - 按天滚动,单文件超过 50MB 再切;只保留 7 天,
cleanHistoryOnStart=true让
「停了一周再启动」也立刻清掉过期归档。主日志上限 500MB、错误日志 200MB,上限先于时间生效。 - 写盘走
AsyncAppender:分析线程不为日志 IO 停顿,队列满时阻塞而不是丢日志;
主日志与错误日志各用一个异步器(AsyncAppender只接受一个appender-ref)。 - 会被反复查询的节点统一写成结构化事件行,例如
event=analysis.done analysisId=42 source=order-service status=DONE durationMs=8421 high=1 medium=3 low=2:
事件名小写点分且稳定,字段 camelCase,每条带定位 id 与durationMs,可直接
grep 'event=analysis.done'或按空白切字段。覆盖分析链路、定时扫描、代码源增删改与
导入导出、版本检查与更新、AI 配置与进程启停。 start.sh/start.ps1的进程原始输出改到logs/console.log(Windows stderr 为
logs/console.err.log),每次启动截断,专收 logback 初始化之前的错误与 JVM 崩溃输出。- 测试不落盘:
logback-test.xml只写控制台,跑测试不会污染logs/。
本次重点:数据库跨程序影响
- 一条
ALTER TABLE的多个动作按动作报告。 以前每种动作只抓第一个:
ADD a INT, ADD b INT只看得到a,ADD a, DROP b甚至把ADD的类型留在
DROP的记录里。现在按顶层逗号拆出全部动作(括号 / 字符串内的逗号不拆),每个动作记
kind / table / column / type / nullable / default / schema / renamedTo;变更检测按
kind|table|column对齐两侧动作,新增、修改、移除各生成一条DDL_CHANGED,
因为加列、删列、改类型对读写方的后果不同,不能共用一条结论。语句级旧字段仍保留第一个
动作,旧索引与旧报告继续可读;ADD INDEX、ADD CONSTRAINT、ENGINE=等非列动作被忽略。 - 表重命名按旧表名的表级契约命中。
ALTER TABLE orders RENAME TO orders_archive
(含顶层RENAME TABLE ... TO ...)现在生成RENAME_TABLE记录:契约写旧表名,
风险种子 0.90,对方读、写、映射旧表的代码都会命中。新表名刻意不产生候选——它是这次
改名才出现的,报它等于把同一次改名算两遍。列重命名也不再额外产生一条
「新列名被当成不可观察加列」的假计数。 NOT NULL且无默认值的列开始命中写入方。 对方一条
INSERT INTO orders (id) VALUES (?)省略了新增必填列,MySQL 严格模式、PostgreSQL、
Oracle 都会拒绝——这是真实不兼容,不该只算盲区。规则只命中完整的INSERT
(非动态 SQL)且列清单里没有该列的语句;UPDATE/DELETE不命中,SELECT *与
动态 SQL 仍计入字段盲区且不重复计数。列可空、有默认值,或由数据库自动填充
(AUTO_INCREMENT/GENERATED/IDENTITY)时都不算必填。- 报告口径:新增「必填列变更」计数与后果说明;这类变更不再同时计入
「对对方不可观察」(否则同一件事既说「对方看不见」又说「对方写入会失败」)。
「不可观察变更」的措辞同步覆盖「移除 DDL 动作」。 - 顺手修掉的解析问题:多语句
.sql中第二条语句的行号曾被算成上一行,导致
sql:文件#行号key 撞车、前一条语句被覆盖;现在按第一条非空白字符计算,多语句脚本的
每个语句都有独立 key。DDL 定义里的DEFAULT 'a,b'不再被顶层逗号拆分。
已知边界
数据库侧仍不分析:写入列集合不变但值语义变了(如 status 1 → 2)、事务与锁顺序、
视图 / 触发器 / 存储过程 / 外键级联、真实数据分布、运行时实际 SQL,以及同一程序
多数据源 / 多 schema 下同名表的快照键冲突。自动填充列只识别 ALTER 列定义文本里的
AUTO_INCREMENT / GENERATED / IDENTITY,触发器、序列等其他机制未识别。
报告的「未发现影响」只表示静态契约层没有找到不兼容证据;SELECT * 与动态 SQL
仍以「字段盲区」列出,需要人工确认。
下载
| 文件 | 说明 |
|---|---|
code-association-0.7.0.jar |
可执行 jar 单文件,应用内「自动更新」用的就是它 |
code-association-0.7.0.zip |
Windows 推荐(自带解压即可,保留 CRLF) |
code-association-0.7.0.tar.gz |
Linux / macOS 推荐 |
两个压缩包内容完全一致,均包含:可执行 jar、start.sh / stop.sh、
start.bat / stop.bat / start.ps1 / stop.ps1、application.yml 示例配置、
README.md、docs/ 与 INSTALL.md。
运行
Linux / macOS
tar -xzf code-association-0.7.0.tar.gz # 或 unzip code-association-0.7.0.zip
cd code-association-0.7.0
chmod +x start.sh stop.sh
./start.sh # 默认 http://127.0.0.1:9996
./stop.shWindows
:: 解压 zip,进入解压目录
start.bat :: 默认 http://127.0.0.1:9996
stop.bat需要 JDK 21+。详见包内 INSTALL.md。
升级说明
从 0.3.0 起可以直接用应用内更新:设置 → 版本与更新 → 应用更新 → 按提示重启。
0.6.0 起换完 jar 会自己重启(auto-restart 默认开),失败自动回滚到备份 jar;
更早的版本换完只会提示你自己执行 stop.sh / start.sh。
0.3.0 及更早的版本没有应用内更新,请手动下载替换 jar(旧 jar 会被备份为 .bak-<版本>,可回滚)。
本版不改接口与更新机制;新增一个可选的日志目录配置 code-association.log-dir
(默认 ./logs,环境变量 LOG_DIR 可覆盖),不设置也能正常启动。
但日志位置有变化:应用日志改到 logs/,启动脚本的进程输出改到 logs/console.log
(Windows 为 logs/console.err.log),旧版写在根目录的 code-association.log 不再更新。
历史报告不会重写——要看到新的判定,请重新分析一次。
code-association 0.6.1
code-association 0.6.1
跨程序变更影响扫描工具(Java / Maven 多模块仓库):分析一次提交改动了哪些类、方法、
SQL、MQ 消息结构,并推导出对其他模块 / 服务的连带影响与风险等级。
这一版没有新功能,全部是 0.6.0「字段级数据库契约」落地之后暴露出来的误报与漏报。
数据库契约的准入条件现在固定为四步:同一数据库对象 → 变更可被观察 → 类型兼容 →
字段级命中。不满足的不扩散,只计数并在报告里说明,或者进「字段盲区」等人确认。
此前「同名表就命中」「加一列和删一列一样严重」这类结果不会再出现。
本次重点:先确认是同一张表
- 契约 key 仍是
表.字段,但匹配前先比较两侧的数据源身份:从
spring.datasource.url/spring.datasource.*.url/spring.datasource.hikari.jdbc-url
解析数据库名,从 SQL 与 DDL 的schema.table读取显式 schema。 - 两侧都已知且同层级不同 → 排除并计数;一侧未知 → 保留匹配但降低置信度;
H2 mem / HSQLDB / Derby / SQLite 视为未知,因为进程内数据库不共享数据。 - 报告会说明有多少候选因数据库不同被排除、多少条因一侧未声明数据库而无法确认同库,
而不是让它们悄悄消失。
本次重点:DDL 按「变更可被观察」分型
- 会扩散:
DROP COLUMN、收窄类型(VARCHAR(64) → VARCHAR(32)、BIGINT → INT)、
类型族变化 → 命中读方、写方、映射方。 - 不扩散只计数:
ADD COLUMN、CREATE TABLE、删除迁移脚本、
类型放宽(VARCHAR(32) → VARCHAR(64)、INT → BIGINT)。加列 / 建表 / 删除迁移脚本
以前是「悄悄消失」,现在报告给出「对对方不可观察的变更」计数与示例。 - 新增
ColumnTypeCompatibility:按字符串长度、整数等级、decimal 精度 / scale、
可空性与安全提升判断兼容性;判断不了就保留命中并降低置信度,不猜。 - decimal 的整数位补上了:
DECIMAL(10,2) → DECIMAL(10,4)的 scale 变大、precision 不变,
但整数位从 8 位降到 6 位,12345678.99放不进去——现在按收窄扩散,不再当成兼容抑制。 - 加列只对
SELECT */ 无列名 INSERT 形成字段盲区;删除迁移脚本不再被当成 schema 回滚。
本次重点:实体映射与数据库 schema 解耦
FIELD_ADDED不再产生数据库 delta;FIELD_REMOVED/FIELD_TYPE_CHANGED
只对同样映射该列的对方代码给出低置信度 mapping 提示,不再命中 SQL 读写方。@Transient、static、集合类型不建列映射;显式@Column/@JoinColumn
优先于隐式命名;隐式命名按 Hibernate 边界转换(userID → user_id、URLPath → url_path)。
本次重点:解析加固
- 解析前剥离 SQL 行注释与块注释:注释掉的
ALTER TABLE ... DROP COLUMN不再生效,
纯注释改动不再产生SQL_CHANGED。 - MySQL 的
#行注释同样识别:#注释里的分号不再把一条 DDL 切成两条。
MyBatis 的#{id}占位符与 PostgreSQL 的#>/#-运算符不受影响。 - 单引号内的反斜杠转义被识别:
'it\'s'不再被当成「字符串到此结束」,
后半句不会被当作 SQL 解析。 - 同一 SQL 从一个 mapper / 迁移文件移到另一个时,按规范化文本配对
SQL_REMOVED与SQL_ADDED并抵消——「文件搬家」不会被读成「本程序停止写这一列」。 - 动态 SQL(
<if>/<choose>/<foreach>/<include>、占位符拼接)不再降级为
表级契约,对方侧改为计入字段盲区。 src/test/下的 mapper、schema.sql、data.sql与迁移脚本不参与生产契约。ADD INDEX/ADD CONSTRAINT/DROP INDEX不再被当成列;INSERT ... SELECT
读取目标列清单;ON DUPLICATE KEY UPDATE不再凭空造出名为status的表。- ALTER / 迁移脚本:识别 PostgreSQL 风格
ALTER COLUMN ... SET/DROP NOT NULL / SET DEFAULT、
ADD/DROP COLUMN IF [NOT] EXISTS、RENAME COLUMN;多动作 ALTER 的类型不再吞掉后续动作;
迁移脚本按数值版本排序(V10 在 V2 后);按引号 / 注释外的分号切分语句;
DDL 只在语句开头识别,字符串字面量里的CREATE TABLE不再污染快照。
报告
- 新增「因数据库不同被排除」「因类型兼容被排除」「对对方不可观察」三组计数与说明。
- 兼容变更与不可观察变更按变更计:此前按「变更 × 对比程序」累加,对比的程序越多,
同一个数字越大。 - 字段盲区口径修正为「读写列都没解析出来或语句不完整」,已作为 writer 命中的纯写语句
不重复计入。 - 文档新增
docs/wiki/数据库影响判断.md:四个准入条件、DDL 分型对照表、类型兼容规则、
字段盲区口径,以及仍然存在的边界(值语义、事务并发、视图 / 触发器 / 存储过程、运行时 SQL)。
下载
| 文件 | 说明 |
|---|---|
code-association-0.6.1.jar |
可执行 jar 单文件,应用内「自动更新」用的就是它 |
code-association-0.6.1.zip |
Windows 推荐(自带解压即可,保留 CRLF) |
code-association-0.6.1.tar.gz |
Linux / macOS 推荐 |
两个压缩包内容完全一致,均包含:可执行 jar、start.sh / stop.sh、
start.bat / stop.bat / start.ps1 / stop.ps1、application.yml 示例配置、
README.md、docs/ 与 INSTALL.md。
运行
Linux / macOS
tar -xzf code-association-0.6.1.tar.gz # 或 unzip code-association-0.6.1.zip
cd code-association-0.6.1
chmod +x start.sh stop.sh
./start.sh # 默认 http://127.0.0.1:9996
./stop.shWindows
:: 解压 zip,进入解压目录
start.bat :: 默认 http://127.0.0.1:9996
stop.bat需要 JDK 21+。详见包内 INSTALL.md。
升级说明
从 0.3.0 起可以直接用应用内更新:设置 → 版本与更新 → 应用更新 → 按提示重启。
0.6.0 起换完 jar 会自己重启(auto-restart 默认开),失败自动回滚到备份 jar;
更早的版本换完只会提示你自己执行 stop.sh / start.sh。
0.3.0 及更早的版本没有应用内更新,请手动下载替换 jar(旧 jar 会被备份为 .bak-<版本>,可回滚)。
这一版只改分析结果,不改接口、配置与更新机制:升级后不需要改 application.yml,
历史报告也不会被重写——要看到新的判定,请重新分析一次。
code-association 0.6.0
code-association 0.6.0
跨程序变更影响扫描工具(Java / Maven 多模块仓库):分析一次提交改动了哪些类、方法、
SQL、MQ 消息结构,并推导出对其他模块 / 服务的连带影响与风险等级。
本次重点:按提交范围评审
新增分析模式 COMMIT_RANGE:起点「起始提交(不含)」与「结束提交(含)」两端明确指定,
用于「这 12 个提交是我要合进去的」这类以提交为单位、而不是以分支名为单位的评审。
- 弹窗选到该模式后,两个输入框变成起始 / 结束提交,输入时给出该仓库的提交下拉
(短 SHA + 提交标题),下方实时预览本次范围包含哪些提交(防抖 300ms,
读取失败只显示一行提示,不打断表单)。 - 新增
GET /api/sources/{id}/commits:只带ref时返回该分支最新提交,
带base+target时返回该范围内的提交,两种形态同一份响应结构。 - 报告新增
commits/commitCount/rangeNote,分析页新增「提交范围」卡片,
PR 评论(--format markdown)在影响明细之前列出本次提交。最多列 200 个
(按提交时间倒序),超出时注明「只列出最新的 N 个」,而不是把截断列表当作全部。 - 范围必须是同一条提交线上的祖先关系:起始提交不在结束提交的历史里时直接拒绝,
并说明是哪一端不成立。否则仍会产出 diff,但那是在比较两个无关快照,
报告会显得正常而实际答非所问。 - 只分析选中的几个提交:预览里每一行都能勾选,勾中的提交才进分析。
基线取最旧那个选中提交的父提交,目标树是选中提交按拓扑从旧到新依次叠加的结果,
所以 diff 恰好只包含它们碰过的文件;跨分支的选择描述的是一个从未存在过的树,
直接拒绝并指出哪个提交不在线上。报告新增selectedCommits。 - 命令行新增
--range <起始>..<结束>,等价于--base+--target并切到
COMMIT_RANGE;范围解析失败改为退出码 2 + 一句人话,
此前是未捕获异常,整段堆栈把原因淹没了。
本次重点:数据库契约的单位从「表」改为「字段」
- 此前只要本程序有一条 SQL 变了,就把这条语句读写的表当成变更契约,对方凡是读写
同一张表的代码全部命中。「给自己多查一个字段」这种纯内部改动,也会把对方所有碰这张表的
模块拉进候选队列,噪声盖住了真正需要通知对方的那几条。 - 现在本程序侧的数据库变更只收三类:表结构变更(DDL)(
ALTER TABLE ... ADD / DROP / MODIFY COLUMN落到具体字段)、写入字段集合变化(INSERT列清单、UPDATE SET列
新增或消失)、实体字段映射变化(@Column映射的 Java 字段新增 / 删除 / 类型变化)。
只改WHERE、JOIN、排序的语句不再产生跨程序数据库影响。 - 匹配侧改为命中对方
db:column:<table>.<column>上的使用点(读 / 写 / 实体映射),
命中条目为DB_COLUMN。只改读取字段集合不扩散:读多少列是本程序的内部行为,
对方的查询不会因此失败。写入字段集合变化只命中读方;表结构变更命中读方与写方。 - 风险种子按操作区分:删字段 / 删表 0.95、改字段类型 0.90、写入字段集合变化 0.85、
加字段 / 建表 0.60。删比加严重:加一列对方按列名读写通常无害,删一列对方照常运行却读到空值。 - 对方写
SELECT *或语句无法解析出列名时不再命中字段级契约,但会计数并在报告里标注
「字段盲区」——「没读到」不能当成「没影响」。
本次重点:AI 审核从「只能改配置文件」变成可选功能
AiExplainer 早已存在,但只能在 application.yml 里配置,生成的 report.ai 前端从未
渲染,历史报告无法补生成,也没有测试连接。现在:
- 设置页新增「AI 审核」卡片:启用开关、接口地址、模型、API Key、每条分析最多送审影响、
请求超时、是否默认生成。「测试连接」发一个只要求模型回pong的最小请求并显示实际端点
与耗时,配置错误的代价从「等一次分析失败」降到一次点击。三个快捷填充
(DeepSeek / OpenAI / Ollama 本地)只填地址与模型,不动 Key。 - 新增
GET /api/ai、PUT /api/ai、POST /api/ai/test、
POST /api/analyses/{id}/ai-review;配置持久化到{data-dir}/ai-settings.json
(原子写,POSIX 下尽量chmod 600)。 apiKey绝不出现在响应、日志与错误信息里,读回的一律是掩码;保存时留空表示不修改,
只有显式clearApiKey才清空。掩码回填的表单若把掩码当明文写回,Key 会在第一次保存后
悄悄失效,而界面上看不出任何异常。- 分析页新增 AI 卡片,按状态给出不同的下一步;正文走既有简易渲染器(模型输出不直接进
innerHTML),上方是随内容一起存下的disclaimer,下方是模型、生成时间与送审条数。 - 失败只影响这张卡:401、超时、响应无法解析都只把原因写进卡片,静态分析结论与
--fail-on
退出码不受影响。命令行新增--ai;未配置时打印一行提示并保持原退出码。 - 关闭(默认)时报告、健康检查与分析流程与改动前完全一致。
本次重点:应用更新后自动重启,失败自动回滚
- 此前的「应用更新」只把新 jar 覆盖到运行位置,然后提示用户自己执行
stop.sh/
start.sh。那不算更新,只算通知——对无人值守的机器等于要求人恰好在线。 - 现在
apply()换完 jar 后把重启交给RestartSupervisor:本进程把一个 POSIX 守护脚本
写到{data-dir}/restart/restart.sh并脱离终端启动它,脚本kill -0等旧 PID 退出
(端口因此自然释放)→ 起新 jar → 轮询GET /api/health→ 超时就用备份 jar 覆盖回去
再拉起一次。 - 本进程延迟约 1.5 秒才退出:延迟是为了让「更新成功」这个 HTTP 响应先写回浏览器。
状态写进{data-dir}/restart-status.json,重启完成后新进程仍能报告
「上一次是成功了还是回滚了」。 - 前端在应用更新后轮询轻量端点
GET /api/update/restart,见到succeeded自动刷新页面,
见到rolled-back显示红色告警与日志路径。 - 新增
auto-restart(默认开)、auto-apply(默认关)、
restart-timeout-seconds(默认 90),以及PUT /api/update/settings供运行时切换。
auto-apply要求auto-restart同时为真:没有热重启的自动应用等于
「自动把服务停掉等人来开」,那不是更新,是故障。
其他新增
- 后台自动更新的进度可见:新增
GET /api/update/progress(phase/bytes/
totalBytes/percent/automatic/message),顶部横幅与设置页各有一条进度条。
总大小未知时走不确定态、只显示已接收字节数,不编造百分比;运行中最多显示 99%,
100% 只属于真正结束的那一步。 - GitHub 网络容错:
api-base-urls多源回退(404 / 401 不降级)、download-mirror、
只作用于更新流量的proxy、指数退避重试(5xx / 408 / 429 与传输失败可重试),
以及全进程共享的RateLimitGate(额度用尽时所有调用方查同一个截止时间)。
全部 host 都失败时,每个 host 的失败原因折叠进warnings展示。 - 界面规范落成文档:新增
docs/wiki/界面规范.md与docs/wiki/界面实现映射.md,
把视觉与交互约定从style.css的注释里搬进可检索、可引用的文档(含按 WCAG 2.1 实算的
对比度结论),并新增UiContractTest把关键令牌、类名双向契约、断点、焦点与
reduced-motion、图标 sprite 引用固化为断言。
修复
- 代码源行的编辑按钮是一块看不见的空白:按钮调
icon('i-edit'),而雪碧图里没有这个
<symbol>;<use>命中不到绘制内容时不报错、不占位,按钮还在、还能点,
只是渲染成什么都没有。改用已有的i-pencil,并新增UiContractTest.IconSprite
逐个核对引用。 - 代码源列表的操作列偏窄,按钮向左压住「同步时间」列:
.tr-sources最后一轨 58px,
而内容要 72px;.cell.actions右对齐,轨道不够时不裁切而是向左溢出。统一改成 76px。 - 编辑保存后的提示恒为「代码源已添加」:
resetSourceModal()在拼提示之前就把
state.editingSourceId清成了null,判断读到的永远是「没在编辑」。 - 编辑代码源后「目录缺失」状态不复位:可用性只在导入时判定一次,把位置改到正确目录后
仍然显示「目录缺失」,还附带一句「导入时目录不存在」。现在编辑保存前显式重判一次。 - 一次分析跑完会把用户在这期间的编辑整行覆盖掉:收尾时用提交那一刻的
RepoSource
快照做整行 UPDATE。现在只更新status / message / last_synced_at三列——
这三列是这次分析产出的,其余列归用户所有。 - 开发模式下「当前运行版本」显示
0.0.0-dev:版本只从运行中的 jar 的 manifest 读,
而mvn spring-boot:run没有 jar。现在构建生成META-INF/build-info.properties兜底。 - 「当前环境不支持自动应用」只写「可能是在 IDE 里启动」:这句话是前端写死的,
最常撞上它的恰恰是终端里的mvn spring-boot:run。现在后端判定启动方式并给出具体原因
与一条可复制的命令,设置页新增「启动方式」一行。 .sql脚本里的 DDL 完全不会产生变更记录:变更识别对.sql直接返回,
用脚本做表结构迁移的项目,加列、删列、删表这些最需要跨程序确认的改动一条都看不到。
现在.sql同样参与比对,产出DDL_CHANGED。stop.bat每次都提示「进程无窗口」并白等 3 秒:java.exe是控制台程序,
主窗口归conhost.exe,MainWindowHandle恒为 0,CloseMainWindow()永远返回
False。现在先判断句柄,没有就直接结束;停止只输出一行「已停止 (PID N)」。
顺带修掉三处会骗人的输出:Stop-Process权限不足时静默失败却照样打印「已停止」
(现在复查并以退出码 1 结束)、结束改用句柄上的Kill()(避免 PID 复用误杀)、
按端口反查到的 PID 也要过Test-ServicePid(此前会把恰好占用该端口的任何程序杀掉)。- 429 带
x-ratelimit-reset时重试与多源回退同时失效:先记录限流截止时间再判断是否重试,
下一轮循环开头的闸门检查立刻把重试打断,连带多源回退也被吃掉,备用源一次都没被请求。
现在限流后不再对该 host 重试,但仍会去问下一个 host。 - 重启状态会自相矛盾(「已回滚」同时「仍在重启」):
state()分别读running标志与
phase,终态 phase 先写、标志后清,轮询落在窗口里就会拿到一个自相矛盾的响应。
现在终态分支先清标志再写状态,running直接由 phase 推导。
下载
| 文件 | 说明 |
|---|---|
code-association-0.6.0.jar |
可执行 jar 单文件,应用内「自动更新」用的就是它 |
code-association-0.6.0.zip |
Windows 推荐(自带解压即可,保留 CRLF) |
code-association-0.6.0.tar.gz |
Linux / macOS 推荐 |
两个压缩包内容完全一致,均包含:可执行 jar、start.sh / stop.sh、
start.bat / stop.bat / start.ps1 / stop.ps1、application.yml 示例配置、
README.md、docs/ 与 INSTALL.md。
运行
Linux / macOS
tar -xzf code-association-0.6.0.tar.gz # 或 unzip code-association-0.6.0.zip
cd code-association-0.6.0
chmod +x start.sh stop.sh
./start.sh # 默认 http://127.0.0.1:9996
./stop.shWindows
:: 解压 zip,进入解压目录
start.bat :: 默认 http://127.0.0.1:9996
stop.bat需要 JDK 21+。详见包内 INSTALL.md。
升级说明
从 0.3.0 起可以直接用应用内更新:设置 → 版本与更新 → 应用更新 → 按提示重启。
0.6.0 起换完 jar 会自己重启(auto-restart 默认开),失败自动回滚到备份 jar;
更早的版本换完只会提示你自己执行 stop.sh / start.sh。
0.3.0 及更早的版本没有应用内更新,请手动下载替换 jar(旧 jar 会被备份为 .bak-<版本>,可回滚)。
code-association 0.5.0
code-association 0.5.0
跨程序变更影响扫描工具(Java / Maven 多模块仓库):分析一次提交改动了哪些类、方法、
SQL、MQ 消息结构,并推导出对其他模块 / 服务的连带影响与风险等级。
本次重点:分析过程进度实时可见
分析详情页在运行期间实时显示阶段、百分比、「第 N / 8 步」,以及当前处理的文件与计数
(如 C215.java (1531/2400)),步骤条随阶段点亮。此前大型仓库上进度会长时间停在
同一个数字,看起来像卡死——修掉了三个原因:
Progress.file收下了to上界却从未使用,索引阶段始终上报from(20%)。
INDEX_HEAD在大型仓库上占用绝大部分墙钟时间,界面于是一整段时间显示同一个数字。
现在按已处理文件数在[from, to)内插值,阶段结束时仍精确落在边界上。- 真正的大头是
CallGraphBuilder.build()的第二次全量遍历,它此前完全不报进度。
两趟遍历现在共用一套计数单位(每文件两个单位),百分比单调上升,不会走到 100% 再回退。 - 从历史记录打开正在运行的分析时只把快照塞进面板、没有订阅它,于是一次渲染后再也不动。
现在打开运行中的分析会重新开始轮询。
本次重点:代码源标签与导入导出
- 代码源标签分类:一个代码源可以打多个标签,左侧菜单按标签分组、每组可折叠,
列表每行显示标签 pill,点一下即按该标签过滤。标签不参与分析,只影响检索与展示。 - 代码源导入导出:设置页新增卡片,用于换机器迁移、团队共享与备份。
按 type + location 判定同一代码源,已存在则合并标签(并集),不存在则新建;
单条非法只记入errors并继续处理其余条目。 - 编辑代码源:列表每行新增编辑按钮,走
PUT /api/sources/{id}。
本次重点:版本检查与自动更新
设置页新增「版本与更新」卡片:当前版本、最新版本、历史版本列表一目了然。
服务会定时向 GitHub 查询 release,不用再手动去发布页翻。
| 入口 | 作用 |
|---|---|
GET /api/update |
当前 / 最新 / 历史版本(带缓存,命中不耗 GitHub 额度) |
POST /api/update/check |
强制重新检查 |
POST /api/update/download |
下载指定版本的 jar 到 {data-dir}/updates/,边下边算 SHA-256 |
POST /api/update/apply |
先备份当前 jar 为 <jar>.bak-<版本>,再替换 |
POST /api/update/rollback |
从最近的备份回滚 |
检查是自动的,替换 jar 需要你点确认。 让程序重启自己会让前端拿不到响应,
也把「什么时候中断服务」的决定权从运维手里拿走了。替换后界面会提示执行
./stop.sh && ./start.sh(Windows 用 stop.bat 再 start.bat)。
三种情况会明确拒绝替换并说明原因:在 IDE 里跑(没有可替换的 jar)、Windows
(运行中的 jar 被系统锁定)、还没下载(无暂存文件)。
关于 GitHub 限流
未认证调用 api.github.com 每小时只有 60 次。默认 6 小时检查一次,够用;
频繁点「立即检查」会撞 403,此时界面会明确说明是限流并给出额度重置时间。
配置 GITHUB_TOKEN(只读 classic token,无需任何 scope)可提到 5000 次/小时。
左侧菜单栏可收起
文字菜单可以折起来只留图标栏,把宽度让给工作区:
- 侧栏右上角的折叠按钮,或图标栏底部收起后出现的展开按钮;
- 快捷键
Ctrl + B/⌘ + B(在输入框里自动让位); - 选择记在浏览器本地,刷新后保持,首帧就按记下的状态渲染。
窄屏(≤860px)默认收起,但仍然可以手动展开——此前该断点把菜单藏死、没有展开入口。
修复
- 重启提示会误判:
apply后要提示「已替换 jar,请重启服务生效」,原判据是
「当前版本 == 已应用版本」。但 JVM 一直报告它启动时的版本,所以「重新应用正在跑的
版本」会被当成「已经重启过」,提示当场消失。改用进程启动时间判断,
status返回startedAt、apply/rollback返回swappedAt,只有前者晚于后者才算重启完成。 release.sh的 jar 校验被 SIGPIPE 误判:unzip -Z1 ... | grep -q在pipefail下
是错的——grep -q命中后立即退出,unzip收到 SIGPIPE 被杀,整条管道返回 141,
于是「校验通过」被当成失败。改为先把清单读进变量再 grep。- 分析失败后看不到任何详情:失败的分析没有报告,而详情页在没有报告时会隐藏
#an-body,进度卡片原先正嵌在这个容器里,于是失败原因被写进一个display:none
的区域——点开一条失败记录,页面显示「暂无数据」和「这个代码源还没有分析记录」。
现在进度/失败卡片移出该容器,失败时单独渲染「失败原因」区块;页面状态改由
选中的分析记录推导,历史列表与总览时间线也直接显示失败原因。 - 仓库里有一个超大文件,就导致该程序的每一次分析全部失败:
GitTreeSource.read把 20MB 写死在loader.getBytes(20 * 1024 * 1024)里,
而 JGit 超限时抛的是LargeObjectException(RuntimeException),原有的
catch (IOException)拦不住,异常一路冒到AnalysisService.run,整次分析被标记为 FAILED。
现在先比loader.getSize()再读,超限即跳过并在报告「跨程序分析边界」里列出文件名与大小。
新增配置max-file-mb(默认 20MB,设为0关闭限制)。
下载
| 文件 | 说明 |
|---|---|
code-association-0.5.0.jar |
可执行 jar 单文件,应用内「自动更新」用的就是它 |
code-association-0.5.0.zip |
Windows 推荐(自带解压即可,保留 CRLF) |
code-association-0.5.0.tar.gz |
Linux / macOS 推荐 |
两个压缩包内容完全一致,均包含:可执行 jar、start.sh / stop.sh、
start.bat / stop.bat / start.ps1 / stop.ps1、application.yml 示例配置、
README.md、docs/ 与 INSTALL.md。
运行
Linux / macOS
tar -xzf code-association-0.5.0.tar.gz # 或 unzip code-association-0.5.0.zip
cd code-association-0.5.0
chmod +x start.sh stop.sh
./start.sh # 默认 http://127.0.0.1:9996
./stop.shWindows
:: 解压 zip,进入解压目录
start.bat :: 默认 http://127.0.0.1:9996
stop.bat需要 JDK 21+。详见包内 INSTALL.md。
升级说明
从 0.3.0 起可以直接用应用内更新:设置 → 版本与更新 → 应用更新 → 按提示重启。
0.3.0 及更早的版本没有这个功能,请手动下载替换 jar(旧 jar 会被备份为 .bak-<版本>,可回滚)。