-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add a virtual environment rule
- Loading branch information
Showing
3 changed files
with
85 additions
and
1 deletion.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,14 @@ | ||
py_binary( | ||
name = "poetry_deps", | ||
srcs = ["poetry_deps.py"], | ||
visibility = ["//visibility:public"], | ||
visibility = ["__subpackages__"], | ||
deps = [ | ||
"@rules_poetry_pip//:pkg", | ||
], | ||
) | ||
|
||
py_binary( | ||
name = "py_venv", | ||
srcs = ["py_venv.py"], | ||
visibility = ["__subpackages__"], | ||
) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
def _py_venv_impl(ctx): | ||
""" | ||
Rule to link Python package into a virtual environment. | ||
Arguments: | ||
ctx: The rule context. | ||
Attributes: | ||
deps: label_list The package dependencies list. | ||
Private attributes: | ||
_py_venv: | ||
Returns: | ||
The providers list or a tuple with a venv package. | ||
""" | ||
|
||
deps = ctx.attr.deps | ||
output = ctx.actions.declare_directory("venv/{}".format(ctx.label.name)) | ||
import_paths = ["{}/external/{}".format(ctx.bin_dir.path, path) for dep in deps for path in dep[PyInfo].imports.to_list()] | ||
|
||
ctx.actions.run( | ||
outputs = [output], | ||
inputs = ctx.files.deps, | ||
mnemonic = "CreateVenv", | ||
progress_message = "Creating venv {}".format(ctx.label.name), | ||
arguments = [output.path] + import_paths, | ||
use_default_shell_env = True, | ||
executable = ctx.executable._py_venv, | ||
) | ||
|
||
transitive_depsets = [dep[PyInfo].transitive_sources for dep in deps] | ||
runfiles = [output] + [item for dep in transitive_depsets for item in dep.to_list()] | ||
files = depset([output], transitive = transitive_depsets) | ||
|
||
return [ | ||
DefaultInfo(files = files, runfiles = ctx.runfiles(files = runfiles)), | ||
PyInfo(transitive_sources = files, imports = depset(["_main/" + output.short_path])), | ||
] | ||
|
||
py_venv = rule( | ||
implementation = _py_venv_impl, | ||
provides = [PyInfo], | ||
attrs = { | ||
"deps": attr.label_list(doc = "The package dependencies list"), | ||
"_py_venv": attr.label(default = ":py_venv", cfg = "exec", executable = True), | ||
}, | ||
) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import argparse | ||
from pathlib import Path | ||
|
||
SKIP_SET = {"requirements.txt"} | ||
MERGE_SET = {"bin"} | ||
|
||
if __name__ == "__main__": | ||
parser = argparse.ArgumentParser(description="Download and install a Poetry package") | ||
|
||
parser.add_argument("venv", type=Path, help="output environment directory") | ||
parser.add_argument("path", type=Path, nargs="*", help="package path") | ||
|
||
args = parser.parse_args() | ||
|
||
args.venv.mkdir(parents=True, exist_ok=True) | ||
for path in args.path: | ||
if not path.exists(): | ||
raise RuntimeError(f"Required {path} does not exist") | ||
|
||
for item in path.iterdir(): | ||
name = item.name | ||
if name in SKIP_SET: | ||
continue | ||
if name in MERGE_SET: | ||
continue # TODO | ||
|
||
# Requires permits_treeartifact_uplevel_symlinks feature | ||
symlink_path = args.venv / name | ||
target_path = item.relative_to(args.venv, walk_up=True) | ||
symlink_path.symlink_to(target_path, target_is_directory=True) |