PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/mvndep.py

http://github.com/hudec/sql-processor
Python | 1236 lines | 1147 code | 67 blank | 22 comment | 219 complexity | cf3b12819299b8be498ccbb10e53e46e MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. #! /usr/bin/env python3
  2. import json
  3. import os, subprocess, argparse, re
  4. from dateutil.parser import parse
  5. import requests
  6. # from lxml import html
  7. FIX_PROPERTIES_UNUSED_VERSIONS = 'unused'
  8. FIX_LIBS_LATEST_COMMON_VERSIONS = 'llibs'
  9. FIX_LIBS_SET_VERSIONS = 'libs'
  10. FIX_LIBS_FROM_REPO = 'rlibs'
  11. FIX_PARENTS_SET_VERSIONS = 'parents'
  12. FIX_PARENTS_FROM_REPO = 'rparents'
  13. FIX_PLUGINS_SET_VERSION = 'plugins'
  14. FIX_PLUGINS_FROM_REPO = 'rplugins'
  15. ACTIONS = [FIX_PROPERTIES_UNUSED_VERSIONS,
  16. FIX_LIBS_LATEST_COMMON_VERSIONS,
  17. FIX_LIBS_SET_VERSIONS,
  18. FIX_LIBS_FROM_REPO,
  19. FIX_PARENTS_SET_VERSIONS,
  20. FIX_PARENTS_FROM_REPO,
  21. FIX_PLUGINS_SET_VERSION,
  22. FIX_PLUGINS_FROM_REPO]
  23. CONFIG_FILENAME = '.mvndep.json'
  24. POM_NAME = 'pom.xml'
  25. SUBST_VER_RE = re.compile(r'{(?P<version>.+)}')
  26. VER_RE = re.compile(r'<version>(?P<version>.+)</version>')
  27. PROPS_START_RE = re.compile(r'<properties>')
  28. PROPS_END_RE = re.compile(r'</properties>')
  29. PROPS_VERSION_RE = re.compile(r'<version(?P<name>.+)>.+</version.+>')
  30. PARENT_START_RE = re.compile(r'<parent>')
  31. PARENT_END_RE = re.compile(r'</parent>')
  32. GROUP_ID_RE = re.compile(r'<groupId>(?P<group>.+)</groupId>')
  33. ARTIFACT_ID_RE = re.compile(r'<artifactId>(?P<artifact>.+)</artifactId>')
  34. VERSION_RE = re.compile(r'<version>(?P<version>.+)</version>')
  35. VERSION_DATE_TIME_RE = re.compile(r'<a href="(?P<version>.+)/">(?P<version2>.+)/</a>.+(?P<date_time>\d\d\d\d-\d\d-\d\d \d\d:\d\d).+')
  36. VERSION_DATE_TIME_AF_RE = re.compile(r'<a href="(?P<version>.+)/">(?P<version2>.+)/</a>.+(?P<date_time>\d?\d-\S\S\S-\d\d\d\d \d\d:\d\d).+')
  37. FOR_PROJECT_RE = re.compile(r'\[INFO].+@ (?P<project>[\S]+)')
  38. MODULES_START_RE = re.compile(r'<modules>')
  39. REPOS = ['https://repo1.maven.org/maven2/',
  40. 'https://oss.sonatype.org/content/groups/public/'
  41. ]
  42. REPO2 = ['https://repo1.maven.org/maven2/org/apache/maven/plugins/',
  43. 'https://repo1.maven.org/maven2/org/codehaus/mojo/',
  44. 'https://repo1.maven.org/maven2/org/codehaus/gmaven/',
  45. 'https://central.maven.org/maven2/org/jvnet/jaxb2/maven2/',
  46. 'https://central.maven.org/maven2/com/spotify/',
  47. 'https://central.maven.org/maven2/org/apache/cxf/',
  48. 'https://central.maven.org/maven2/org/springframework/boot/',
  49. 'https://central.maven.org/maven2/org/apache/tomcat/maven/'
  50. ]
  51. class Version:
  52. def __init__(self, str_version):
  53. self.vers = []
  54. self.rest = []
  55. self.version = str_version
  56. _vers = str_version.split('.')
  57. for _ver in _vers:
  58. if len(self.rest) > 0:
  59. self.rest.append(_ver)
  60. continue
  61. if _ver.isdigit():
  62. self.vers.append(int(_ver))
  63. continue
  64. start = ''
  65. end = ''
  66. for c in _ver:
  67. if len(end) == 0 and c.isdigit():
  68. start = start + c
  69. else:
  70. end = end + c
  71. if len(start) > 0:
  72. self.vers.append(int(start))
  73. if len(end) > 0:
  74. self.rest.append(end)
  75. def compare(self, version):
  76. 'test, if this version is newer than version in parameter'
  77. # print(self.vers, self.rest, version.vers, version.rest)
  78. if self.version == version.version:
  79. return False
  80. mlen = min(len(self.vers), len(version.vers))
  81. for i in range(0, mlen):
  82. if self.vers[i] > version.vers[i]:
  83. return True
  84. if self.vers[i] < version.vers[i]:
  85. return False
  86. if len(self.vers) > len(version.vers):
  87. return True
  88. if len(self.vers) < len(version.vers):
  89. return False
  90. mlen = min(len(self.rest), len(version.rest))
  91. for i in range(0, mlen):
  92. if self.rest[i] > version.rest[i]:
  93. return True
  94. if self.rest[i] < version.rest[i]:
  95. return False
  96. if len(self.rest) > len(version.rest):
  97. return True
  98. if len(self.rest) < len(version.rest):
  99. return False
  100. return False
  101. def __hash__(self):
  102. return hash(self.version)
  103. def __eq__(self, other):
  104. return self.version == other.version
  105. def __str__(self):
  106. return self.version
  107. def __repr__(self):
  108. return str(self)
  109. class Library:
  110. def __init__(self, str_library):
  111. items = str_library.split(':')
  112. if len(items) < 1:
  113. raise ValueError('%s should be groupId:artifactId:version, the required is at least groupId or artifactId' % (str))
  114. self.groupId = items[0]
  115. self.artifactId = None if len(items) <= 1 else items[1]
  116. self.version = None if len(items) <= 2 else items[2]
  117. self.library = str_library
  118. def __hash__(self):
  119. return hash(self.library)
  120. def __eq__(self, other):
  121. return self.library == other.library
  122. def __str__(self):
  123. return self.library
  124. def __repr__(self):
  125. return str(self)
  126. class Libraries:
  127. def __init__(self, libs):
  128. self.map_group_artifact_version = {}
  129. self.map_artifact_version = {}
  130. self.map_group_artifact = {}
  131. self.set_group = set([])
  132. for lib in libs:
  133. self.__add_lib(lib)
  134. def __add_lib(self, str_library):
  135. lib = Library(str_library)
  136. if lib.groupId and lib.artifactId and lib.version:
  137. self.map_group_artifact_version[lib.groupId + '.' + lib.artifactId] = lib.version
  138. elif lib.artifactId and lib.version:
  139. self.map_artifact_version[lib.artifactId] = lib.version
  140. elif lib.groupId and lib.artifactId:
  141. self.map_group_artifact[lib.groupId] = lib.artifactId
  142. else:
  143. self.set_group.add(lib.groupId)
  144. def contains_and_version(self, str_library):
  145. if str_library in self.map_group_artifact_version:
  146. return True, self.map_group_artifact_version[str_library]
  147. if str_library in self.map_artifact_version:
  148. return True, self.map_artifact_version[str_library]
  149. items = str_library.split('.')
  150. artifactId = items[-1]
  151. items = items[0:-1]
  152. groupId = '.'.join(items)
  153. if groupId in self.set_group:
  154. return True, None
  155. if groupId in self.map_group_artifact:
  156. return True, None
  157. if groupId + '.' + artifactId in self.map_group_artifact_version:
  158. return True, self.map_group_artifact_version[groupId + '.' + artifactId]
  159. return False, None
  160. @staticmethod
  161. def skip(libs, str_library):
  162. if not libs:
  163. return False
  164. result = libs.contains_and_version(str_library)
  165. if result[0]:
  166. return True
  167. return False
  168. @staticmethod
  169. def process(libs, str_library):
  170. if not libs:
  171. return True
  172. result = libs.contains_and_version(str_library)
  173. if result[0]:
  174. return True
  175. return False
  176. @staticmethod
  177. def version(libs, str_library):
  178. if not libs:
  179. return None
  180. result = libs.contains_and_version(str_library)
  181. if result[0]:
  182. return result[1]
  183. return None
  184. def __str__(self):
  185. return 'g-a-v: ' + str(self.map_group_artifact_version) + '\na-v: ' + str(self.map_artifact_version) + '\ng-a: ' + str(self.map_group_artifact) + '\ng: ' + str(self.set_group)
  186. def __repr__(self):
  187. return str(self)
  188. def read_pom(path, name=None):
  189. if name:
  190. fname = os.path.join(path, name, POM_NAME)
  191. else:
  192. fname = os.path.join(path, POM_NAME)
  193. print("<- %s" % fname)
  194. with open(fname, 'r') as file:
  195. return file.readlines()
  196. def read_poms(cfg, path, depth=1, pom=None):
  197. map_project_pom = {}
  198. map_project_path = {}
  199. print('in ', path)
  200. if pom:
  201. lines = read_pom(path)
  202. group_id, artifact_id = find_main_in_pom(lines)
  203. map_project_pom[artifact_id] = lines
  204. map_project_path[artifact_id] = os.path.join(path)
  205. for entry in os.scandir(path):
  206. if not entry.name.startswith('.') and entry.is_dir():
  207. if POM_NAME in os.listdir(entry.path):
  208. if cfg.projects and not entry.name in cfg.projects:
  209. continue
  210. if cfg.skip_projects and entry.name in cfg.skip_projects:
  211. continue
  212. lines = read_pom(path, entry.name)
  213. group_id, artifact_id = find_main_in_pom(lines)
  214. map_project_pom[artifact_id] = lines
  215. map_project_path[artifact_id] = os.path.join(path, entry.name)
  216. if depth > 1:
  217. for project in list(map_project_pom.keys()):
  218. _map_project_pom, _map_project_path = read_poms(cfg, map_project_path[project], depth - 1)
  219. map_project_pom.update(_map_project_pom)
  220. map_project_path.update(_map_project_path)
  221. return map_project_pom, map_project_path
  222. def write_pom(path, pom, skip_lines=None):
  223. fname = os.path.join(path, POM_NAME)
  224. print("-> %s" % fname)
  225. with open(fname, 'w') as file:
  226. for linenum, line in enumerate(pom):
  227. if skip_lines and linenum in skip_lines:
  228. continue
  229. file.write(line)
  230. def write_poms(map_project_pom, map_project_path, skip_lines=None):
  231. for project in map_project_pom:
  232. if skip_lines:
  233. write_pom(map_project_path[project], map_project_pom[project], skip_lines[project])
  234. else:
  235. write_pom(map_project_path[project], map_project_pom[project])
  236. return map_project_pom
  237. def maven_anc_line(cfg, line, map_anc_versions_main):
  238. if line.startswith("[INFO] Ancestor"):
  239. line_ok = line[22:]
  240. line_ok_arr = line_ok.split(" <-")
  241. if cfg.verbosity >= 2:
  242. print("-- %s" % line_ok_arr[0])
  243. cols = line_ok_arr[0].split(":")
  244. lib = cols[0] + '.' + cols[1]
  245. version = cols[2]
  246. map_anc_versions_main[lib] = [Version(version)]
  247. def maven_dep_line(cfg, line, map_lib_versions_main, map_lib_versions):
  248. if line.startswith('[INFO] |') or line.startswith('[INFO] +') or line.startswith('[INFO] \\'):
  249. line_ok = line[7:]
  250. if line_ok.startswith('+-') or line_ok.startswith('\-'):
  251. if cfg.verbosity >= 2:
  252. print("== %s" % line_ok[3:])
  253. cols = line_ok[3:].split(":")
  254. scope = cols[4 if len(cols) == 5 else 5]
  255. if cfg.skip_scopes and scope in cfg.skip_scopes:
  256. return
  257. if cfg.scopes and scope not in cfg.scopes:
  258. return
  259. lib = cols[0] + '.' + cols[1]
  260. version = cols[3 if len(cols) == 5 else 4]
  261. map_lib_versions_main[lib] = [Version(version)]
  262. else:
  263. line_ok = line_ok[line_ok.find('-'):]
  264. if cfg.verbosity >= 2:
  265. print("-- %s" % line_ok[2:])
  266. cols = line_ok[2:].split(":")
  267. scope = cols[4 if len(cols) == 5 else 5]
  268. if cfg.skip_scopes and scope in cfg.skip_scopes:
  269. return
  270. if cfg.scopes and scope not in cfg.scopes:
  271. return
  272. lib = cols[0] + '.' + cols[1]
  273. version = cols[3 if len(cols) == 5 else 4]
  274. if lib in map_lib_versions:
  275. map_lib_versions[lib] = map_lib_versions[lib] + [Version(version)]
  276. else:
  277. map_lib_versions[lib] = [Version(version)]
  278. def maven_dep_pom(cfg, path, pom=None):
  279. map2_project_lib_versions_main = {}
  280. map2_project_lib_versions = {}
  281. map_lib_versions_main = {}
  282. map_lib_versions = {}
  283. project = None
  284. if pom:
  285. pipe = subprocess.Popen(['mvn', '-f', pom, 'dependency:tree'], cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  286. else:
  287. pipe = subprocess.Popen(['mvn', 'dependency:tree'], cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  288. text = pipe.communicate()[0].decode("utf-8")
  289. # print(text)
  290. for line in text.split("\n"):
  291. if line.find('[ERROR]') >= 0:
  292. print(line)
  293. continue
  294. result = FOR_PROJECT_RE.search(line)
  295. if result:
  296. print(line)
  297. if project:
  298. map2_project_lib_versions_main[project] = map_lib_versions_main
  299. map2_project_lib_versions[project] = map_lib_versions
  300. map_lib_versions_main = {}
  301. map_lib_versions = {}
  302. project = result.group('project')
  303. if cfg.projects and not project in cfg.projects:
  304. project = None
  305. if cfg.skip_projects and project in cfg.skip_projects:
  306. project = None
  307. print("project %s" % (project))
  308. else:
  309. maven_dep_line(cfg, line, map_lib_versions_main, map_lib_versions)
  310. if project:
  311. map2_project_lib_versions_main[project] = map_lib_versions_main
  312. map2_project_lib_versions[project] = map_lib_versions
  313. return (map2_project_lib_versions_main, map2_project_lib_versions)
  314. def maven_anc_pom(cfg, path, pom=None):
  315. map2_project_lib_versions_main = {}
  316. map_lib_versions_main = {}
  317. project = None
  318. if pom:
  319. pipe = subprocess.Popen(['mvn', '-f', pom, 'dependency:display-ancestors'], cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  320. else:
  321. pipe = subprocess.Popen(['mvn', 'dependency:display-ancestors'], cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  322. text = pipe.communicate()[0].decode("utf-8")
  323. # print(text)
  324. for line in text.split("\n"):
  325. if line.find('[ERROR]') >= 0:
  326. print(line)
  327. continue
  328. result = FOR_PROJECT_RE.search(line)
  329. if result:
  330. print(line)
  331. if project:
  332. map2_project_lib_versions_main[project] = map_lib_versions_main
  333. map_lib_versions_main = {}
  334. project = result.group('project')
  335. if cfg.projects and not project in cfg.projects:
  336. project = None
  337. if cfg.skip_projects and project in cfg.skip_projects:
  338. project = None
  339. print("project %s" % (project))
  340. else:
  341. maven_anc_line(cfg, line, map_lib_versions_main)
  342. if project:
  343. map2_project_lib_versions_main[project] = map_lib_versions_main
  344. return (map2_project_lib_versions_main)
  345. def maven_anc_tree(cfg, path):
  346. map2_project_lib_versions_main = {}
  347. for entry in os.scandir(path):
  348. if not entry.name.startswith('.') and entry.is_dir():
  349. if POM_NAME in os.listdir(entry.path):
  350. if cfg.projects and not entry.name in cfg.projects:
  351. continue
  352. if cfg.skip_projects and entry.name in cfg.skip_projects:
  353. continue
  354. print("dir %s" % (entry.path))
  355. _map2_project_lib_versions_main = maven_anc_pom(cfg, entry.path, None)
  356. if cfg.verbosity >= 2:
  357. print(_map2_project_lib_versions_main)
  358. map2_project_lib_versions_main.update(_map2_project_lib_versions_main)
  359. return (map2_project_lib_versions_main)
  360. def maven_dep_tree(cfg, path):
  361. map2_project_lib_versions_main = {}
  362. map2_project_lib_versions = {}
  363. for entry in os.scandir(path):
  364. if not entry.name.startswith('.') and entry.is_dir():
  365. if POM_NAME in os.listdir(entry.path):
  366. if cfg.projects and not entry.name in cfg.projects:
  367. continue
  368. if cfg.skip_projects and entry.name in cfg.skip_projects:
  369. continue
  370. print("dir %s" % (entry.path))
  371. _map2_project_lib_versions_main, _map2_project_lib_versions = maven_dep_pom(cfg, entry.path, None)
  372. if cfg.verbosity >= 2:
  373. print(_map2_project_lib_versions_main)
  374. print(_map2_project_lib_versions)
  375. map2_project_lib_versions_main.update(_map2_project_lib_versions_main)
  376. map2_project_lib_versions.update(_map2_project_lib_versions)
  377. return (map2_project_lib_versions_main, map2_project_lib_versions)
  378. def maven_ancestors(cfg):
  379. if cfg.pom:
  380. return maven_anc_pom(cfg, cfg.dir, cfg.pom)
  381. else:
  382. return maven_anc_tree(cfg, cfg.dir)
  383. def maven_dependencies(cfg):
  384. if cfg.pom:
  385. return maven_dep_pom(cfg, cfg.dir, cfg.pom)
  386. else:
  387. return maven_dep_tree(cfg, cfg.dir)
  388. def maven_plug_line(cfg, line, map_lib_versions_main):
  389. if line.startswith('[INFO] Plugin Resolved'):
  390. line_ok = line[24:]
  391. if cfg.verbosity >= 2:
  392. print("== %s" % line_ok)
  393. cols = line_ok.split("-")
  394. version = cols[-1][:-4]
  395. del cols[-1]
  396. # lib = 'org.apache.maven.plugins.' + '-'.join(cols)
  397. lib = '-'.join(cols)
  398. map_lib_versions_main[lib] = [Version(version)]
  399. def maven_plug_pom(cfg, path, pom=None):
  400. map2_project_lib_versions_main = {}
  401. map_lib_versions_main = {}
  402. project = None
  403. if pom:
  404. if cfg.exclude_artifacts:
  405. pipe = subprocess.Popen(['mvn', '-f', pom, 'dependency:resolve-plugins', '-DexcludeArtifactIds=' + ','.join(cfg.exclude_artifacts)], cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  406. else:
  407. pipe = subprocess.Popen(['mvn', '-f', pom, 'dependency:resolve-plugins'], cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  408. else:
  409. if cfg.exclude_artifacts:
  410. pipe = subprocess.Popen(['mvn', 'dependency:resolve-plugins', '-DexcludeArtifactIds=' + ','.join(cfg.exclude_artifacts)], cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  411. else:
  412. pipe = subprocess.Popen(['mvn', 'dependency:resolve-plugins'], cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  413. text = pipe.communicate()[0].decode("utf-8")
  414. # print(text)
  415. for line in text.split("\n"):
  416. if line.find('[ERROR]') >= 0:
  417. print(line)
  418. continue
  419. result = FOR_PROJECT_RE.search(line)
  420. if result:
  421. if project:
  422. map2_project_lib_versions_main[project] = map_lib_versions_main
  423. map_lib_versions_main = {}
  424. project = result.group('project')
  425. if cfg.projects and not project in cfg.projects:
  426. project = None
  427. if cfg.skip_projects and project in cfg.skip_projects:
  428. project = None
  429. print("project %s" % (project))
  430. else:
  431. maven_plug_line(cfg, line, map_lib_versions_main)
  432. if project:
  433. map2_project_lib_versions_main[project] = map_lib_versions_main
  434. return map2_project_lib_versions_main
  435. def maven_plug_tree(cfg, path):
  436. map2_project_lib_versions_main = {}
  437. for entry in os.scandir(path):
  438. if not entry.name.startswith('.') and entry.is_dir():
  439. if POM_NAME in os.listdir(entry.path):
  440. if cfg.projects and not entry.name in cfg.projects:
  441. continue
  442. if cfg.skip_projects and entry.name in cfg.skip_projects:
  443. continue
  444. print("dir %s" % (entry.path))
  445. _map2_project_lib_versions_main = maven_plug_pom(cfg, entry.path, None)
  446. if cfg.verbosity >= 2:
  447. print(_map2_project_lib_versions_main)
  448. map2_project_lib_versions_main.update(_map2_project_lib_versions_main)
  449. return map2_project_lib_versions_main
  450. def maven_plugins(cfg):
  451. if cfg.pom:
  452. return maven_plug_pom(cfg, cfg.dir, cfg.pom)
  453. else:
  454. return maven_plug_tree(cfg, cfg.dir)
  455. def merge_libs(cfg, map2_project_lib_versions, map2_lib_version_projects=None):
  456. if not map2_lib_version_projects:
  457. map2_lib_version_projects_new = {}
  458. else:
  459. map2_lib_version_projects_new = map2_lib_version_projects.copy()
  460. for project in map2_project_lib_versions.keys():
  461. for lib, vers in map2_project_lib_versions[project].items():
  462. for ver in vers:
  463. if cfg.verbosity >= 2:
  464. print("%s - %s - %s" % (project, lib, ver))
  465. if lib in map2_lib_version_projects_new:
  466. ver_projects = map2_lib_version_projects_new[lib]
  467. if ver in ver_projects:
  468. ver_projects[ver] = ver_projects[ver] + [project]
  469. else:
  470. ver_projects[ver] = [project]
  471. else:
  472. map2_lib_version_projects_new[lib] = {ver : [project]}
  473. return map2_lib_version_projects_new
  474. def dump_libs_usage(text, map2_lib_version_projects_main, _all=True):
  475. print("-> %s " % text)
  476. libs = list(map2_lib_version_projects_main.keys())
  477. libs.sort()
  478. for lib in libs:
  479. map_version_projects = map2_lib_version_projects_main[lib]
  480. if _all:
  481. if len(map_version_projects) > 1:
  482. print("%s = %s ****" % (lib, map_version_projects))
  483. else:
  484. print("%s = %s" % (lib, map_version_projects))
  485. else:
  486. if (len(map_version_projects) > 1):
  487. print("%s = %s" % (lib, map_version_projects))
  488. def find_value_in_pom(pom, value):
  489. str_re = re.compile('<' + value + '>(?P<value>.+)</' + value + '>')
  490. for linenum, line in enumerate(pom):
  491. result = str_re.search(line)
  492. if result:
  493. return linenum, result.group('value')
  494. return None, None
  495. def find_artifact_in_pom(pom, artifact, from_linenum=None):
  496. artifact_re = re.compile('<artifactId>' + artifact + '</artifactId>')
  497. found_line, prev_line, next_line = None, None, None
  498. found_linenum = None
  499. for linenum, line in enumerate(pom):
  500. if from_linenum:
  501. if linenum <= from_linenum + 1:
  502. continue
  503. if found_line:
  504. next_line = line
  505. break
  506. if artifact_re.search(line):
  507. found_line = line
  508. found_linenum = linenum
  509. else:
  510. prev_line = line
  511. return found_linenum, found_line, prev_line, next_line
  512. def find_version_in_pom(pom, found_linenum, found_line, prev_line, next_line):
  513. result = SUBST_VER_RE.search(next_line)
  514. if result:
  515. version = result.group('version')
  516. return find_value_in_pom(pom, version)
  517. result = SUBST_VER_RE.search(prev_line)
  518. if result:
  519. version = result.group('version')
  520. return find_value_in_pom(pom, version)
  521. result = VER_RE.search(next_line)
  522. if result:
  523. return found_linenum + 1, result.group('version')
  524. result = VER_RE.search(prev_line)
  525. if result:
  526. return found_linenum - 1, result.group('version')
  527. return None, None
  528. def find_versions_in_pom(pom):
  529. found_props = False
  530. map_verprop_linenum = {}
  531. for linenum, line in enumerate(pom):
  532. if found_props:
  533. if PROPS_END_RE.search(line):
  534. break
  535. result = PROPS_VERSION_RE.search(line)
  536. if result:
  537. map_verprop_linenum['version' + result.group('name')] = linenum
  538. if PROPS_START_RE.search(line):
  539. found_props = True
  540. return map_verprop_linenum
  541. def unused_versions_in_pom(pom, map_verprop_linenum):
  542. unused_pom_versions = dict(map_verprop_linenum)
  543. pom_versions_unused = map_verprop_linenum
  544. for verprop in pom_versions_unused.keys():
  545. verprop_re = re.compile('{' + verprop + '}')
  546. for line in pom:
  547. if verprop_re.search(line):
  548. unused_pom_versions.pop(verprop)
  549. break
  550. return unused_pom_versions
  551. def find_main_in_pom(pom):
  552. group_id, artifact_id = None, None
  553. for line in pom:
  554. if group_id and artifact_id:
  555. break
  556. if MODULES_START_RE.search(line):
  557. break
  558. if PROPS_START_RE.search(line):
  559. break
  560. result = GROUP_ID_RE.search(line)
  561. if result:
  562. group_id = result.group('group')
  563. continue
  564. result = ARTIFACT_ID_RE.search(line)
  565. if result:
  566. artifact_id = result.group('artifact')
  567. continue
  568. return group_id, artifact_id
  569. def find_parent_in_pom(pom):
  570. found_parent = False
  571. group_id, artifact_id, version, version_line = None, None, None, None
  572. for index, line in enumerate(pom):
  573. if found_parent:
  574. if PARENT_END_RE.search(line):
  575. break
  576. result = GROUP_ID_RE.search(line)
  577. if result:
  578. group_id = result.group('group')
  579. continue
  580. result = ARTIFACT_ID_RE.search(line)
  581. if result:
  582. artifact_id = result.group('artifact')
  583. continue
  584. result = VERSION_RE.search(line)
  585. if result:
  586. version = result.group('version')
  587. version_line = index
  588. continue
  589. if PARENT_START_RE.search(line):
  590. found_parent = True
  591. return group_id, artifact_id, version, version_line
  592. def find_versions_maven_central(cfg, lib):
  593. list_ver_datetime = []
  594. if lib.startswith('cz.'):
  595. return list_ver_datetime
  596. # print('1111', lib)
  597. for repo in cfg.remote_urls:
  598. url = repo + lib.replace('.', '/') + '/'
  599. # print('2222', url)
  600. try:
  601. req = requests.get(url)
  602. except Exception as ex:
  603. print('For', url, 'there is error:', ex)
  604. return list_ver_datetime
  605. # print('2222b', req.status_code)
  606. if req.status_code == 200:
  607. break
  608. if req.status_code != 200:
  609. for repo in cfg.remote_urls:
  610. url = repo + lib.replace('.', '/') + '/'
  611. ix = url[:-1].rfind('/')
  612. if ix < 0:
  613. continue
  614. url = url[:ix] + '.' + url[ix + 1:]
  615. # print('3333', url)
  616. req = requests.get(url)
  617. # print('3333b', req.status_code)
  618. if req.status_code == 200:
  619. break
  620. if req.status_code != 200:
  621. print("Not found ", lib)
  622. return list_ver_datetime
  623. # print(req.content)
  624. lines = str(req.content).split('\\n')
  625. # tree = html.fromstring(req.content)
  626. # hrefs = tree.xpath('/html/body//a/@href')
  627. for line in lines:
  628. result = VERSION_DATE_TIME_RE.search(line)
  629. if result:
  630. version = result.group('version2')
  631. date_time = result.group('date_time')
  632. if version.startswith('.') or version.startswith('maven'):
  633. continue
  634. if version.endswith('/'):
  635. version = version[0:-1]
  636. list_ver_datetime.append((version, date_time))
  637. else:
  638. result = VERSION_DATE_TIME_AF_RE.search(line)
  639. if result:
  640. version = result.group('version2')
  641. date_time = result.group('date_time')
  642. if version.startswith('.') or version.startswith('maven'):
  643. continue
  644. if version.endswith('/'):
  645. version = version[0:-1]
  646. dt = parse(date_time)
  647. list_ver_datetime.append((version, str(dt)))
  648. return list_ver_datetime
  649. central_maven_incorrect_datetimes = set(['commons-lang.commons-lang'])
  650. def compare_based_on_version(lib):
  651. return True
  652. def is_valid_lib(lib):
  653. if lib.startswith('200'):
  654. return False
  655. if lib.lower().find('alpha') >= 0 or lib.lower().find('beta') >= 0 or lib.lower().find('incubat') >= 0 or lib.lower().find('mistake') >= 0 or lib.find('-M') >= 0:
  656. return False
  657. return True
  658. def find_latest_maven_central(cfg, lib):
  659. list_ver_datetime = find_versions_maven_central(cfg, lib)
  660. if not list_ver_datetime:
  661. return None
  662. if compare_based_on_version(lib):
  663. latest_version, latest_datetime = None, None
  664. for ver_datetime in list_ver_datetime:
  665. if not latest_version:
  666. if is_valid_lib(ver_datetime[0]):
  667. latest_version = Version(ver_datetime[0])
  668. latest_datetime = ver_datetime[1]
  669. elif is_valid_lib(ver_datetime[0]):
  670. version = Version(ver_datetime[0])
  671. if version.compare(latest_version):
  672. latest_version = version
  673. latest_datetime = ver_datetime[1]
  674. if latest_version:
  675. print('find_latest_maven_central lib=%s, ver=%s from %s' % (lib, latest_version, latest_datetime))
  676. return latest_version.version
  677. else:
  678. print('not find_latest_maven_central lib=%s' % (lib))
  679. return None
  680. else:
  681. latest_version, latest_datetime = None, None
  682. for ver_datetime in list_ver_datetime:
  683. if not latest_datetime or ver_datetime[1] > latest_datetime:
  684. latest_version = ver_datetime[0]
  685. latest_datetime = ver_datetime[1]
  686. print('find_latest_maven_central lib=%s, ver=%s from %s' % (lib, latest_version, latest_datetime))
  687. return latest_version
  688. def find_pom_for_artifact_version(lib, project, map_project_pom, map_project_parents):
  689. pom = map_project_pom[project]
  690. _lib = lib.split('.')[-1]
  691. found_linenum, found_line, prev_line, next_line = find_artifact_in_pom(pom, _lib)
  692. if found_line:
  693. # print('found_line ', found_line, end = '')
  694. # print('prev_line ', prev_line, end = '')
  695. # print('next_line ', next_line, end = '')
  696. version_linenum, version = find_version_in_pom(pom, found_linenum, found_line, prev_line, next_line)
  697. if not version:
  698. found_linenum, found_line, prev_line, next_line = find_artifact_in_pom(pom, _lib, found_linenum)
  699. if found_line:
  700. version_linenum, version = find_version_in_pom(pom, found_linenum, found_line, prev_line, next_line)
  701. if version:
  702. return project, pom, version_linenum, version
  703. if not project in map_project_parents:
  704. return None, None, None, None
  705. for parent in map_project_parents[project]:
  706. pom = map_project_pom[parent]
  707. found_linenum, found_line, prev_line, next_line = find_artifact_in_pom(pom, _lib)
  708. if found_line:
  709. # print('found_line2 ', found_line, end = '')
  710. # print('prev_line2 ', prev_line, end = '')
  711. # print('next_line2 ', next_line, end = '')
  712. version_linenum, version = find_version_in_pom(pom, found_linenum, found_line, prev_line, next_line)
  713. if not version:
  714. found_linenum, found_line, prev_line, next_line = find_artifact_in_pom(pom, _lib, found_linenum)
  715. if found_line:
  716. version_linenum, version = find_version_in_pom(pom, found_linenum, found_line, prev_line, next_line)
  717. if version:
  718. return parent, pom, version_linenum, version
  719. return None, None, None, None
  720. def fix_latest_versions_in_poms(cfg, map_project_pom, map_project_parents, map2_lib_version_projects):
  721. map_project_pom_fixed = {}
  722. libs = list(map2_lib_version_projects.keys())
  723. libs.sort()
  724. for lib in libs:
  725. if len(map2_lib_version_projects[lib]) <= 1:
  726. continue
  727. if Libraries.skip(cfg.skip_libs, lib):
  728. continue
  729. if not Libraries.process(cfg.libs, lib):
  730. continue
  731. # print("%s = %s" % (lib, map2_lib_version_projects[lib]))
  732. latest_version = None
  733. for version, projects in map2_lib_version_projects[lib].items():
  734. if not latest_version or version.compare(latest_version):
  735. latest_version = version
  736. for version, projects in map2_lib_version_projects[lib].items():
  737. if latest_version == version:
  738. continue
  739. print("FIX for %s version %s -> %s in %s" % (lib, version, latest_version, projects))
  740. for project in projects:
  741. if not project in map_project_pom:
  742. print('??? Missing ' + project + ' in ', map_project_pom.keys())
  743. continue
  744. project_version, pom_version, version_linenum, version = find_pom_for_artifact_version(lib, project, map_project_pom, map_project_parents)
  745. if not version:
  746. print("Not found artifactId (or version) %s in %s nor in it's parents" % (lib.split('.')[-1], project))
  747. continue
  748. # print("Found version for artifactId %s in %s" % (lib.split('.')[-1], project_version))
  749. if version == latest_version.version:
  750. print("FIXED line %d: %s -> %s in %s" % (version_linenum, version, latest_version, project_version))
  751. else:
  752. print("TOFIX line %d: %s -> %s in %s" % (version_linenum, version, latest_version.version, project_version))
  753. print(pom_version[version_linenum], end="")
  754. if cfg.fix >= 2:
  755. pom_version[version_linenum] = pom_version[version_linenum].replace(version, latest_version.version)
  756. map_project_pom_fixed[project_version] = pom_version
  757. print(pom_version[version_linenum], end="")
  758. return map_project_pom_fixed
  759. def update_libraries_in_poms(cfg, map_project_pom, map_project_parents, map2_lib_version_projects, central_libs):
  760. map_project_pom_fixed = {}
  761. libs = list(map2_lib_version_projects.keys())
  762. libs.sort()
  763. for lib in libs:
  764. if Libraries.skip(cfg.skip_libs, lib):
  765. continue
  766. if central_libs:
  767. if not Libraries.process(cfg.libs, lib):
  768. continue
  769. if not lib in central_libs:
  770. continue
  771. new_version = central_libs[lib]
  772. else:
  773. new_version = Libraries.version(cfg.libs, lib)
  774. if not new_version:
  775. continue
  776. # print("%s = %s" % (lib, map2_lib_version_projects[lib]))
  777. for version, projects in map2_lib_version_projects[lib].items():
  778. if new_version == version.version:
  779. continue
  780. print("FIX for %s version %s -> %s in %s" % (lib, version, new_version, projects))
  781. for project in projects:
  782. if not project in map_project_pom:
  783. print('??? Missing ' + project + ' in ', map_project_pom.keys())
  784. continue
  785. project_version, pom_version, version_linenum, version = find_pom_for_artifact_version(lib, project, map_project_pom, map_project_parents)
  786. if not version:
  787. print("Not found artifactId (or version) %s in %s nor in it's parents" % (lib.split('.')[-1], project))
  788. continue
  789. # print("Found version for artifactId %s in %s" % (lib.split('.')[-1], project_version))
  790. if version == new_version:
  791. print("FIXED line %d: %s -> %s in %s" % (version_linenum, version, new_version, project_version))
  792. else:
  793. print("TOFIX line %d: %s -> %s in %s" % (version_linenum, version, new_version, project_version))
  794. print(pom_version[version_linenum], end="")
  795. if cfg.fix >= 2:
  796. pom_version[version_linenum] = pom_version[version_linenum].replace(version, new_version)
  797. map_project_pom_fixed[project_version] = pom_version
  798. print(pom_version[version_linenum], end="")
  799. return map_project_pom_fixed
  800. def update_parent_in_poms(cfg, map_project_pom, central_ancs=None):
  801. map_project_pom_fixed = {}
  802. for project, pom in map_project_pom.items():
  803. group_id, artifact_id, version, version_line = find_parent_in_pom(pom)
  804. if group_id and artifact_id and version and version_line:
  805. lib = group_id + "." + artifact_id
  806. if central_ancs:
  807. if lib in central_ancs:
  808. new_version = central_ancs[lib]
  809. else:
  810. new_version = None
  811. else:
  812. new_version = Libraries.version(cfg.libs, lib)
  813. if new_version:
  814. print("TOFIX line %d: %s -> %s in %s" % (version_line, version, new_version, project))
  815. print(pom[version_line], end="")
  816. if cfg.fix >= 2:
  817. pom[version_line] = pom[version_line].replace(version, new_version)
  818. map_project_pom_fixed[project] = pom
  819. print(pom[version_line], end="")
  820. return map_project_pom_fixed
  821. def build_pom_hierarchy(map_project_path):
  822. map_project_parents = {}
  823. main_project = None
  824. for project, path in map_project_path.items():
  825. if path == '.':
  826. main_project = project
  827. for project, path in map_project_path.items():
  828. # print(project, ': ', path)
  829. path_list = path.split(os.sep)
  830. path_list.reverse()
  831. # print(path_list)
  832. parents = []
  833. project_first = True
  834. for _project in path_list:
  835. if project_first:
  836. project_first = False
  837. if _project != '.':
  838. continue
  839. if _project == '.':
  840. if main_project:
  841. parents.append(main_project)
  842. else:
  843. parents.append(_project)
  844. if parents:
  845. map_project_parents[project] = parents
  846. # print(map_project_parents)
  847. return map_project_parents
  848. class Config:
  849. def __init__(self):
  850. self.default_skip_projects = []
  851. self.default_skip_libs = []
  852. self.default_skip_scopes = []
  853. self.default_pom = None
  854. self.default_depth = 1
  855. self.default_exclude_artifacts = []
  856. self.default_remote_urls = []
  857. if os.path.isfile(CONFIG_FILENAME):
  858. with open(CONFIG_FILENAME, encoding='utf-8') as config_file:
  859. default_config = json.loads(config_file.read())
  860. if 'skip_projects' in default_config:
  861. self.default_skip_projects = default_config['skip_projects']
  862. print("default skip projects", self.default_skip_projects)
  863. if 'skip_libs' in default_config:
  864. self.default_skip_libs = default_config['skip_libs']
  865. print("default skip libs", self.default_skip_libs)
  866. if 'skip_scopes' in default_config:
  867. self.default_skip_scopes = default_config['skip_scopes']
  868. print("default skip scopes", self.default_skip_scopes)
  869. if 'pom' in default_config:
  870. self.default_pom = default_config['pom']
  871. print("default pom", self.default_pom)
  872. if 'depth' in default_config:
  873. self.default_depth = default_config['depth']
  874. print("default depth", self.default_depth)
  875. if 'exclude_artifacts' in default_config:
  876. self.default_exclude_artifacts = default_config['exclude_artifacts']
  877. print("default exclude artifacts", self.default_exclude_artifacts)
  878. if 'remote_urls' in default_config:
  879. self.default_remote_urls = default_config['remote_urls']
  880. print("default remote urls", self.default_remote_urls)
  881. parser = argparse.ArgumentParser(description='Analyze Maven projects.')
  882. parser.add_argument('-d', '--dir', metavar='dir', default='.',
  883. help='directory to scan for the Maven projects (default: the working directory)')
  884. parser.add_argument('-p', '--projects', metavar='project', nargs='+',
  885. help='the Maven projects to analyze (default: all projects in selected directory)')
  886. parser.add_argument('-P', '--skip_projects', metavar='project', nargs='+', default=self.default_skip_projects,
  887. help='the Maven projects to skip')
  888. parser.add_argument('-v', '--verbosity', action='count', default=0,
  889. help='the verbosity of debug output')
  890. parser.add_argument('-f', '--fix', action='count', default=0,
  891. help='fix the Maven projects\' to the latest libraries\' version')
  892. parser.add_argument('-t', '--type', default=FIX_LIBS_LATEST_COMMON_VERSIONS, choices=ACTIONS,
  893. help='fix the Maven projects\' to the latest libraries\' version')
  894. parser.add_argument('-s', '--scopes', metavar='scope', nargs='+',
  895. help='the Maven scopes to work with')
  896. parser.add_argument('-S', '--skip_scopes', metavar='scope', nargs='+', default=self.default_skip_scopes,
  897. help='the Maven scopes to skip')
  898. parser.add_argument('-l', '--libs', dest='_libs', metavar='library', nargs='+',
  899. help='the list of libraries to process (in the form groupId:artifactId:version)')
  900. parser.add_argument('-L', '--skip_libs', dest='_skip_libs', metavar='library', nargs='+', default=self.default_skip_libs,
  901. help='the list of libraries to skip (in the form groupId:artifactId:version)')
  902. parser.add_argument('--pom', metavar='pom', default=self.default_pom,
  903. help='the parent (main) pom.xml used instead of directory scanning')
  904. parser.add_argument('--depth', type=int, default=self.default_depth,
  905. help='the depth of directories to scan for pom.xml')
  906. parser.add_argument('-X', '--exclude_artifacts', dest='exclude_artifacts', metavar='artifact', nargs='+', default=self.default_exclude_artifacts,
  907. help='the list of artifacts to exclude (right now only plugins)')
  908. parser.add_argument('-r', '--remote', dest='_remote_urls', metavar='url', nargs='+', default=self.default_remote_urls,
  909. help='consult the remote (central) maven repositories')
  910. parser.parse_args(namespace=self)
  911. self.libs = None if not self._libs else Libraries(self._libs)
  912. self.skip_libs = None if not self._skip_libs else Libraries(self._skip_libs)
  913. print("selected directory %s" % self.dir)
  914. print("selected projects %s" % self.projects)
  915. print("skip projects %s" % self.skip_projects)
  916. print("selected scopes %s" % self.scopes)
  917. print("skip scopes %s" % self.skip_scopes)
  918. print("libraries %s" % self.libs)
  919. print("skip libraries %s" % self.skip_libs)
  920. print("verbosity %d" % self.verbosity)
  921. print("fix %d" % self.fix)
  922. print("type %s" % self.type)
  923. print("pom %s" % self.pom)
  924. print("depth %d" % self.depth)
  925. print("exclude_artifacts %s" % self.exclude_artifacts)
  926. print("remote urls %s" % self._remote_urls)
  927. if self.type == FIX_PLUGINS_FROM_REPO:
  928. self.remote_urls = REPO2 + self._remote_urls
  929. else:
  930. self.remote_urls = REPOS + self._remote_urls
  931. def main():
  932. cfg = Config()
  933. if cfg.type == FIX_LIBS_LATEST_COMMON_VERSIONS:
  934. map2_project_lib_versions_main, map2_project_lib_versions = maven_dependencies(cfg)
  935. if cfg.verbosity >= 1:
  936. print(map2_project_lib_versions_main)
  937. print(map2_project_lib_versions)
  938. map2_lib_version_projects_main = merge_libs(cfg, map2_project_lib_versions_main)
  939. if cfg.fix == 0:
  940. print("-------------------------------------------------------")
  941. dump_libs_usage("Main dependencies", map2_lib_version_projects_main)
  942. map2_lib_version_projects = merge_libs(cfg, map2_project_lib_versions, map2_lib_version_projects_main)
  943. if cfg.fix == 0:
  944. print("-------------------------------------------------------")
  945. dump_libs_usage("Conflict dependencies", map2_lib_version_projects, False)
  946. print("-------------------------------------------------------")
  947. if cfg.fix >= 1:
  948. map_project_pom, map_project_path = read_poms(cfg, cfg.dir, cfg.depth, cfg.pom)
  949. if cfg.verbosity >= 3:
  950. print(map_project_pom)
  951. print(map_project_path)
  952. map_project_parents = build_pom_hierarchy(map_project_path)
  953. map_project_pom_fixed = fix_latest_versions_in_poms(cfg, map_project_pom, map_project_parents, map2_lib_version_projects)
  954. if cfg.fix >= 2:
  955. write_poms(map_project_pom_fixed, map_project_path)
  956. elif cfg.type == FIX_LIBS_SET_VERSIONS and cfg.libs:
  957. map2_project_lib_versions_main, map2_project_lib_versions = maven_dependencies(cfg)
  958. if cfg.verbosity >= 1:
  959. print(map2_project_lib_versions_main)
  960. map2_lib_version_projects_main = merge_libs(cfg, map2_project_lib_versions_main)
  961. if cfg.verbosity >= 3:
  962. print(map2_lib_version_projects_main)
  963. map_project_pom, map_project_path = read_poms(cfg, cfg.dir, cfg.depth, cfg.pom)
  964. if cfg.verbosity >= 3:
  965. print(map_project_pom)
  966. print(map_project_path)
  967. map_project_parents = build_pom_hierarchy(map_project_path)
  968. map_project_pom_fixed = update_libraries_in_poms(cfg, map_project_pom, map_project_parents, map2_lib_version_projects_main, None)
  969. if cfg.fix >= 2:
  970. write_poms(map_project_pom_fixed, map_project_path)
  971. elif cfg.type == FIX_PROPERTIES_UNUSED_VERSIONS:
  972. map_project_pom, map_project_path = read_poms(cfg, cfg.dir, cfg.depth, cfg.pom)
  973. if cfg.verbosity >= 3:
  974. print(map_project_pom)
  975. print(map_project_path)
  976. map_project_parents = build_pom_hierarchy(map_project_path)
  977. map_project_linenums_unused = {}
  978. for project, pom in map_project_pom.items():
  979. map_verprop_linenum = find_versions_in_pom(pom)
  980. map_project_linenums_unused[project] = list(unused_versions_in_pom(pom, map_verprop_linenum).values())
  981. if map_project_linenums_unused and cfg.fix >= 2:
  982. write_poms(map_project_pom, map_project_path, map_project_linenums_unused)
  983. else:
  984. print(map_project_linenums_unused)
  985. elif cfg.type == FIX_PARENTS_SET_VERSIONS and cfg.libs:
  986. map_project_pom, map_project_path = read_poms(cfg, cfg.dir, cfg.depth, cfg.pom)
  987. if cfg.verbosity >= 3:
  988. print(map_project_pom)
  989. print(map_project_path)
  990. map_project_parents = build_pom_hierarchy(map_project_path)
  991. map_project_pom_fixed = update_parent_in_poms(cfg, map_project_pom)
  992. if cfg.fix >= 2:
  993. write_poms(map_project_pom_fixed, map_project_path)
  994. elif cfg.type == FIX_LIBS_FROM_REPO:
  995. map2_project_lib_versions_main, map2_project_lib_versions = maven_dependencies(cfg)
  996. if cfg.verbosity >= 1:
  997. print("---map2_project_lib_versions_main-----------------------------------------------------------------------------------------------------------")
  998. print(map2_project_lib_versions_main)
  999. print("---map2_project_lib_versions-----------------------------------------------------------------------------------------------------------")
  1000. print(map2_project_lib_versions)
  1001. map2_lib_version_projects_main = merge_libs(cfg, map2_project_lib_versions_main)
  1002. if cfg.verbosity >= 3:
  1003. print("---map2_lib_version_projects_main-----------------------------------------------------------------------------------------------------------")
  1004. print(map2_lib_version_projects_main)
  1005. central_libs = {}
  1006. for lib in map2_lib_version_projects_main.keys():
  1007. latest_version = find_latest_maven_central(cfg, lib)
  1008. if latest_version:
  1009. central_libs[lib] = latest_version
  1010. if cfg.verbosity >= 2:
  1011. print("---central_libs-----------------------------------------------------------------------------------------------------------")
  1012. print(central_libs)
  1013. if cfg.fix >= 1:
  1014. map_project_pom, map_project_path = read_poms(cfg, cfg.dir, cfg.depth, cfg.pom)
  1015. if cfg.verbosity >= 3:
  1016. print("---map_project_pom-----------------------------------------------------------------------------------------------------------")
  1017. print(map_project_pom)
  1018. print("---map_project_path-----------------------------------------------------------------------------------------------------------")
  1019. print(map_project_path)
  1020. map_project_parents = build_pom_hierarchy(map_project_path)
  1021. if cfg.verbosity >= 3:
  1022. print("---map_project_parents-----------------------------------------------------------------------------------------------------------")
  1023. print(map_project_parents)
  1024. map_project_pom_fixed = update_libraries_in_poms(cfg, map_project_pom, map_project_parents, map2_lib_version_projects_main, central_libs)
  1025. if cfg.fix >= 2:
  1026. write_poms(map_project_pom_fixed, map_project_path)
  1027. elif cfg.type == FIX_PARENTS_FROM_REPO:
  1028. map2_project_anc_versions_main = maven_ancestors(cfg)
  1029. if cfg.verbosity >= 1:
  1030. print("---map2_project_anc_versions_main-----------------------------------------------------------------------------------------------------------")
  1031. print(map2_project_anc_versions_main)
  1032. map2_anc_version_projects_main = merge_libs(cfg, map2_project_anc_versions_main)
  1033. if cfg.verbosity >= 3:
  1034. print("---map2_anc_version_projects_main-----------------------------------------------------------------------------------------------------------")
  1035. print(map2_anc_version_projects_main)
  1036. central_ancs = {}
  1037. for anc in map2_anc_version_projects_main.keys():
  1038. latest_version = find_latest_maven_central(cfg

Large files files are truncated, but you can click here to view the full file