40
40
GRPC_LIBS = ['netty' , 'protobuf' , 'stub' ]
41
41
GUAVA_VERSION = '33.3.1-jre'
42
42
43
+ # This should include values corresponding to `MavenCoordinates.artifact_name`,
44
+ # i.e., group:artifact after stripping any Scala version suffix from artifact.
43
45
EXCLUDED_ARTIFACTS = set (["com.google.guava:listenablefuture" ])
44
46
45
47
THIS_FILE = Path (__file__ )
@@ -77,14 +79,13 @@ def select_root_artifacts(scala_version, scala_major, is_scala_3) -> List[str]:
77
79
78
80
scala_2_version = scala_version
79
81
scala_2_major = scala_major
80
- scalatest_major = scala_major
81
82
scalapb_major = scala_2_major
82
83
83
84
if is_scala_3 :
84
85
scala_2_version = max_scala_2_version
85
86
scala_2_major = max_scala_2_major
86
- scalatest_major = '3'
87
- scalapb_major = max_scala_2_major if minor_version < 3 else '3'
87
+ scala_major = '3'
88
+ scalapb_major = max_scala_2_major if minor_version < 3 else scala_major
88
89
89
90
scalafmt_version = SCALAFMT_VERSION
90
91
scalapb_version = SCALAPB_VERSION
@@ -115,11 +116,17 @@ def select_root_artifacts(scala_version, scala_major, is_scala_3) -> List[str]:
115
116
f'org.scala-lang:scala-reflect:{ scala_2_version } ' ,
116
117
f'org.scala-lang:scalap:{ scala_2_version } ' ,
117
118
f'org.scalameta:scalafmt-core_{ scala_2_major } :{ scalafmt_version } ' ,
118
- f'org.scalatest:scalatest_{ scalatest_major } :{ SCALATEST_VERSION } ' ,
119
+ f'org.scalatest:scalatest_{ scala_major } :{ SCALATEST_VERSION } ' ,
119
120
f'org.typelevel:kind-projector_{ scala_2_version } :' +
120
121
KIND_PROJECTOR_VERSION ,
121
122
] + [f'io.grpc:grpc-{ lib } :{ GRPC_VERSION } ' for lib in GRPC_LIBS ]
122
123
124
+ if scala_major != '2.11' :
125
+ root_artifacts .append (
126
+ f'com.thesamet.scalapb:protoc-gen_{ scalapb_major } :' +
127
+ protoc_bridge_version ,
128
+ )
129
+
123
130
if scala_version == max_scala_2_version or is_scala_3 :
124
131
# Since the Scala 2.13 compiler is included in Scala 3 deps.
125
132
root_artifacts .append ('org.jline:jline:' + JLINE_VERSION )
@@ -158,18 +165,51 @@ class MavenCoordinates:
158
165
version : str
159
166
coordinate : str
160
167
168
+ # The `artifact` with the Scala version suffix stripped
169
+ unversioned_artifact : str
170
+
171
+ # Canonical name for comparing new and existing artifacts
172
+ artifact_name : str
173
+
161
174
@staticmethod
162
- def new (artifact ) -> Self :
175
+ def new (coords ) -> Self :
163
176
"""Creates a new MavenCoordinates from a Maven coordinate string."""
164
177
# There are Maven artifacts that contain extra components like `:jar` in
165
178
# their coordinates. However, the groupId and artifactId are always the
166
179
# first two components, and the version is the last.
167
- parts = artifact .split (':' )
168
- return MavenCoordinates (parts [0 ], parts [1 ], parts [- 1 ], artifact )
169
-
170
- def artifact_name (self ):
171
- """Returns the name to use as a hash key for existing artifacts."""
172
- return f'{ self .group } :{ self .artifact } '
180
+ parts = coords .split (':' )
181
+ group , artifact , vers = parts [0 ], parts [1 ], parts [- 1 ]
182
+
183
+ # Remove any Scala version suffix from what will become the
184
+ # `artifact_name`. This is to avoid consecutive runs of the script
185
+ # flipping between the `_2.x` and `_3` versions of some artifacts.
186
+ #
187
+ # Specifically, there are ScalaPB root artifacts specified by this
188
+ # script that end in `_3` yet still transitively depend on artifacts
189
+ # ending in `_2.13`. However, some of these transitive dependencies are
190
+ # also specified as root artifacts ending in `_3`.
191
+ #
192
+ # Without trimming the version suffix, the script would see the `_3`
193
+ # root artifacts and the `_2.13` transitive dependency artifacts as
194
+ # entirely different. However, their computed repository labels would be
195
+ # the same, causing one version to replace the other on consecutive
196
+ # runs.
197
+ artifact_parts = artifact .rsplit ('_' , 1 )
198
+
199
+ if len (artifact_parts ) != 1 :
200
+ version_suffix = artifact_parts [- 1 ]
201
+
202
+ # "Why does `'2.13'.isdecimal()` return `False`, sir?"
203
+ # "Nobody knows."
204
+ # See: https://youtu.be/JYqfVE-fykk (couldn't resist!)
205
+ if version_suffix .split ('.' )[0 ].isdigit ():
206
+ del artifact_parts [- 1 ]
207
+
208
+ unversioned_artifact = '_' .join (artifact_parts )
209
+ artifact_name = f'{ group } :{ unversioned_artifact } '
210
+ return MavenCoordinates (
211
+ group , artifact , vers , coords , unversioned_artifact , artifact_name
212
+ )
173
213
174
214
def is_newer_than (self , other ):
175
215
"""Determines if this artifact is newer than the other.
@@ -188,7 +228,7 @@ def is_newer_than(self, other):
188
228
CreateRepositoryError if other doesn't match self.group and
189
229
self.artifact
190
230
"""
191
- if ( self .group != other .group ) or ( self . artifact != other . artifact ) :
231
+ if self .artifact_name != other .artifact_name :
192
232
raise CreateRepositoryError (
193
233
f'Expected { self .group } :{ self .artifact } , ' +
194
234
f'got { other .group } :{ other .artifact } '
@@ -234,8 +274,7 @@ def get_label(self, coordinates) -> str:
234
274
def _get_label_impl (self , coordinates ) -> str :
235
275
group = coordinates .group
236
276
group_label = self ._labelize (group )
237
- artifact = self ._remove_scala_version_suffix (coordinates .artifact )
238
- artifact_label = self ._labelize (artifact )
277
+ artifact_label = self ._labelize (coordinates .unversioned_artifact )
239
278
240
279
if group in self ._SCALA_LANG_GROUPS :
241
280
return self ._get_scala_lang_label (artifact_label , coordinates )
@@ -246,7 +285,7 @@ def _get_label_impl(self, coordinates) -> str:
246
285
if group in self ._SCALA_PROTO_RULES_GROUPS :
247
286
return self ._get_scala_proto_label (artifact_label , coordinates )
248
287
249
- artifact_name = f' { group } : { artifact } '
288
+ artifact_name = coordinates . artifact_name
250
289
251
290
if artifact_name in self ._SPECIAL_CASE_ARTIFACT_LABELS :
252
291
return self ._SPECIAL_CASE_ARTIFACT_LABELS [artifact_name ]
@@ -256,14 +295,6 @@ def _get_label_impl(self, coordinates) -> str:
256
295
def _labelize (s ):
257
296
return s .replace ('.' , '_' ).replace ('-' , '_' )
258
297
259
- @staticmethod
260
- def _remove_scala_version_suffix (artifact ):
261
- """Removes the Scala version suffix from artifact, e.g., scopt_2.13."""
262
- parts = artifact .split ('_' )
263
- if len (parts ) != 1 and parts [- 1 ][0 ].isdigit ():
264
- return '_' .join (parts [:- 1 ])
265
- return artifact
266
-
267
298
_ARTIFACT_LABEL_ONLY_GROUPS = set ([
268
299
"com.google.guava" ,
269
300
"com.twitter" ,
@@ -361,9 +392,9 @@ def resolve_artifacts(
361
392
362
393
for artifact in artifacts_data ['dependencies' ]:
363
394
coords = MavenCoordinates .new (artifact ['coord' ])
364
- current = current_artifacts_map .get (coords .artifact_name () )
395
+ current = current_artifacts_map .get (coords .artifact_name )
365
396
366
- if coords .artifact_name () in EXCLUDED_ARTIFACTS :
397
+ if coords .artifact_name in EXCLUDED_ARTIFACTS :
367
398
continue
368
399
369
400
if current is None or coords .is_newer_than (current .coordinates ):
@@ -395,7 +426,7 @@ def _create_current_artifacts_map(original_artifacts):
395
426
396
427
for metadata in original_artifacts .values ():
397
428
coordinates = MavenCoordinates .new (metadata ['artifact' ])
398
- name = coordinates .artifact_name ()
429
+ name = coordinates .artifact_name
399
430
400
431
if name not in result and metadata .get ('testonly' ) is not True :
401
432
result [name ] = ResolvedArtifact (
@@ -412,7 +443,7 @@ def _get_artifact_metadata(self, artifact) -> str:
412
443
MavenCoordinates .new (d ) for d in artifact ['directDependencies' ]
413
444
]
414
445
metadata ['deps' ] = [
415
- d for d in deps if d .artifact_name () not in EXCLUDED_ARTIFACTS
446
+ d for d in deps if d .artifact_name not in EXCLUDED_ARTIFACTS
416
447
]
417
448
with open (artifact ['file' ], 'rb' ) as f :
418
449
metadata ['checksum' ] = hashlib .sha256 (f .read ()).hexdigest ()
@@ -533,7 +564,7 @@ def _update_artifact_labels(artifacts, labeler):
533
564
for existing_label , metadata in artifacts .items ():
534
565
coords = MavenCoordinates .new (metadata ['artifact' ])
535
566
536
- if coords .artifact_name () in EXCLUDED_ARTIFACTS :
567
+ if coords .artifact_name in EXCLUDED_ARTIFACTS :
537
568
continue
538
569
539
570
label = (
0 commit comments