#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" V1_DIR="${ROOT_DIR}/cw-elevator-application-V1.0.0.20211103" V2_DIR="${ROOT_DIR}/maven-cw-elevator-application/deploy/v2-maven" V2_RELEASES_DIR="${ROOT_DIR}/maven-cw-elevator-application/releases" V1_JAR="${V1_DIR}/cw-elevator-application-V1.0.0.20211103.jar" V2_JAR="" for candidate in $(ls -1t "${V2_RELEASES_DIR}"/v*/cw-elevator-application-*.jar 2>/dev/null || true); do if [[ -f "${candidate}" ]]; then V2_JAR="${candidate}" break fi done if [[ -z "${V2_JAR}" ]]; then for candidate in $(ls -1t "${V2_DIR}"/cw-elevator-application-*.jar 2>/dev/null || true); do if [[ -f "${candidate}" ]]; then V2_JAR="${candidate}" break fi done fi if [[ ! -f "${V1_JAR}" ]]; then echo "ERROR: V1 jar not found: ${V1_JAR}" >&2 exit 1 fi if [[ -z "${V2_JAR}" || ! -f "${V2_JAR}" ]]; then echo "ERROR: V2 jar not found under ${V2_DIR}" >&2 exit 1 fi python3 - "$V1_DIR" "$V2_DIR" "$V1_JAR" "$V2_JAR" <<'PY' import subprocess import sys from pathlib import Path v1_dir = Path(sys.argv[1]) v2_dir = Path(sys.argv[2]) v1_jar = Path(sys.argv[3]) v2_jar = Path(sys.argv[4]) files = [ "bootstrap.properties", "application.properties", "application-access-control.properties", ] keys = [ "spring.cloud.consul.host", "spring.cloud.consul.port", "spring.cloud.consul.discovery.enabled", "spring.cloud.consul.config.enabled", "feign.cwos-portal.name", "feign.ninca-common.name", "feign.component-organization.name", ] def parse_properties(text): result = {} for raw_line in text.splitlines(): line = raw_line.strip() if not line or line.startswith("#") or line.startswith("!"): continue if "=" in line: k, v = line.split("=", 1) elif ":" in line: k, v = line.split(":", 1) else: continue result[k.strip()] = v.strip() return result def read_external(dir_path, name): p = dir_path / name if not p.exists(): return None return parse_properties(p.read_text(encoding="utf-8", errors="ignore")) def read_jar(jar_path, name): try: out = subprocess.check_output( ["jar", "tf", str(jar_path)], text=True, errors="ignore", ).splitlines() except subprocess.CalledProcessError: return None candidates = [] suffix = "/" + name for item in out: if item == name or item.endswith(suffix): candidates.append(item) if not candidates: return None preferred = None for c in candidates: if c.startswith("BOOT-INF/classes/"): preferred = c break if preferred is None: preferred = candidates[0] try: content = subprocess.check_output( ["unzip", "-p", str(jar_path), preferred], text=True, errors="ignore", ) except subprocess.CalledProcessError: return None return parse_properties(content) def describe_source(external_map, internal_map, key): ext_val = None if external_map is None else external_map.get(key) int_val = None if internal_map is None else internal_map.get(key) if ext_val is not None: return "external", ext_val if int_val is not None: return "jar-internal", int_val return "unset", "" def report_version(tag, base_dir, jar_path): print(f"\n==== {tag} ====") print(f"base_dir: {base_dir}") print(f"jar: {jar_path}") ext_maps = {name: read_external(base_dir, name) for name in files} int_maps = {name: read_jar(jar_path, name) for name in files} print("\n[1] 配置文件存在性") for name in files: ext_exists = ext_maps[name] is not None int_exists = int_maps[name] is not None print(f"- {name}: external={'Y' if ext_exists else 'N'}, jar={'Y' if int_exists else 'N'}") print("\n[2] 关键键值最终命中来源(按常见优先级:external > jar)") merged_ext = {} merged_int = {} for name in files: if ext_maps[name]: merged_ext.update(ext_maps[name]) if int_maps[name]: merged_int.update(int_maps[name]) for key in keys: src, val = describe_source(merged_ext, merged_int, key) print(f"- {key}: source={src}, value={val}") print("\n[3] 加载顺序结论") has_any_internal = any(int_maps[name] is not None for name in files) if has_any_internal: print("- 该版本具备 jar 内置配置兜底。") else: print("- 该版本无 jar 内置配置兜底,依赖 external/远端配置。") print("- 在未显式传 --spring.config.location 时,外部同名配置通常优先于 jar 内置。") report_version("V1", v1_dir, v1_jar) report_version("V2", v2_dir, v2_jar) print("\n==== 总结对比 ====") print("- V1: external + jar 内置(有兜底)") v2_internal = any(read_jar(v2_jar, name) is not None for name in files) if v2_internal: print("- V2: external + jar 内置(有兜底)") else: print("- V2: external 优先,当前样本无 jar 内置同名配置(无兜底)") print("- 若 external 与远端配置中心并存,最终以运行时属性源优先级为准。") PY