Skip to content

Commit

Permalink
Add sync_venv macro (#172)
Browse files Browse the repository at this point in the history
In #166, create_venv was switched to perform a `uv pip sync`, but this has slightly different semantics than `uv pip install`. The latter will expand the input requirements as needed, while the former treats the input as a complete lockfile. To achieve both behaviors, revert `create_venv` to its old functionality and add a `sync_venv` macro that runs `uv pip sync`.
  • Loading branch information
mark-thm authored Nov 19, 2024
1 parent fb96bb2 commit 7125645
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 6 deletions.
7 changes: 6 additions & 1 deletion examples/typical/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
load("@rules_uv//uv:pip.bzl", "pip_compile")
load("@rules_uv//uv:venv.bzl", "create_venv")
load("@rules_uv//uv:venv.bzl", "create_venv", "sync_venv")

pip_compile(name = "generate_requirements_txt")

Expand All @@ -25,3 +25,8 @@ create_venv(
"site_packages_extra/sitecustomize.py",
],
)

sync_venv(
name = "sync-venv",
destination_folder = ".sync-venv",
)
1 change: 1 addition & 0 deletions uv/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports_files([
"create_venv.sh",
"pip_compile_test.sh",
"pip_compile.sh",
"sync_venv.sh",
])

bzl_library(
Expand Down
4 changes: 2 additions & 2 deletions uv/private/create_venv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ then
exit -1
fi

"$UV" venv "$BUILD_WORKSPACE_DIRECTORY/$target" --python "$PYTHON" --allow-existing
"$UV" venv "$BUILD_WORKSPACE_DIRECTORY/$target" --python "$PYTHON"
source "$BUILD_WORKSPACE_DIRECTORY/$target/bin/activate"
"$UV" pip sync "$REQUIREMENTS_TXT" {{args}}
"$UV" pip install -r "$REQUIREMENTS_TXT" {{args}}

site_packages_extra_files=({{site_packages_extra_files}})
if [ ! -z ${site_packages_extra_files+x} ]; then
Expand Down
42 changes: 42 additions & 0 deletions uv/private/sync_venv.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash

set -euo pipefail

UV="{{uv}}"
RESOLVED_PYTHON="{{resolved_python}}"
REQUIREMENTS_TXT="{{requirements_txt}}"

PYTHON="$(realpath "$RESOLVED_PYTHON")"

bold="$(tput bold)"
normal="$(tput sgr0)"

if [ $# -gt 1 ]; then
echo "create-venv takes one optional argument, the path to the virtual environment."
exit -1
elif [ $# == 0 ] || [ -z "$1" ]; then
target="{{destination_folder}}"
else
target="$1"
fi

if [ "${target}" == "/" ] || [ "${target}" == "." ]
then
echo "${bold}Invalid venv target '${target}'${normal}"
exit -1
fi

"$UV" venv "$BUILD_WORKSPACE_DIRECTORY/$target" --python "$PYTHON" --allow-existing
source "$BUILD_WORKSPACE_DIRECTORY/$target/bin/activate"
"$UV" pip sync "$REQUIREMENTS_TXT" {{args}}

site_packages_extra_files=({{site_packages_extra_files}})
if [ ! -z ${site_packages_extra_files+x} ]; then
site_packages_dir=$(find "$BUILD_WORKSPACE_DIRECTORY/$target/lib" -type d -name 'site-packages')
for file in "${site_packages_extra_files[@]}"; do
cp "$file" "$site_packages_dir"/
done
fi

echo "${bold}Created '${target}', to activate run:${normal}"
echo " source ${target}/bin/activate"
16 changes: 14 additions & 2 deletions uv/private/venv.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def _runfiles(ctx):

def _venv_impl(ctx):
executable = ctx.actions.declare_file(ctx.attr.name)
_uv_template(ctx, ctx.file._template, executable)
_uv_template(ctx, ctx.file.template, executable)
return DefaultInfo(
executable = executable,
runfiles = _runfiles(ctx),
Expand All @@ -43,7 +43,7 @@ _venv = rule(
"site_packages_extra_files": attr.label_list(default = [], doc = "Files to add to the site-packages folder inside the virtual environment. Useful for adding `sitecustomize.py` or `.pth` files", allow_files = True),
"requirements_txt": attr.label(mandatory = True, allow_single_file = True),
"_uv": attr.label(default = "@multitool//tools/uv", executable = True, cfg = transition_to_target),
"_template": attr.label(default = "//uv/private:create_venv.sh", allow_single_file = True),
"template": attr.label(allow_single_file = True),
"uv_args": attr.string_list(default = []),
},
toolchains = [_PY_TOOLCHAIN],
Expand All @@ -59,4 +59,16 @@ def create_venv(name, requirements_txt = None, target_compatible_with = None, de
requirements_txt = requirements_txt or "//:requirements.txt",
target_compatible_with = target_compatible_with,
uv_args = uv_args,
template = "@rules_uv//uv/private:create_venv.sh",
)

def sync_venv(name, requirements_txt = None, target_compatible_with = None, destination_folder = None, site_packages_extra_files = [], uv_args = []):
_venv(
name = name,
destination_folder = destination_folder,
site_packages_extra_files = site_packages_extra_files,
requirements_txt = requirements_txt or "//:requirements.txt",
target_compatible_with = target_compatible_with,
uv_args = uv_args,
template = "@rules_uv//uv/private:sync_venv.sh",
)
3 changes: 2 additions & 1 deletion uv/venv.bzl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"uv based virtual env generation"

load("//uv/private:venv.bzl", _create_venv = "create_venv")
load("//uv/private:venv.bzl", _create_venv = "create_venv", _sync_venv = "sync_venv")

create_venv = _create_venv
sync_venv = _sync_venv

0 comments on commit 7125645

Please sign in to comment.