1414
1515import sys
1616import re
17+ import os
1718
19+ def parse_pom_for_version (file_path ):
20+ """Extracts artifactId and version from a pom.xml file."""
21+ artifact_id = None
22+ version = None
23+ parent_version = None
24+
25+ try :
26+ with open (file_path , 'r' ) as f :
27+ in_parent = False
28+ in_skipped_section = False
29+ # Sections to skip to avoid capturing artifactId/version from dependencies or plugins
30+ skip_tags = ['dependencies' , 'dependencyManagement' , 'plugins' , 'build' , 'reporting' , 'profiles' ]
31+
32+ for line in f :
33+ stripped = line .strip ()
34+ if not stripped : continue
35+
36+ # Check for skipped sections
37+ section_start = False
38+ for tag in skip_tags :
39+ if f'<{ tag } >' in stripped :
40+ in_skipped_section = True
41+ section_start = True
42+ break
43+ if section_start : continue
44+
45+ section_end = False
46+ for tag in skip_tags :
47+ if f'</{ tag } >' in stripped :
48+ in_skipped_section = False
49+ section_end = True
50+ break
51+ if section_end : continue
52+
53+ if in_skipped_section : continue
54+
55+ if '<parent>' in stripped :
56+ in_parent = True
57+ continue
58+ if '</parent>' in stripped :
59+ in_parent = False
60+ continue
61+
62+ if '<artifactId>' in stripped and not artifact_id and not in_parent :
63+ match = re .search (r'<artifactId>(.*?)</artifactId>' , stripped )
64+ if match :
65+ artifact_id = match .group (1 ).strip ()
66+
67+ if '<version>' in stripped :
68+ match = re .search (r'<version>(.*?)</version>' , stripped )
69+ if match :
70+ v = match .group (1 ).strip ()
71+ if in_parent :
72+ parent_version = v
73+ elif not version :
74+ version = v
75+
76+ if artifact_id and version :
77+ break
78+ except Exception as e :
79+ print (f"Warning: Could not parse { file_path } : { e } " )
80+
81+ return artifact_id , version or parent_version
1882
19- def modernize_pom (file_path , parent_version , source_repo_name = None , parent_artifactId = 'google-cloud-jar-parent' , relative_path = '../google-cloud-jar-parent/pom.xml' ):
83+ def get_monorepo_versions (monorepo_root = '.' ):
84+ """Scans all pom.xml files in the monorepo to build a map of artifactId to version."""
85+ versions = {}
86+ for root , dirs , files in os .walk (monorepo_root ):
87+ # Skip common directories to improve performance and avoid noise
88+ dirs [:] = [d for d in dirs if d not in ['samples' , 'test' , 'target' , '.git' , '.cloud' , 'verification' , 'test_data' ]]
89+
90+ if 'pom.xml' in files :
91+ pom_path = os .path .join (root , 'pom.xml' )
92+ artifactId , version = parse_pom_for_version (pom_path )
93+ if artifactId and version :
94+ versions [artifactId ] = version
95+ return versions
96+
97+ def modernize_pom (file_path , parent_version , source_repo_name = None , parent_artifactId = 'google-cloud-jar-parent' , relative_path = '../google-cloud-jar-parent/pom.xml' , monorepo_versions = None ):
2098 with open (file_path , 'r' ) as f :
2199 lines = f .readlines ()
22100
@@ -121,9 +199,6 @@ def modernize_pom(file_path, parent_version, source_repo_name=None, parent_artif
121199 continue
122200
123201 if in_dependency :
124- current_dependency_lines .append (line )
125- if '{x-version-update:' in line :
126- should_preserve = True
127202 if '<groupId>' in line :
128203 match = re .search (r'<groupId>(.*?)</groupId>' , line )
129204 if match :
@@ -134,6 +209,19 @@ def modernize_pom(file_path, parent_version, source_repo_name=None, parent_artif
134209 current_artifact_id = match .group (1 ).strip ()
135210 if '<version>' in line :
136211 has_version = True
212+
213+ if monorepo_versions and current_artifact_id and current_artifact_id in monorepo_versions :
214+ new_version = monorepo_versions [current_artifact_id ]
215+ indent = line [:line .find ('<' )]
216+ if '<version>' in line :
217+ marker_artifact = current_artifact_id .replace ('-bom' , '' )
218+ current_dependency_lines .append (f"{ indent } <version>{ new_version } </version><!-- {{x-version-update:{ marker_artifact } :current}} -->\n " )
219+ should_preserve = True
220+ continue
221+
222+ current_dependency_lines .append (line )
223+ if '{x-version-update:' in line :
224+ should_preserve = True
137225 continue
138226
139227 # Prune comments and extra whitespace in depMgmt for a cleaner result
@@ -161,10 +249,18 @@ def modernize_pom(file_path, parent_version, source_repo_name=None, parent_artif
161249
162250if __name__ == "__main__" :
163251 if len (sys .argv ) > 2 :
252+ # Monorepo root is likely the parent of the directory containing this script
253+ script_dir = os .path .dirname (os .path .abspath (__file__ ))
254+ monorepo_root = os .path .dirname (script_dir )
255+
256+ print (f"Scanning monorepo at { monorepo_root } for versions..." )
257+ monorepo_versions = get_monorepo_versions (monorepo_root )
258+ print (f"Found { len (monorepo_versions )} artifacts." )
259+
164260 source_repo = sys .argv [3 ] if len (sys .argv ) > 3 else None
165261 parent_artifactId = sys .argv [4 ] if len (sys .argv ) > 4 else 'google-cloud-jar-parent'
166262 relative_path = sys .argv [5 ] if len (sys .argv ) > 5 else '../google-cloud-jar-parent/pom.xml'
167- modernize_pom (sys .argv [1 ], sys .argv [2 ], source_repo , parent_artifactId , relative_path )
263+ modernize_pom (sys .argv [1 ], sys .argv [2 ], source_repo , parent_artifactId , relative_path , monorepo_versions )
168264 else :
169265 print ("Usage: python3 modernize_pom.py <file_path> <parent_version> [source_repo_name] [parent_artifactId] [relative_path]" )
170266 sys .exit (1 )
0 commit comments