Skip to content

Commit c2f76d8

Browse files
committed
ensure rules_python never overrides settings from the root module
1 parent f2b8ad7 commit c2f76d8

File tree

2 files changed

+83
-16
lines changed

2 files changed

+83
-16
lines changed

python/uv/private/uv.bzl

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -132,31 +132,40 @@ for a particular version.
132132
},
133133
)
134134

135-
def _configure(config, *, platform, compatible_with, target_settings, urls = [], sha256 = "", **values):
135+
def _configure(config, *, platform, compatible_with, target_settings, urls = [], sha256 = "", override = False, **values):
136136
"""Set the value in the config if the value is provided"""
137137
for key, value in values.items():
138138
if not value:
139139
continue
140140

141+
if not override and config.get(key):
142+
continue
143+
141144
config[key] = value
142145

143146
config.setdefault("platforms", {})
144-
if platform and not (compatible_with or target_settings or urls):
145-
config["platforms"].pop(platform)
146-
elif platform:
147-
if compatible_with or target_settings:
148-
config["platforms"][platform] = struct(
149-
name = platform.replace("-", "_").lower(),
150-
compatible_with = compatible_with,
151-
target_settings = target_settings,
152-
)
153-
if urls:
154-
config.setdefault("urls", {})[platform] = struct(
155-
sha256 = sha256,
156-
urls = urls,
157-
)
147+
if not platform:
148+
if compatible_with or target_settings or urls:
149+
fail("`platform` name must be specified when specifying `compatible_with`, `target_settings` or `urls`")
158150
elif compatible_with or target_settings:
159-
fail("`platform` name must be specified when specifying `compatible_with` or `target_settings`")
151+
if not override and config.get("platforms", {}).get(platform):
152+
return
153+
154+
config["platforms"][platform] = struct(
155+
name = platform.replace("-", "_").lower(),
156+
compatible_with = compatible_with,
157+
target_settings = target_settings,
158+
)
159+
elif urls:
160+
if not override and config.get("urls", {}).get(platform):
161+
return
162+
163+
config.setdefault("urls", {})[platform] = struct(
164+
sha256 = sha256,
165+
urls = urls,
166+
)
167+
else:
168+
config["platforms"].pop(platform)
160169

161170
def process_modules(
162171
module_ctx,
@@ -205,6 +214,7 @@ def process_modules(
205214
platform = tag.platform,
206215
compatible_with = tag.compatible_with,
207216
target_settings = tag.target_settings,
217+
override = mod.is_root,
208218
)
209219

210220
for key in [
@@ -259,6 +269,7 @@ def process_modules(
259269
target_settings = tag.target_settings,
260270
sha256 = tag.sha256,
261271
urls = tag.urls,
272+
override = mod.is_root,
262273
)
263274

264275
if not versions:

tests/uv/uv/uv_tests.bzl

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,62 @@ def _test_non_rules_python_non_root_is_ignored(env):
487487

488488
_tests.append(_test_non_rules_python_non_root_is_ignored)
489489

490+
def _test_rules_python_does_not_take_precedence(env):
491+
calls = []
492+
uv = _process_modules(
493+
env,
494+
module_ctx = _mock_mctx(
495+
_mod(
496+
default = [
497+
_default(
498+
base_url = "https://example.org",
499+
manifest_filename = "manifest.json",
500+
version = "1.0.0",
501+
platform = "osx",
502+
compatible_with = ["@platforms//os:os"],
503+
),
504+
],
505+
configure = [
506+
_configure(), # use defaults
507+
],
508+
),
509+
_mod(
510+
name = "rules_python",
511+
configure = [
512+
_configure(
513+
version = "1.0.0",
514+
base_url = "https://foobar.org",
515+
platform = "osx",
516+
compatible_with = ["@platforms//os:osx"],
517+
),
518+
],
519+
),
520+
),
521+
uv_repository = lambda **kwargs: calls.append(kwargs),
522+
)
523+
524+
uv.names().contains_exactly([
525+
"1_0_0_osx",
526+
])
527+
uv.implementations().contains_exactly({
528+
"1_0_0_osx": "@uv_1_0_0_osx//:uv_toolchain",
529+
})
530+
uv.compatible_with().contains_exactly({
531+
"1_0_0_osx": ["@platforms//os:os"],
532+
})
533+
uv.target_settings().contains_exactly({})
534+
env.expect.that_collection(calls).contains_exactly([
535+
{
536+
"name": "uv_1_0_0_osx",
537+
"platform": "osx",
538+
"sha256": "deadb00f",
539+
"urls": ["https://example.org/1.0.0/osx"],
540+
"version": "1.0.0",
541+
},
542+
])
543+
544+
_tests.append(_test_rules_python_does_not_take_precedence)
545+
490546
_analysis_tests = []
491547

492548
def _test_toolchain_precedence(name):

0 commit comments

Comments
 (0)