资讯动态

Renovate 中 Conan 版本策略深度解析:版本区间语法、loose/预发布限定符与 bump、widen、replace 策略的源码实现

发布时间:2026/9/13 11:54:53 来源:尧图企业网站定制
Renovate 中 Conan 版本策略深度解析版本区间语法、loose/预发布限定符与 bump、widen、replace 策略的源码实现【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate本篇指南以 Renovate 仓库中 Conan 版本策略模块versioning module的说明文档为核心完整讲清 Conan 依赖版本区间的语法规则、loose与include_prerelease两个限定符的解析方式以及bump/widen/replace三种区间更新策略在源码中的具体实现。读完后你能理解 Renovate 是如何识别conanfile.txt/conanfile.py中的版本约束、判断新版本是否兼容旧区间并正确改写区间字符串的。模块定位Renovate 版本策略体系中的 conan 实现Renovate 对每种依赖生态都提供一套独立的“版本策略”versioning实现统一的注册入口在 版本策略注册表其中api.set(conan.id, conan.api)将 Conan 策略以标识conan注册进全局 Map。模块说明文档 开宗明义Conan 版本策略支持 Semantic Versioning 2.0但现实中不少 Conan 包并不严格遵守该规范因此 Renovate 的 conan 策略在严格的semver库之上叠加了容错与宽松loose回退机制并实现了 python-node-semver 所定义的区间匹配行为。该策略的关键元信息定义在 conan 策略入口export const id conan; export const displayName conan; export const supportsRanges true; export const supportedRangeStrategies: RangeStrategy[] [ auto, bump, widen, replace, ];即支持版本区间且支持auto、bump、widen、replace四种rangeStrategy取值。对外暴露的 API 包括equals、getMajor/getMinor/getPatch、getNewValue、isCompatible、isGreaterThan、isLessThanRange、isStable、isValid、isVersion、matches、getSatisfyingVersion、minSatisfyingVersion、sortVersions等函数它们共同支撑了 Renovate 的“发现新版本 → 判断升级类型 → 改写区间”全流程。版本区间语法从官方语法表到源码行为原文档 给出了 Conan 版本区间的核心语法表这里完整保留并结合测试用例补充验证依据测试位于 conan 策略测试文件语法含义5.45等价于5.4516.00等价于16.002.8.3等价于2.8.3[1.1 2.1]把版本保持在范围内[2.8]等价于2.8[~3.0]兼容模式compatible符合 SemVer 语义[1.1 \|\| 0.8]条件之间可以用||取或[1.2.7 \|\| 1.2.9 2.0.0]匹配1.2.7、1.2.9、1.4.6但不匹配1.2.8或2.0.0[1.1 2.1, include_prereleaseTrue]例如会接受2.0.0-pre.1这样的匹配[~1.2.3, looseFalse]只接受严格符合 Semantic Versioning 的字符串例如1.2.3.4不会被接受[~1.2.3, looseFalse, include_prereleaseTrue]两个限定符可以在同一个版本区间中同时使用从源码结构看这些语法点分别落在不同的实现文件里方括号[...]、loose、include_prerelease等修饰部分是 Conan 特有的写法由 common.ts 中的cleanVersion()统一剥离它用正则,|\[|\]||include_prerelease|include_prerelease|loose|True|False把这些字符从输入中全部替换为空串再trim()剩下的就是标准的 npm 风格区间可以直接交给semver库处理。~3.0这类兼容运算符源码中实际的运算符形式是~Conan 的兼容范围写法在 range.ts 的replaceRange()中有专门分支if (element.operator ~) return ~ ${major}.${minor}.0。loose与include_prerelease两个限定符的解析集中在getOptions()export function getOptions(input: string): { loose: boolean; includePrerelease: boolean; } { let includePrerelease false; let loose true; if (input) { includePrerelease input.includes(include_prerelease) !input.includes(include_prereleaseFalse); loose input.includes(looseTrue) || !input.includes(looseFalse); } return { loose, includePrerelease }; }注意其中的默认值设计loose默认为trueinclude_prerelease默认为false。也就是说一个不带限定符的区间如[1.1 2.1]走宽松模式[~1.2.3, looseFalse]才启用严格 SemVer 校验——这正是语法表最后一行的行为来源。双轨判断semver 优先、loose 回退conan 策略里几乎每个判断函数都遵循同一个模式先用semver严格库判断失败或不确定时再回退到 loose 版本策略。以equals和isGreaterThan为例index.tsfunction equals(version: string, other: string): boolean { const cleanedVersion cleanVersion(version); const cleanOther cleanVersion(other); const options { loose: true, includePrerelease: true }; const looseResult looseAPI.equals(cleanedVersion, cleanOther); try { return semver.eq(cleanedVersion, cleanOther, options) || looseResult; } catch { return looseResult; } }loose 策略本身是一个“数字段逐位比较、段数少的更小、后缀按 localeCompare 排序”的通用版本比较器见 loose/index.ts它甚至能处理 Conan 世界里常见的四段版本号4.1.3.2。测试文件中专门有一组四段版本用例印证了这一点// test 4-digit ${4.1.3} | ${4} | ${1} | ${3} ${4.1.3.2} | ${4} | ${1} | ${3} ${4.1.3.2-pre.2xxx} | ${4} | ${1} | ${3} ${1.a.2} | ${null} | ${null} | ${null}即getMajor(4.1.3.2) 4、getPatch(4.1.3.2) 3第四段被忽略而不会导致解析失败。isVersion()判断输入是否为“单一版本号”而非区间的入口逻辑也体现了双轨思路index.tsfunction isVersion(input: string): boolean { if (input !input.includes([)) { const qualifiers getOptions(input); const version cleanVersion(input); if (qualifiers.loose looseAPI.isVersion(version)) { return true; } return makeVersion(version, qualifiers) ! null; } return false; }先排除含[的区间字符串loose 模式下只要 loose 策略认为它是版本号即通过严格模式下则交给makeVersion()做 SemVer 校验。关键函数逐个拆解makeVersion预发布版本与四段版本的裁剪common.ts 中的makeVersion()是严格模式下的核心校验函数若版本带预发布标识如1.2.3-pre.1且未开启include_prerelease如果预发布串以数字开头如1.2.3.4被 SemVer 解释为1.2.3 预发布4则裁掉预发布段只返回1.2.3的合法形式否则返回false。若loose为真、严格semver.valid失败且版本段数不等于 3则用semver.coerce()强行归一化后再校验。其余情况直接semver.valid()。这解释了为什么语法表中16.00、5.45这类两位小数的写法都能通过isValid校验而[1.2.3.4, looseFalse]在测试中被判定为false。matches 与 isCompatible 的细微差别两者都接受“版本号 区间”两个参数但语义不同测试用例也验证了差异function matches(version: string, range: string): boolean { if (isVersion(version) isVersion(range)) { return true; } const cleanedVersion cleanVersion(version); const options getOptions(range); const cleanRange cleanVersion(range); return matchesWithOptions(cleanedVersion, cleanRange, options); }matches()最终调用semver.satisfies()并且当区间声明了include_prerelease时会先把带预发布标识的版本coerce成主干版本号再匹配common.ts。而isCompatible()更宽松只要版本号“不早于区间”即!isLessThanRange(version, range)就返回兼容。测试中同一组输入出现了典型差异区间[~1.18]对版本1.20.0isCompatible返回true可以升级进来而matches返回false该版本并不落在~1.18区间内。Renovate 用matches判断“当前版本是否已被区间覆盖”用isCompatible判断“新版本是否可以安全替换”。getMajor / getMinor / getPatch强制包含预发布range.ts 中三个取段函数在注释中都写明“always include prereleases”——它们会先把options.includePrerelease置为true再解析避免1.2.3-rc.1这类版本取段失败。getPatch还额外用semver.coerce()补齐缺失的 patch 段。getSatisfyingVersion 与 minSatisfyingVersion两个“从候选版本列表挑版本”的函数共用 findSatisfyingVersion()遍历候选列表用makeVersion校验 matchesWithOptions匹配再按semver.compare的结果取最大MAX -1或最小MIN 1者。测试展示了include_prerelease开关的实际影响versions: [1.0.0-beta, 1.1.0-beta, 1.0.0] range [1.0.x, looseFalse, include_prereleaseFalse] → null range [1.0.x, looseFalse, include_prereleaseTrue] → 1.0.0-betagetNewValue三种区间更新策略的实现这是 conan 策略最有实战价值的部分。getNewValue()index.ts负责在发现新版本时改写conanfile中的版本字符串其决策顺序为当前值本身就是单一版本号isVersion(currentValue)为真直接返回newVersion无需区间逻辑。通配区间*、*、x、空区间semver.validRange(cleanRange) *时原样返回因为通配区间天然覆盖新版本。按rangeStrategy分派到 widenRange()、bumpRange() 或 replaceRange()。最后用currentValue.replace(cleanRange, newValue)把新区间替换回原字符串的中间部分——这是保留, looseFalse, include_prereleaseTrue]限定符后缀的关键机制。replace 策略按运算符重写replaceRange()逐个运算符处理~生成~ X.Y.0生成新版本~保留~X.Y.0形式带预发布时拼上-rc之类的后缀//按新版本的主次版本递增边界无运算符时处理x、*通配段如[1.0.x]→[1.1.x]。测试用例index.spec.ts中的典型输出currentValue: [1.0.0], newVersion: 2.1.0 → [3.0.0] currentValue: [1.0.*], newVersion: 1.1.0 → [1.1.*] currentValue: [~0.6], newVersion: 0.7.0 → [~0.7.0] currentValue: [~0.6.1], newVersion: 0.7.0-rc.2 → [~ 0.7.0]widen 策略能扩则扩否则用||追加widenRange()的逻辑是若新版本已经满足旧区间则原样返回若区间以结尾则把上界推高[1.2.3]1.5.6→[1.5.7]若是1.0.0 - 2.0.0这类横杠区间则扩展右端点以结尾的复合区间会记录警告Complex ranges ending in greater than are not supported并放弃其余情况直接||追加新版本[1.2.7] 0.1.24 → [1.2.7 || 0.1.24] [1.2.3] 1.2.3 → [1.2.3] 已覆盖保持不变bump 策略保持区间“形态”不变地滚动bumpRange()针对单元素区间按运算符原地滚动~运算符按原区间段数重写[~1]→[~2]、[~1.0]→[~1.1]、[~1.0.0]→[~1.1.7]下移下界[1.0.0]1.1.0→[1.1.0]上界类区间直接返回原值上界不需要跟着小版本走||连接的裸版本列表则委托给 widen 追加[3.17.2 || 3.15.7]3.21.3→[3.17.2 || 3.15.7 || 3.21.3]。多元素复合区间会先经fixParsedRange()拆分为带运算符的片段该函数会专门保护||两侧的裸版本不被误改再对每个片段递归 bump 或 replace最后用空格拼接还原——例如[ 0.0.1 1]1.0.1得到[ 1.0.1 2]。而限定符保留机制在 bump 用例中体现得最清楚~8.4.0, looseFalse bump 8.5.0 → [~8.5.0, looseFalse] ~1.0 include_prereleaseTrue bump 1.21.1 → [~1.21 include_prereleaseTrue]因为替换只作用于cleanVersion之后的中间区间串looseFalse、include_prereleaseTrue等尾部限定符得以原样保留。与 Conan 管理器manager的联动版本策略必须与提取依赖的管理器配合才能发挥作用。Renovate 的 conan 管理器 声明了以下关键配置export const supportsLockFileMaintenance true; export const lockFileNames [conan.lock]; export const categories: Category[] [c]; export const defaultConfig { managerFilePatterns: [/(^|/)conanfile\\.(txt|py)$/], datasource: ConanDatasource.id, versioning: conan.id, // 指向本文剖析的 versioning/conan 模块 };按 管理器说明文档 描述的工作流程Renovate 在仓库中查找conanfile.txt或conanfile.py从conanfile.txt的[requires]、[build_requires]段落以及conanfile.py的requirements()、build_requirements()函数和python_requires、requires、build_requires变量中提取依赖通过 Conan v2 API 解析最新版本发现更新后回写conanfile.txt/conanfile.py若存在conan.lock也一并更新锁文件维护已委派给包管理器执行。管理器还通过 getRangeStrategy() 规定了默认策略行为export function getRangeStrategy({ rangeStrategy, }: RangeConfig): RangeStrategy { return rangeStrategy auto ? bump : rangeStrategy!; }即用户未显式指定时conan 管家的auto等价于bump——默认倾向“保持区间形态滚动”而非“||追加”。这也解释了为什么 conan 策略的supportedRangeStrategies里包含auto。小结与使用建议Conan 版本策略模块lib/modules/versioning/conan在 SemVer 2.0 基础上叠加了loose宽松回退与四段版本号支持能覆盖不符合严格规范的 Conan 包版本。区间限定符loose默认True控制是否接受非严格 SemVer 字符串include_prerelease默认False控制预发布版本是否参与匹配与升级两者可组合使用。getNewValue是区间改写的总入口单一版本号直接替换、通配区间不动、其余按replace/bump/widen策略处理且改写只替换区间中间段从而保留原限定符。在 Renovate 配置中若使用 conan 管家rangeStrategy设为auto时实际执行bump需要“区间只增不减”的行为可显式配置widen需要精确钉住版本可配置replace。所有行为均可在 conan 策略测试文件 中找到逐条对应的断言用例适合在定制或排错时作为行为基准查阅。【免费下载链接】renovateHome of the Renovate CLI: Cross-platform Dependency Automation by Mend.io项目地址: https://gitcode.com/GitHub_Trending/re/renovate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价