Skip to content

Commit ad71483

Browse files
committed
Prevent create_repository.py from downgrading jars
The script will now only update an existing artifact if the newly resolved version is greater than that already in the third_party/repositories file. Part of bazel-contrib#1482. Tested by running on `master` both before and after bazel-contrib#1631. The script produced no new changes, and is even faster now, since it also won't try to downgrade existing artifact versions. More specifically, this change prevents the following downgrades: - scalap: from latest Scala version to an earlier version, including 2.13.14 to 2.13.11 - com.lihaoyi.pprint: from pprint_3:0.9.0 to pprint_2.13:0.6.4 - compiler-interface: 1.10.1 to 1.3.5 or 1.9.6 - com.lihaoyi.geny: from geny_3:1.1.1 to geny_2.13:0.6.5
1 parent c5244de commit ad71483

File tree

1 file changed

+46
-5
lines changed

1 file changed

+46
-5
lines changed

scripts/create_repository.py

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,16 +156,50 @@ def get_label(coordinates, is_scala_3) -> str:
156156
return f'scala_proto_rules_{artifact_label}'
157157
return f'{group_label}_{artifact_label}'.replace('_v2', '')
158158

159+
def split_artifact_and_version(artifact_id):
160+
# There are Maven artifacts that contain extra components like `:jar` in
161+
# their coordinates. However, the groupId and artifactId are always the
162+
# first two components, and the version is the last.
163+
components = artifact_id.split(':')
164+
return ':'.join(components[0:2]), components[-1]
165+
166+
def is_newer_than_current_version(version_to_check, current_version):
167+
"""Determines if the version_to_check is newer than the current_version.
168+
169+
The idea is to prevent downgrades of versions already in the artifacts file.
170+
If they are later versions, presumably they were updated to that version for
171+
a good reason.
172+
"""
173+
if current_version is None:
174+
return True
175+
if version_to_check == current_version:
176+
return False
177+
178+
check_parts = version_to_check.split(".")
179+
current_parts = current_version.split(".")
180+
181+
for check_part, current_part in zip(check_parts, current_parts):
182+
if check_part == current_part:
183+
continue
184+
if check_part.isdecimal() and current_part.isdecimal():
185+
return int(current_part) < int(check_part)
186+
return current_part < check_part
187+
188+
return len(current_parts) < len(check_parts)
189+
159190
def map_to_resolved_artifacts(
160-
output, current_artifacts
191+
output, current_artifact_to_version_map
161192
) -> List[ResolvedArtifact]:
162193

163194
artifacts_to_update = []
164195
fetch_specs = []
165196

166197
for line in output:
167198
artifact = line.replace(':default', '')
168-
if artifact not in current_artifacts:
199+
name, version = split_artifact_and_version(artifact)
200+
current_version = current_artifact_to_version_map.get(name, None)
201+
202+
if is_newer_than_current_version(version, current_version):
169203
artifacts_to_update.append(artifact)
170204
fetch_specs.append(line)
171205

@@ -184,15 +218,15 @@ def map_to_resolved_artifacts(
184218
]
185219

186220
def resolve_artifacts_with_checksums_and_direct_dependencies(
187-
root_artifacts, current_artifacts
221+
root_artifacts, current_artifact_to_version_map
188222
) -> List[ResolvedArtifact]:
189223
command = f'cs resolve {' '.join(root_artifacts)}'
190224
proc = subprocess.run(
191225
command, capture_output=True, text=True, shell=True, check=False
192226
)
193227
print(proc.stderr)
194228
return map_to_resolved_artifacts(
195-
proc.stdout.splitlines(), current_artifacts,
229+
proc.stdout.splitlines(), current_artifact_to_version_map,
196230
)
197231

198232
def to_rules_scala_compatible_dict(artifacts, is_scala_3) -> Dict[str, Dict]:
@@ -229,6 +263,13 @@ def write_to_file(artifact_dict, version, file):
229263
data.write('\nartifacts = ')
230264
data.write(artifacts)
231265

266+
def create_artifact_version_map(original_artifacts):
267+
result = {}
268+
for metadata in original_artifacts.values():
269+
artifact, version = split_artifact_and_version(metadata['artifact'])
270+
result[artifact] = version
271+
return result
272+
232273
def create_file(version):
233274
file = (
234275
Path(__file__).parent.parent /
@@ -255,7 +296,7 @@ def create_file(version):
255296
transitive_artifacts: List[ResolvedArtifact] = (
256297
resolve_artifacts_with_checksums_and_direct_dependencies(
257298
root_artifacts,
258-
{a["artifact"] for a in original_artifacts.values()},
299+
create_artifact_version_map(original_artifacts),
259300
)
260301
)
261302
generated_artifacts = to_rules_scala_compatible_dict(

0 commit comments

Comments
 (0)