#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 从 V1 运行包目录读取 lib/ 与 cw_lib/ 的 JAR 清单,并与 V2 Maven 反应堆 `cw-elevator-application-reactor/pom.xml` 中显式声明的版本属性做对照。 用法(在仓库根目录): python3 scripts/compare_v1_v2_elevator_dependencies.py 可选环境变量: V1_ROOT 默认: cw-elevator-application-V1.0.0.20211103 REPO_ROOT 默认: 脚本所在目录的上一级(仓库根) """ from __future__ import annotations import os import re import sys from collections import defaultdict from pathlib import Path def repo_root() -> Path: return Path(__file__).resolve().parents[1] def list_jars(d: Path) -> list[str]: if not d.is_dir(): return [] return sorted(p.name for p in d.glob("*.jar")) def jar_stem_versions(jars: list[str]) -> dict[str, list[str]]: """artifactId -> [version-ish suffixes from filename].""" by_artifact: dict[str, list[str]] = defaultdict(list) for name in jars: if not name.endswith(".jar"): continue base = name[:-4] m = re.match(r"^(.+)-(\d[\d.\w-]*)$", base) if m: by_artifact[m.group(1)].append(m.group(2)) else: by_artifact[base].append("") return dict(by_artifact) def parse_pom_properties(pom: Path) -> dict[str, str]: text = pom.read_text(encoding="utf-8", errors="replace") m = re.search(r"(.*?)", text, re.DOTALL) if not m: return {} block = m.group(1) props = {} for mm in re.finditer(r"<([a-zA-Z0-9_.-]+)>\s*([^<]+?)\s*", block): k, v = mm.group(1), mm.group(2).strip() if k and v and "${" not in v: props[k] = v return props def main() -> int: root = Path(os.environ.get("REPO_ROOT", repo_root())) v1 = root / os.environ.get( "V1_ROOT", "cw-elevator-application-V1.0.0.20211103" ) lib = v1 / "lib" cw = v1 / "cw_lib" pom = root / "maven-cw-elevator-application" / "pom.xml" if not pom.is_file(): print("missing", pom, file=sys.stderr) return 2 jars_lib = list_jars(lib) jars_cw = list_jars(cw) props = parse_pom_properties(pom) print("## V1 目录\n") print(f"- lib: {lib} ({len(jars_lib)} 个 JAR)") print(f"- cw_lib: {cw} ({len(jars_cw)} 个 JAR)\n") print("## V2 反应堆版本属性(节选,与 cw_lib 对齐项)\n") keys = [ "cloudwalk.internal.version", "cloudwalk.legacy.public.version", "intelligent.cwoscomponent.version", "davinci.manager.storage.version", "intelligent.lock.version", "cwos.sdk.resource.version", "cwos.sdk.event.version", "spring-cloud.version", ] for k in keys: if k in props: print(f"- `{k}` → **{props[k]}**") dup = {a: vs for a, vs in jar_stem_versions(jars_lib).items() if len(vs) > 1} print("\n## V1 lib 中「同 artifact 前缀、多版本」示例( Classpath 冲突风险)\n") shown = 0 for art in sorted(dup.keys()): vers = sorted(set(dup[art])) if len(vers) <= 1: continue print(f"- `{art}`: {', '.join(vers)}") shown += 1 if shown >= 25: print("- …(其余略,可对本脚本输出重定向后全文检索)") break print("\n## 与 cw_lib 文件名逐字对照(V2 POM 显式坐标)\n") mapping = [ ("cloudwalk-common-event", "cloudwalk.internal.version"), ("cloudwalk-common-result", "cloudwalk.legacy.public.version"), ("cloudwalk-common-serial", "cloudwalk.legacy.public.version"), ("cloudwalk-common-service", "cloudwalk.internal.version"), ("cloudwalk-common-web", "cloudwalk.legacy.public.version"), ("cloudwalk-intelligent-component-lock", "intelligent.lock.version"), ("davinci-manager-storage", "davinci.manager.storage.version"), ("intelligent-cwoscomponent-rest", "intelligent.cwoscomponent.version"), ("intelligent-cwoscomponent-interface", "intelligent.cwoscomponent.version"), ("cwos-java-sdk-resource", "cwos.sdk.resource.version"), ("cwos-sdk-event", "cwos.sdk.event.version"), ] cw_set = set(jars_cw) for prefix, prop in mapping: ver = props.get(prop, "?") expect = f"{prefix}-{ver}.jar" hit = expect if expect in cw_set else None if not hit: # SNAPSHOT / classifier 简判:取 cw_lib 中以 prefix- 开头的文件 cand = [j for j in jars_cw if j.startswith(prefix + "-")] cand_s = cand[0] if len(cand) == 1 else str(cand) print(f"- **{prefix}**: V2 属性 `{prop}`=`{ver}` → 期望 `{expect}`;V1 cw_lib 实际: `{cand_s}`") else: print(f"- **{prefix}**: V1=`{hit}`,V2 属性 `{prop}`=`{ver}` ✓") print("\n## 电梯自研模块 JAR 版本\n") print( "- V1 cw_lib: `cw-elevator-application-*-**1.0-SNAPSHOT**.jar`(四模块)\n" "- V2 Maven: `cn.cloudwalk.elevator:*:**2.0-SNAPSHOT**`(反应堆版本,与 1.0 并存为正常升级)" ) print("\n完整清单文件: `docs/architecture/data/v1-elevator-lib-jars.txt` 与 `v1-elevator-cw-lib-jars.txt`。") print( "\n生成 **V2 全量传递依赖树** 请在可解析私服的环境执行:\n" " cd maven-cw-elevator-application && " "mvn -pl cw-elevator-application-starter -am dependency:tree " "-DoutputFile=target/v2-starter-dependency-tree.txt" ) return 0 if __name__ == "__main__": raise SystemExit(main())