23
23
24
24
visibility ("public" )
25
25
26
- unavailable_xcode_message = "'bazel fetch --configure' (Bzlmod) or 'bazel sync --configure' (WORKSPACE)"
26
+ UNAVAILABLE_XCODE_MESSAGE = "'bazel fetch --configure' (Bzlmod) or 'bazel sync --configure' (WORKSPACE)"
27
27
28
28
def _xcode_config_impl (ctx ):
29
29
apple_fragment = ctx .fragments .apple
@@ -54,6 +54,7 @@ def _xcode_config_impl(ctx):
54
54
remote_versions ,
55
55
):
56
56
xcode_version_properties , availability = _resolve_xcode_from_local_and_remote (
57
+ ctx .actions ,
57
58
local_versions ,
58
59
remote_versions ,
59
60
apple_fragment .xcode_version_flag ,
@@ -208,6 +209,7 @@ def _aliases_to_xcode_version(versions):
208
209
return version_map
209
210
210
211
def _resolve_xcode_from_local_and_remote (
212
+ actions ,
211
213
local_versions ,
212
214
remote_versions ,
213
215
xcode_version_flag ,
@@ -256,32 +258,29 @@ def _resolve_xcode_from_local_and_remote(
256
258
)
257
259
258
260
elif local_version_from_flag :
259
- error = (
260
- " --xcode_version={} specified, but it is not available remotely. Actions " +
261
- "requiring Xcode will be run locally, which could make your build slower."
262
- ).format (
263
- xcode_version_flag ,
264
- )
265
- if (mutually_available_versions ):
266
- error += " Consider using one of [{}]." .format (
267
- ", " .join ([version for version in mutually_available_versions ]),
261
+ if mutually_available_versions :
262
+ _warn (
263
+ actions ,
264
+ "explicit_version_not_available_remotely_consider_mutual" ,
265
+ version = xcode_version_flag ,
266
+ mutual_versions = [version for version in mutually_available_versions ],
267
+ )
268
+ else :
269
+ _warn (
270
+ actions ,
271
+ "explicit_version_not_available_remotely" ,
272
+ version = xcode_version_flag ,
268
273
)
269
-
270
- # buildifier: disable=print
271
- print (error )
272
274
return local_version_from_flag .xcode_version_properties , "LOCAL"
273
275
274
276
elif remote_version_from_flag :
275
- # buildifier: disable=print
276
- print (("--xcode_version={version} specified, but it is not available locally. " +
277
- "Your build will fail if any actions require a local Xcode. " +
278
- "If you believe you have '{version}' installed, try running {command}," +
279
- "and then re-run your command. Locally available versions: {local_versions}. " )
280
- .format (
277
+ _warn (
278
+ actions ,
279
+ "version_not_available_locally" ,
281
280
version = xcode_version_flag ,
282
- command = unavailable_xcode_message ,
281
+ command = UNAVAILABLE_XCODE_MESSAGE ,
283
282
local_versions = ", " .join ([version for version in local_alias_to_version_map .keys ()]),
284
- ))
283
+ )
285
284
availability = "REMOTE"
286
285
287
286
return remote_version_from_flag .xcode_version_properties , availability
@@ -293,7 +292,7 @@ def _resolve_xcode_from_local_and_remote(
293
292
" you believe you have '{0}' installed, try running {1}, and then" +
294
293
" re-run your command." ).format (
295
294
xcode_version_flag ,
296
- unavailable_xcode_message ,
295
+ UNAVAILABLE_XCODE_MESSAGE ,
297
296
", " .join ([version .xcode_version_properties .xcode_version for version in local_versions ]),
298
297
", " .join ([version .xcode_version_properties .xcode_version for version in remote_versions ]),
299
298
),
@@ -305,12 +304,11 @@ def _resolve_xcode_from_local_and_remote(
305
304
306
305
# If there aren't any mutually available versions, select the local default.
307
306
if not mutually_available_versions :
308
- # buildifier: disable=print
309
- print (
310
- ("Using a local Xcode version, '{}', since there are no" +
311
- " remotely available Xcodes on this machine. Consider downloading one of the" +
312
- " remotely available Xcode versions ({}) in order to get the best build" +
313
- " performance." ).format (local_default_version .xcode_version_properties .xcode_version , ", " .join ([version .xcode_version_properties .xcode_version for version in remote_versions ])),
307
+ _warn (
308
+ actions ,
309
+ "local_default_not_available_remotely" ,
310
+ local_version = local_default_version .xcode_version_properties .xcode_version ,
311
+ remote_versions = ", " .join ([version .xcode_version_properties .xcode_version for version in remote_versions ]),
314
312
)
315
313
local_version = local_default_version
316
314
availability = "LOCAL"
@@ -385,3 +383,57 @@ def _resolve_explicitly_defined_version(
385
383
386
384
def _dotted_version_or_default (field , default ):
387
385
return apple_common .dotted_version (field ) or default
386
+
387
+ _WARNINGS = {
388
+ "version_not_available_locally" : """\
389
+ --xcode_version={version} specified, but it is not available locally. \
390
+ Your build will fail if any actions require a local Xcode. \
391
+ If you believe you have '{version}' installed, try running {command}, \
392
+ and then re-run your command. Locally available versions: {local_versions}.
393
+ """ ,
394
+ "local_default_not_available_remotely" : """\
395
+ Using a local Xcode version, '{local_version}', since there are no \
396
+ remotely available Xcodes on this machine. Consider downloading one of the \
397
+ remotely available Xcode versions ({remote_versions}) in order to get the best \
398
+ build performance.
399
+ """ ,
400
+ "explicit_version_not_available_remotely" : """\
401
+ --xcode_version={version} specified, but it is not available remotely. Actions \
402
+ requiring Xcode will be run locally, which could make your build slower.
403
+ """ ,
404
+ "explicit_version_not_available_remotely_consider_mutual" : """\
405
+ --xcode_version={version} specified, but it is not available remotely. Actions \
406
+ requiring Xcode will be run locally, which could make your build slower. \
407
+ Consider using one of [{mutual_versions}].
408
+ """ ,
409
+ }
410
+
411
+ def _warn (actions , msg_id , ** kwargs ):
412
+ """Print a warning and also record it as a testable dummy action.
413
+
414
+ Starlark doesn't support testing the output of the `print()` function, so
415
+ this function also registers a dummy action with a specifically formatted
416
+ mnemonic that can be read in the test using the `assert_warning` helper.
417
+
418
+ Args:
419
+ actions: The object used to register actions.
420
+ msg_id: A string identifying the warning as a key in the `_WARNINGS`
421
+ dictionary.
422
+ **kwargs: Formatting arguments for the message string.
423
+ """
424
+
425
+ # buildifier: disable=print
426
+ print (_WARNINGS [msg_id ].format (** kwargs ))
427
+
428
+ mnemonic = "Warning:{}" .format (msg_id )
429
+ if kwargs :
430
+ # Sort the format arguments by key so that they're deterministically
431
+ # ordered for tests.
432
+ sorted_values = []
433
+ for key in sorted (kwargs .keys ()):
434
+ sorted_values .append ("{}={}" .format (key , str (kwargs [key ])))
435
+ mnemonic += ":{}" .format (";" .join (sorted_values ))
436
+
437
+ actions .do_nothing (
438
+ mnemonic = mnemonic ,
439
+ )
0 commit comments