Last active
February 16, 2024 23:11
-
-
Save ewhauser/9e4269b9c871620bc2a4b8d58f1799a3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/internal_setup.bzl b/internal_setup.bzl | |
index a80099f..56eb486 100644 | |
--- a/internal_setup.bzl | |
+++ b/internal_setup.bzl | |
@@ -21,7 +21,7 @@ load("@rules_bazel_integration_test//bazel_integration_test:deps.bzl", "bazel_in | |
load("@rules_bazel_integration_test//bazel_integration_test:repo_defs.bzl", "bazel_binaries") | |
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains") | |
load("//:version.bzl", "SUPPORTED_BAZEL_VERSIONS") | |
-load("//python/pip_install:repositories.bzl", "pip_install_dependencies") | |
+load("//python/pip_install:repositories.bzl", "pip_install_dependencies", "uv_dependencies") | |
load("//python/private:internal_config_repo.bzl", "internal_config_repo") # buildifier: disable=bzl-visibility | |
def rules_python_internal_setup(): | |
@@ -31,6 +31,7 @@ def rules_python_internal_setup(): | |
# Because we don't use the pip_install rule, we have to call this to fetch its deps | |
pip_install_dependencies() | |
+ uv_dependencies() | |
bazel_skylib_workspace() | |
diff --git a/python/pip_install/mirror_uv.sh b/python/pip_install/mirror_uv.sh | |
new file mode 100755 | |
index 0000000..8d9c719 | |
--- /dev/null | |
+++ b/python/pip_install/mirror_uv.sh | |
@@ -0,0 +1,67 @@ | |
+#!/usr/bin/env bash | |
+ | |
+set -o errexit -o nounset -o pipefail | |
+SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" | |
+RELEASES=$(mktemp) | |
+RAW=$(mktemp) | |
+ | |
+REPOSITORY=${1:-"astral-sh/uv"} | |
+ | |
+JQ_FILTER=\ | |
+'map( | |
+ { | |
+ "key": .tag_name, | |
+ "value": .assets | |
+ | map(select((.name | contains("uv-")) and (.name | contains("sha256") | not) )) | |
+ | map({ | |
+ "key": .name | capture("uv-(?<platform>.*)\\.(tar\\.gz|zip)") | .platform, | |
+ "value": (.browser_download_url + ".sha256"), | |
+ }) | |
+ | from_entries | |
+ } | |
+) | from_entries' | |
+ | |
+SHA256_FILTER=\ | |
+' | |
+map( | |
+ select(.name == $tag) | |
+ | .assets | |
+ | map(.browser_download_url)[] | |
+ | select(endswith(".sha256")) | |
+)[] | |
+' | |
+ | |
+curl > $RELEASES \ | |
+ --silent \ | |
+ --header "Accept: application/vnd.github.v3+json" \ | |
+ https://api.github.com/repos/${REPOSITORY}/releases?per_page=1 | |
+ | |
+cat $RELEASES | |
+ | |
+jq "$JQ_FILTER" <$RELEASES >$RAW | |
+ | |
+# Combine the new versions with the existing ones. | |
+# New versions should appear first, but existing content should overwrite new | |
+CURRENT=$(mktemp) | |
+python3 -c "import json; exec(open('$SCRIPT_DIR/uv_versions.bzl').read()); print(json.dumps(UV_VERSIONS))" > $CURRENT | |
+OUT=$(mktemp) | |
+jq --slurp '.[0] * .[1]' $RAW $CURRENT > $OUT | |
+ | |
+FIXED=$(mktemp) | |
+# Replace placeholder sha256 URLs with their content | |
+for tag in $(jq -r 'keys | .[]' < $OUT); do | |
+ # Download checksums for this tag | |
+ # Note: this is wasteful; we will curl for sha256 files even if the CURRENT content already had resolved them | |
+ for sha256url in $(jq --arg tag $tag -r "$SHA256_FILTER" < $RELEASES); do | |
+ sha256=$(curl --silent --location $sha256url | awk '{print $1}') | |
+ jq ".[\"$tag\"] |= with_entries(.value = (if .value == \"$sha256url\" then \"$sha256\" else .value end))" < $OUT > $FIXED | |
+ mv $FIXED $OUT | |
+ done | |
+done | |
+ | |
+# Overwrite the file with updated content | |
+( | |
+ echo '"This file is automatically updated by mirror_uv.sh"' | |
+ echo -n "UV_VERSIONS = " | |
+ cat $OUT | |
+)>$SCRIPT_DIR/uv_versions.bzl | |
diff --git a/python/pip_install/repositories.bzl b/python/pip_install/repositories.bzl | |
index 91bdd4b..b7179ff 100644 | |
--- a/python/pip_install/repositories.bzl | |
+++ b/python/pip_install/repositories.bzl | |
@@ -16,6 +16,7 @@ | |
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") | |
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") | |
+load(":uv_versions.bzl", "UV_VERSIONS") | |
_RULE_DEPS = [ | |
# START: maintained by 'bazel run //tools/private:update_pip_deps' | |
@@ -142,3 +143,25 @@ def pip_install_dependencies(): | |
type = "zip", | |
build_file_content = _GENERIC_WHEEL, | |
) | |
+ | |
+def uv_dependencies(tag = UV_VERSIONS.keys()[0]): | |
+ version = tag.lstrip("v") | |
+ url = "https://github.com/astral-sh/uv/releases/download/{tag}/uv-{plat}.{ext}" | |
+ | |
+ for plat, sha256 in UV_VERSIONS[tag].items(): | |
+ fetch_rule = http_archive | |
+ is_windows = plat.endswith("windows-msvc") | |
+ | |
+ maybe( | |
+ http_archive, | |
+ name = "uv_" + plat, | |
+ url = url.format( | |
+ tag = tag, | |
+ plat = plat, | |
+ version = version, | |
+ ext = "zip" if is_windows else "tar.gz", | |
+ ), | |
+ sha256 = sha256, | |
+ strip_prefix = "uv-" + plat, | |
+ build_file_content = """exports_files(["uv", "uv.exe"])""", | |
+ ) | |
diff --git a/python/pip_install/requirements.bzl b/python/pip_install/requirements.bzl | |
index 5caf762..1a80389 100644 | |
--- a/python/pip_install/requirements.bzl | |
+++ b/python/pip_install/requirements.bzl | |
@@ -84,7 +84,11 @@ def compile_pip_requirements( | |
visibility = visibility, | |
) | |
- data = [name, requirements_txt, src] + [f for f in (requirements_linux, requirements_darwin, requirements_windows) if f != None] | |
+ data = [name, requirements_txt, src] + [f for f in ( | |
+ requirements_linux, | |
+ requirements_darwin, | |
+ requirements_windows, | |
+ ) if f != None] + [Label("@//tools:uv")] | |
# Use the Label constructor so this is expanded in the context of the file | |
# where it appears, which is to say, in @rules_python | |
diff --git a/python/pip_install/tools/dependency_resolver/dependency_resolver.py b/python/pip_install/tools/dependency_resolver/dependency_resolver.py | |
index 5e914bc..4ae603a 100644 | |
--- a/python/pip_install/tools/dependency_resolver/dependency_resolver.py | |
+++ b/python/pip_install/tools/dependency_resolver/dependency_resolver.py | |
@@ -17,6 +17,7 @@ | |
import atexit | |
import os | |
import shutil | |
+import subprocess | |
import sys | |
from pathlib import Path | |
from typing import Optional, Tuple | |
@@ -79,6 +80,18 @@ def _locate(bazel_runfiles, file): | |
return bazel_runfiles.Rlocation(file) | |
+def _run_uv(uv, argv): | |
+ seen = set() | |
+ # Construct the command list while maintaining order, removing duplicates, | |
+ # and excluding "--allow-unsafe" arguments | |
+ cmd = [uv] + [arg for arg in argv if arg != "--allow-unsafe" and (arg not in seen and seen.add(arg) is None)] | |
+ print(" ".join(cmd), file=sys.stderr) | |
+ result = subprocess.run(cmd, capture_output=True, text=True) | |
+ print(result.stdout, file=sys.stderr) | |
+ print(result.stderr, file=sys.stderr) | |
+ raise SystemExit(result.returncode) | |
+ | |
+ | |
@click.command(context_settings={"ignore_unknown_options": True}) | |
@click.argument("requirements_in") | |
@click.argument("requirements_txt") | |
@@ -157,6 +170,8 @@ def main( | |
os.environ["CUSTOM_COMPILE_COMMAND"] = update_command | |
os.environ["PIP_CONFIG_FILE"] = os.getenv("PIP_CONFIG_FILE") or os.devnull | |
+ argv.append("pip") | |
+ argv.append("compile") | |
argv.append(f"--output-file={requirements_file_relative if UPDATE else requirements_out}") | |
argv.append( | |
requirements_in_relative | |
@@ -165,6 +180,12 @@ def main( | |
) | |
argv.extend(extra_args) | |
+ plat = sys.platform | |
+ if plat == "linux": | |
+ uv = _locate(bazel_runfiles, "uv_x86_64-unknown-linux-gnu/uv") | |
+ elif plat == "darwin": | |
+ uv = _locate(bazel_runfiles, "uv_aarch64-apple-darwin/uv") | |
+ | |
if UPDATE: | |
print("Updating " + requirements_file_relative) | |
if "BUILD_WORKSPACE_DIRECTORY" in os.environ: | |
@@ -179,7 +200,7 @@ def main( | |
resolved_requirements_file, requirements_file_tree | |
) | |
) | |
- cli(argv) | |
+ _run_uv(uv, argv) | |
requirements_file_relative_path = Path(requirements_file_relative) | |
content = requirements_file_relative_path.read_text() | |
content = content.replace(absolute_path_prefix, "") | |
@@ -188,7 +209,7 @@ def main( | |
# cli will exit(0) on success | |
try: | |
print("Checking " + requirements_file) | |
- cli(argv) | |
+ _run_uv(uv, argv) | |
print("cli() should exit", file=sys.stderr) | |
sys.exit(1) | |
except SystemExit as e: | |
diff --git a/python/pip_install/uv_versions.bzl b/python/pip_install/uv_versions.bzl | |
new file mode 100644 | |
index 0000000..3d5e012 | |
--- /dev/null | |
+++ b/python/pip_install/uv_versions.bzl | |
@@ -0,0 +1,20 @@ | |
+"This file is automatically updated by mirror_uv.sh" | |
+UV_VERSIONS = { | |
+ "0.1.2": { | |
+ "aarch64-apple-darwin": "13289f543d96c2506f7c3319e8bbc5fb944c8109374b61188593567dc2dae454", | |
+ "aarch64-unknown-linux-gnu": "5d4a1e82e78080ba308a06ecc408b3f17a13077dd35174031ed37646a4c24bfd", | |
+ "aarch64-unknown-linux-musl": "c869e839347f2fd9e0302d25470659df99918ad8bdfad2477a61393a32d1a361", | |
+ "armv7-unknown-linux-gnueabihf": "67f6d19583bb24d628c6d3a97fd412a81b0f15f88491b6b244cda2832365d3a3", | |
+ "armv7-unknown-linux-musleabihf": "7acbfaef69adffb9591766c1e6b25b5750ddac8c43bded8b8b6301852b3bb436", | |
+ "i686-pc-windows-msvc": "7c923a8c0198da91094c96fe9bf9f737e09aa67f569b5c0f76b5f492b9394190", | |
+ "i686-unknown-linux-gnu": "d5462c8746aaf8f36ca43829c6bc71f8ad303bec83d9173f44e1a3ad36d83871", | |
+ "i686-unknown-linux-musl": "aa85ccbac61b7e8153dd7239f9757ca3a95fb01d0782949f554fd88a396edb29", | |
+ "powerpc64-unknown-linux-gnu": "4055b1ce30f7786fa49fcc9dd7eb3b818aa8903930fc49a42dd11ce99507f8d9", | |
+ "powerpc64le-unknown-linux-gnu": "d36b4d8c78ad8816a760f2d888d52c732b2eae5d62fc0830e6918a0732361c96", | |
+ "s390x-unknown-linux-gnu": "5829510eb1684d2f0f58ddab2e80313e5858d5e5be6e315b9b9a74c9742f6fac", | |
+ "x86_64-apple-darwin": "20777b7f904ec9cf7e4f7ee19fe8a0b64afada1a7168908c14557130768f46b7", | |
+ "x86_64-pc-windows-msvc": "35b7fdb10fad5e644125bfb3d7f5aff83d9aca24268701359e9fef767b8a4a15", | |
+ "x86_64-unknown-linux-gnu": "89624cd11aa20bc4a841bdcb110940ecb9f05555d79c3f8f4758e34d76c5c7ca", | |
+ "x86_64-unknown-linux-musl": "f69cbd79dfea3bd69c4db064565f9eaebb86db2c0ba0609c090be86366d5db42" | |
+ } | |
+} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# put this in tools/BUILD.bazel | |
alias( | |
name = "uv", | |
actual = select({ | |
"@bazel_tools//src/conditions:linux_x86_64": "@uv_x86_64-unknown-linux-gnu//:uv", | |
"@bazel_tools//src/conditions:linux_aarch64": "@uv_aarch64-unknown-linux-gnu//:uv", | |
"@bazel_tools//src/conditions:darwin_arm64": "@uv_aarch64-apple-darwin//:uv", | |
"@bazel_tools//src/conditions:darwin_x86_64": "@uv_x86_64-apple-darwin//:uv", | |
}), | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment