Skip to content

Commit 76d581c

Browse files
committed
Allow specifying the URL and sha256 values manually
1 parent 1ac0437 commit 76d581c

File tree

2 files changed

+106
-40
lines changed

2 files changed

+106
-40
lines changed

python/uv/private/uv.bzl

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,15 @@ similarly how `rules_python` is doing it itself.
106106
"platform": attr.string(
107107
doc = "The platform string used in the UV repository to denote the platform triple.",
108108
),
109+
"sha256": attr.string(
110+
doc = "The sha256 of the downloaded artifact.",
111+
),
109112
"target_settings": attr.label_list(
110113
doc = "The `target_settings` to add to platform definitions.",
111114
),
115+
"urls": attr.string_list(
116+
doc = "The urls to download the binary from. If this is used, {attr}`base_url` is ignored.",
117+
),
112118
"version": attr.string(
113119
doc = "The version of uv to use.",
114120
),
@@ -160,7 +166,7 @@ def parse_modules(module_ctx, uv_repository = None):
160166
for config_attr in mod.tags.configure:
161167
last_version = config_attr.version or last_version or config["version"]
162168
specific_config = versions.setdefault(last_version, {
163-
"base_url": config["base_url"],
169+
"base_url": config.get("base_url", ""),
164170
"manifest_filename": config["manifest_filename"],
165171
"platforms": {k: v for k, v in config["platforms"].items()}, # make a copy
166172
})
@@ -172,14 +178,19 @@ def parse_modules(module_ctx, uv_repository = None):
172178
compatible_with = config_attr.compatible_with,
173179
target_settings = config_attr.target_settings,
174180
)
181+
if config_attr.urls:
182+
specific_config.setdefault("urls", {})[config_attr.platform] = struct(
183+
sha256 = config_attr.sha256,
184+
urls = config_attr.urls,
185+
)
175186
elif config_attr.compatible_with or config_attr.target_settings:
176187
fail("TODO: unsupported")
177188

178189
if config_attr.base_url:
179190
specific_config["base_url"] = config_attr.base_url
180191

181192
if config_attr.manifest_filename:
182-
config["manifest_filename"] = config_attr.manifest_filename
193+
specific_config["manifest_filename"] = config_attr.manifest_filename
183194

184195
versions = {
185196
v: config
@@ -205,19 +216,22 @@ def parse_modules(module_ctx, uv_repository = None):
205216
toolchain_target_settings = {}
206217

207218
for version, config in versions.items():
208-
config["urls"] = _get_tool_urls_from_dist_manifest(
209-
module_ctx,
210-
base_url = "{base_url}/{version}".format(
211-
version = version,
212-
base_url = config["base_url"],
213-
),
214-
manifest_filename = config["manifest_filename"],
215-
)
219+
urls = config.get("urls")
220+
if not urls:
221+
urls = _get_tool_urls_from_dist_manifest(
222+
module_ctx,
223+
base_url = "{base_url}/{version}".format(
224+
version = version,
225+
base_url = config["base_url"],
226+
),
227+
manifest_filename = config["manifest_filename"],
228+
)
229+
216230
platforms = config["platforms"]
217231
result = uv_repositories(
218232
name = "uv",
219233
platforms = platforms,
220-
urls = config["urls"],
234+
urls = urls,
221235
version = version,
222236
uv_repository = uv_repository,
223237
)

tests/uv/uv/uv_tests.bzl

Lines changed: 81 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ load("//python/uv/private:uv.bzl", "parse_modules") # buildifier: disable=bzl-v
2121
_tests = []
2222

2323
def _mock_mctx(*modules, download = None, read = None):
24+
# Here we construct a fake minimal manifest file that we use to mock what would
25+
# be otherwise read from GH files
2426
manifest_files = {
2527
"different.json": {
2628
x: {
@@ -123,9 +125,9 @@ def _default(
123125
**kwargs
124126
)
125127

126-
def _configure(**kwargs):
128+
def _configure(urls = None, sha256 = None, **kwargs):
127129
# We have the same attributes
128-
return _default(**kwargs)
130+
return _default(sha256 = sha256, urls = urls, **kwargs)
129131

130132
def _test_only_defaults(env):
131133
uv = _parse_modules(
@@ -157,6 +159,56 @@ def _test_only_defaults(env):
157159

158160
_tests.append(_test_only_defaults)
159161

162+
def _test_manual_url_spec(env):
163+
calls = []
164+
uv = _parse_modules(
165+
env,
166+
module_ctx = _mock_mctx(
167+
_mod(
168+
default = [
169+
_default(
170+
manifest_filename = "manifest.json",
171+
version = "1.0.0",
172+
),
173+
],
174+
configure = [
175+
_configure(
176+
platform = "linux",
177+
compatible_with = ["@platforms//os:linux"],
178+
urls = ["https://example.org/download.zip"],
179+
sha256 = "deadbeef",
180+
),
181+
],
182+
),
183+
read = lambda *args, **kwargs: fail(args, kwargs),
184+
),
185+
uv_repository = lambda **kwargs: calls.append(kwargs),
186+
)
187+
188+
uv.names().contains_exactly([
189+
"uv_1_0_0_linux_toolchain",
190+
])
191+
uv.labels().contains_exactly({
192+
"uv_1_0_0_linux_toolchain": "@uv_1_0_0_linux//:uv_toolchain",
193+
})
194+
uv.compatible_with().contains_exactly({
195+
"uv_1_0_0_linux_toolchain": ["@platforms//os:linux"],
196+
})
197+
uv.target_settings().contains_exactly({
198+
"uv_1_0_0_linux_toolchain": [],
199+
})
200+
env.expect.that_collection(calls).contains_exactly([
201+
{
202+
"name": "uv_1_0_0_linux",
203+
"platform": "linux",
204+
"sha256": "deadbeef",
205+
"urls": ["https://example.org/download.zip"],
206+
"version": "1.0.0",
207+
},
208+
])
209+
210+
_tests.append(_test_manual_url_spec)
211+
160212
def _test_defaults(env):
161213
calls = []
162214
uv = _parse_modules(
@@ -281,7 +333,7 @@ def _test_complex_configuring(env):
281333
base_url = "https://example.org",
282334
manifest_filename = "manifest.json",
283335
version = "1.0.0",
284-
platform = "os",
336+
platform = "osx",
285337
compatible_with = ["@platforms//os:os"],
286338
),
287339
],
@@ -296,13 +348,13 @@ def _test_complex_configuring(env):
296348
manifest_filename = "different.json",
297349
), # use defaults
298350
_configure(
299-
platform = "os",
351+
platform = "osx",
300352
compatible_with = ["@platforms//os:different"],
301353
),
302354
_configure(
303355
version = "1.0.3",
304356
),
305-
_configure(platform = "os"), # remove the default
357+
_configure(platform = "osx"), # remove the default
306358
_configure(
307359
platform = "linux",
308360
compatible_with = ["@platforms//os:linux"],
@@ -314,49 +366,49 @@ def _test_complex_configuring(env):
314366
)
315367

316368
uv.names().contains_exactly([
317-
"uv_1_0_0_os_toolchain",
318-
"uv_1_0_1_os_toolchain",
319-
"uv_1_0_2_os_toolchain",
369+
"uv_1_0_0_osx_toolchain",
370+
"uv_1_0_1_osx_toolchain",
371+
"uv_1_0_2_osx_toolchain",
320372
"uv_1_0_3_linux_toolchain",
321373
])
322374
uv.labels().contains_exactly({
323-
"uv_1_0_0_os_toolchain": "@uv_1_0_0_os//:uv_toolchain",
324-
"uv_1_0_1_os_toolchain": "@uv_1_0_1_os//:uv_toolchain",
325-
"uv_1_0_2_os_toolchain": "@uv_1_0_2_os//:uv_toolchain",
375+
"uv_1_0_0_osx_toolchain": "@uv_1_0_0_osx//:uv_toolchain",
376+
"uv_1_0_1_osx_toolchain": "@uv_1_0_1_osx//:uv_toolchain",
377+
"uv_1_0_2_osx_toolchain": "@uv_1_0_2_osx//:uv_toolchain",
326378
"uv_1_0_3_linux_toolchain": "@uv_1_0_3_linux//:uv_toolchain",
327379
})
328380
uv.compatible_with().contains_exactly({
329-
"uv_1_0_0_os_toolchain": ["@platforms//os:os"],
330-
"uv_1_0_1_os_toolchain": ["@platforms//os:os"],
331-
"uv_1_0_2_os_toolchain": ["@platforms//os:different"],
381+
"uv_1_0_0_osx_toolchain": ["@platforms//os:os"],
382+
"uv_1_0_1_osx_toolchain": ["@platforms//os:os"],
383+
"uv_1_0_2_osx_toolchain": ["@platforms//os:different"],
332384
"uv_1_0_3_linux_toolchain": ["@platforms//os:linux"],
333385
})
334386
uv.target_settings().contains_exactly({
335-
"uv_1_0_0_os_toolchain": [],
336-
"uv_1_0_1_os_toolchain": [],
337-
"uv_1_0_2_os_toolchain": [],
387+
"uv_1_0_0_osx_toolchain": [],
388+
"uv_1_0_1_osx_toolchain": [],
389+
"uv_1_0_2_osx_toolchain": [],
338390
"uv_1_0_3_linux_toolchain": [],
339391
})
340392
env.expect.that_collection(calls).contains_exactly([
341393
{
342-
"name": "uv_1_0_0_os",
343-
"platform": "os",
344-
"sha256": "deadbeef",
345-
"urls": ["https://example.org/1.0.0/os"],
394+
"name": "uv_1_0_0_osx",
395+
"platform": "osx",
396+
"sha256": "deadb00f",
397+
"urls": ["https://example.org/1.0.0/osx"],
346398
"version": "1.0.0",
347399
},
348400
{
349-
"name": "uv_1_0_1_os",
350-
"platform": "os",
351-
"sha256": "deadbeef",
352-
"urls": ["https://example.org/1.0.1/os"],
401+
"name": "uv_1_0_1_osx",
402+
"platform": "osx",
403+
"sha256": "deadb00f",
404+
"urls": ["https://example.org/1.0.1/osx"],
353405
"version": "1.0.1",
354406
},
355407
{
356-
"name": "uv_1_0_2_os",
357-
"platform": "os",
358-
"sha256": "deadbeef",
359-
"urls": ["something_different/1.0.2/os"],
408+
"name": "uv_1_0_2_osx",
409+
"platform": "osx",
410+
"sha256": "deadb00f",
411+
"urls": ["something_different/1.0.2/osx"],
360412
"version": "1.0.2",
361413
},
362414
{

0 commit comments

Comments
 (0)