Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Allow controlling the prefix added to repos/packages #459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 2 docs/pip.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ alias(
| Name | Description | Default Value |
| :-------------: | :-------------: | :-------------: |
| requirements_lock | A fully resolved 'requirements.txt' pip requirement file containing the transitive set of your dependencies. If this file is passed instead of 'requirements' no resolve will take place and pip_repository will create individual repositories for each of your dependencies so that wheels are fetched/built only for the targets specified by 'build/run/test'. | none |
| name | The name of the generated repository. | <code>"pip_parsed_deps"</code> |
| name | The name of the generated repository. The generated repositories containing each requirement will be of the form &lt;name&gt;_&lt;requirement-name&gt;. | <code>"pip_parsed_deps"</code> |
| kwargs | Additional keyword arguments for the underlying <code>pip_repository</code> rule. | none |


Expand Down
5 changes: 2 additions & 3 deletions 5 examples/pip_parse/BUILD
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
load(
"@pip_parsed_deps//:requirements.bzl",
"@pypi//:requirements.bzl",
"data_requirement",
"dist_info_requirement",
"entry_point",
"requirement",
)
load("@rules_python//python:defs.bzl", "py_binary", "py_test")
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
Expand Down Expand Up @@ -38,7 +37,7 @@ py_binary(
name = "main",
srcs = ["main.py"],
deps = [
requirement("requests"),
"@pypi_requests//:pkg",
],
)

Expand Down
5 changes: 2 additions & 3 deletions 5 examples/pip_parse/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,11 @@ pip_parse(
# style env vars are read, but env vars that control requests and urllib3
# can be passed
# environment = {"HTTPS_PROXY": "http://my.proxy.fun/"},

# Uses the default repository name "pip_parsed_deps"
name = "pypi",
requirements_lock = "//:requirements_lock.txt",
)

load("@pip_parsed_deps//:requirements.bzl", "install_deps")
load("@pypi//:requirements.bzl", "install_deps")

# Initialize repositories for all packages in requirements_lock.txt.
install_deps()
22 changes: 11 additions & 11 deletions 22 examples/pip_parse/pip_parse_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ def test_data(self):
self.assertListEqual(
env.split(" "),
[
"external/pip_parsed_deps_pypi__s3cmd/s3cmd-2.1.0.data/data/share/doc/packages/s3cmd/INSTALL.md",
"external/pip_parsed_deps_pypi__s3cmd/s3cmd-2.1.0.data/data/share/doc/packages/s3cmd/LICENSE",
"external/pip_parsed_deps_pypi__s3cmd/s3cmd-2.1.0.data/data/share/doc/packages/s3cmd/NEWS",
"external/pip_parsed_deps_pypi__s3cmd/s3cmd-2.1.0.data/data/share/doc/packages/s3cmd/README.md",
"external/pip_parsed_deps_pypi__s3cmd/s3cmd-2.1.0.data/data/share/man/man1/s3cmd.1",
"external/pip_parsed_deps_pypi__s3cmd/s3cmd-2.1.0.data/scripts/s3cmd",
"external/pypi_s3cmd/s3cmd-2.1.0.data/data/share/doc/packages/s3cmd/INSTALL.md",
"external/pypi_s3cmd/s3cmd-2.1.0.data/data/share/doc/packages/s3cmd/LICENSE",
"external/pypi_s3cmd/s3cmd-2.1.0.data/data/share/doc/packages/s3cmd/NEWS",
"external/pypi_s3cmd/s3cmd-2.1.0.data/data/share/doc/packages/s3cmd/README.md",
"external/pypi_s3cmd/s3cmd-2.1.0.data/data/share/man/man1/s3cmd.1",
"external/pypi_s3cmd/s3cmd-2.1.0.data/scripts/s3cmd",
],
)

Expand All @@ -61,11 +61,11 @@ def test_dist_info(self):
self.assertListEqual(
env.split(" "),
[
"external/pip_parsed_deps_pypi__requests/requests-2.25.1.dist-info/LICENSE",
"external/pip_parsed_deps_pypi__requests/requests-2.25.1.dist-info/METADATA",
"external/pip_parsed_deps_pypi__requests/requests-2.25.1.dist-info/RECORD",
"external/pip_parsed_deps_pypi__requests/requests-2.25.1.dist-info/WHEEL",
"external/pip_parsed_deps_pypi__requests/requests-2.25.1.dist-info/top_level.txt",
"external/pypi_requests/requests-2.25.1.dist-info/LICENSE",
"external/pypi_requests/requests-2.25.1.dist-info/METADATA",
"external/pypi_requests/requests-2.25.1.dist-info/RECORD",
"external/pypi_requests/requests-2.25.1.dist-info/WHEEL",
"external/pypi_requests/requests-2.25.1.dist-info/top_level.txt",
],
)

Expand Down
5 changes: 4 additions & 1 deletion 5 python/pip.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ def pip_install(requirements, name = "pip", **kwargs):
pip_repository(
name = name,
requirements = requirements,
repo_prefix = "pypi__",
**kwargs
)

Expand Down Expand Up @@ -171,7 +172,8 @@ def pip_parse(requirements_lock, name = "pip_parsed_deps", **kwargs):
of 'requirements' no resolve will take place and pip_repository will create
individual repositories for each of your dependencies so that wheels are
fetched/built only for the targets specified by 'build/run/test'.
name (str, optional): The name of the generated repository.
name (str, optional): The name of the generated repository. The generated repositories
containing each requirement will be of the form <name>_<requirement-name>.
**kwargs (dict): Additional keyword arguments for the underlying
`pip_repository` rule.
"""
Expand All @@ -182,6 +184,7 @@ def pip_parse(requirements_lock, name = "pip_parsed_deps", **kwargs):
pip_repository(
name = name,
requirements_lock = requirements_lock,
repo_prefix = "{}_".format(name),
incremental = True,
**kwargs
)
Expand Down
13 changes: 8 additions & 5 deletions 13 python/pip_install/extract_wheels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def main() -> None:
# relative requirements to be correctly resolved. The --wheel-dir is therefore required to be repointed back to the
# current calling working directory (the repo root in .../external/name), where the wheel files should be written to
pip_args = (
[sys.executable, "-m", "pip"] +
(["--isolated"] if args.isolated else []) +
[sys.executable, "-m", "pip"] +
(["--isolated"] if args.isolated else []) +
["wheel", "-r", args.requirements] +
["--wheel-dir", os.getcwd()] +
deserialized_args["extra_pip_args"]
Expand All @@ -86,11 +86,14 @@ def main() -> None:
repo_label = "@%s" % args.repo

targets = [
'"%s%s"'
% (
'"{}{}"'.format(
repo_label,
bazel.extract_wheel(
whl, extras, deserialized_args["pip_data_exclude"], args.enable_implicit_namespace_pkgs
whl,
extras,
deserialized_args["pip_data_exclude"],
args.enable_implicit_namespace_pkgs,
args.repo_prefix,
),
)
for whl in glob.glob("*.whl")
Expand Down
6 changes: 5 additions & 1 deletion 6 python/pip_install/extract_wheels/lib/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ def parse_common_args(parser: ArgumentParser) -> ArgumentParser:
action="store",
help="Extra environment variables to set on the pip environment.",
)
parser.add_argument(
"--repo-prefix",
required=True,
help="Prefix to prepend to packages",
)
return parser


Expand All @@ -45,4 +50,3 @@ def deserialize_structured_args(args):
else:
args[arg_name] = []
return args

11 changes: 10 additions & 1 deletion 11 python/pip_install/extract_wheels/lib/arguments_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,25 @@ def test_arguments(self) -> None:
parser = argparse.ArgumentParser()
parser = arguments.parse_common_args(parser)
repo_name = "foo"
repo_prefix = "pypi_"
index_url = "--index_url=pypi.org/simple"
extra_pip_args = [index_url]
args_dict = vars(parser.parse_args(
args=["--repo", repo_name, f"--extra_pip_args={json.dumps({'arg': extra_pip_args})}"]))
args=[
"--repo",
repo_name,
f"--extra_pip_args={json.dumps({'arg': extra_pip_args})}",
"--repo-prefix",
repo_prefix,
]
))
args_dict = arguments.deserialize_structured_args(args_dict)
self.assertIn("repo", args_dict)
self.assertIn("extra_pip_args", args_dict)
self.assertEqual(args_dict["pip_data_exclude"], [])
self.assertEqual(args_dict["enable_implicit_namespace_pkgs"], False)
self.assertEqual(args_dict["repo"], repo_name)
self.assertEqual(args_dict["repo_prefix"], repo_prefix)
self.assertEqual(args_dict["extra_pip_args"], extra_pip_args)

def test_deserialize_structured_args(self) -> None:
Expand Down
42 changes: 13 additions & 29 deletions 42 python/pip_install/extract_wheels/lib/bazel.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,17 +215,7 @@ def install_deps():
)


DEFAULT_PACKAGE_PREFIX = "pypi__"


def whl_library_repo_prefix(parent_repo: str) -> str:
return "{parent}_{default_package_prefix}".format(
parent=parent_repo,
default_package_prefix=DEFAULT_PACKAGE_PREFIX
)


def sanitise_name(name: str, prefix: str = DEFAULT_PACKAGE_PREFIX) -> str:
def sanitise_name(name: str, prefix: str) -> str:
"""Sanitises the name to be compatible with Bazel labels.

There are certain requirements around Bazel labels that we need to consider. From the Bazel docs:
Expand Down Expand Up @@ -268,12 +258,12 @@ def setup_namespace_pkg_compatibility(wheel_dir: str) -> None:
namespace_pkgs.add_pkgutil_style_namespace_pkg_init(ns_pkg_dir)


def sanitised_library_label(whl_name: str) -> str:
return '"//%s"' % sanitise_name(whl_name)
def sanitised_library_label(whl_name: str, prefix: str) -> str:
return '"//%s"' % sanitise_name(whl_name, prefix)


def sanitised_file_label(whl_name: str) -> str:
return '"//%s:%s"' % (sanitise_name(whl_name), WHEEL_FILE_LABEL)
def sanitised_file_label(whl_name: str, prefix: str) -> str:
return '"//%s:%s"' % (sanitise_name(whl_name, prefix), WHEEL_FILE_LABEL)


def _whl_name_to_repo_root(whl_name: str, repo_prefix: str) -> str:
Expand All @@ -293,8 +283,8 @@ def extract_wheel(
extras: Dict[str, Set[str]],
pip_data_exclude: List[str],
enable_implicit_namespace_pkgs: bool,
repo_prefix: str,
incremental: bool = False,
incremental_repo_prefix: Optional[str] = None,
) -> Optional[str]:
"""Extracts wheel into given directory and creates py_library and filegroup targets.

Expand All @@ -305,8 +295,6 @@ def extract_wheel(
enable_implicit_namespace_pkgs: if true, disables conversion of implicit namespace packages and will unzip as-is
incremental: If true the extract the wheel in a format suitable for an external repository. This
effects the names of libraries and their dependencies, which point to other external repositories.
incremental_repo_prefix: If incremental is true, use this prefix when creating labels from wheel
names instead of the default.

Returns:
The Bazel label for the extracted wheel, in the form '//path/to/wheel'.
Expand All @@ -316,7 +304,7 @@ def extract_wheel(
if incremental:
directory = "."
else:
directory = sanitise_name(whl.name)
directory = sanitise_name(whl.name, prefix=repo_prefix)

os.mkdir(directory)
# copy the original wheel
Expand All @@ -333,25 +321,21 @@ def extract_wheel(
whl_deps = sorted(whl.dependencies(extras_requested))

if incremental:
# check for mypy Optional validity
if incremental_repo_prefix is None:
raise TypeError(
"incremental_repo_prefix arguement cannot be None if incremental == True")
sanitised_dependencies = [
sanitised_repo_library_label(d, repo_prefix=incremental_repo_prefix) for d in whl_deps
sanitised_repo_library_label(d, repo_prefix=repo_prefix) for d in whl_deps
]
sanitised_wheel_file_dependencies = [
sanitised_repo_file_label(d, repo_prefix=incremental_repo_prefix) for d in whl_deps
sanitised_repo_file_label(d, repo_prefix=repo_prefix) for d in whl_deps
]
else:
sanitised_dependencies = [
sanitised_library_label(d) for d in whl_deps
sanitised_library_label(d, prefix=repo_prefix) for d in whl_deps
]
sanitised_wheel_file_dependencies = [
sanitised_file_label(d) for d in whl_deps
sanitised_file_label(d, prefix=repo_prefix) for d in whl_deps
]

library_name = PY_LIBRARY_LABEL if incremental else sanitise_name(whl.name)
library_name = PY_LIBRARY_LABEL if incremental else sanitise_name(whl.name, repo_prefix)

directory_path = Path(directory)
entry_points = []
Expand All @@ -365,7 +349,7 @@ def extract_wheel(

with open(os.path.join(directory, "BUILD.bazel"), "w") as build_file:
contents = generate_build_file_contents(
library_name,
PY_LIBRARY_LABEL if incremental else sanitise_name(whl.name, repo_prefix),
sanitised_dependencies,
sanitised_wheel_file_dependencies,
pip_data_exclude,
Expand Down
8 changes: 4 additions & 4 deletions 8 python/pip_install/extract_wheels/lib/whl_filegroup_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ def tearDown(self):

def _run(
self,
repo_prefix: str,
incremental: bool = False,
incremental_repo_prefix: Optional[str] = None,
) -> None:
generated_bazel_dir = bazel.extract_wheel(
self.wheel_path,
extras={},
pip_data_exclude=[],
enable_implicit_namespace_pkgs=False,
incremental=incremental,
incremental_repo_prefix=incremental_repo_prefix
repo_prefix=repo_prefix
)
# Take off the leading // from the returned label.
# Assert that the raw wheel ends up in the package.
Expand All @@ -44,10 +44,10 @@ def _run(
self.assertIn('filegroup', build_file_content)

def test_nonincremental(self) -> None:
self._run()
self._run(repo_prefix="prefix_")

def test_incremental(self) -> None:
self._run(incremental=True, incremental_repo_prefix="test")
self._run(incremental=True, repo_prefix="prefix_")


if __name__ == "__main__":
Expand Down
19 changes: 11 additions & 8 deletions 19 python/pip_install/parse_requirements_to_bzl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,19 @@ def generate_parsed_requirements_contents(all_args: argparse.Namespace) -> str:
args.setdefault("python_interpreter", sys.executable)
# Pop this off because it wont be used as a config argument to the whl_library rule.
requirements_lock = args.pop("requirements_lock")
repo_prefix = bazel.whl_library_repo_prefix(args["repo"])

install_req_and_lines = parse_install_requirements(requirements_lock, args["extra_pip_args"])
repo_names_and_reqs = repo_names_and_requirements(install_req_and_lines, repo_prefix)
all_requirements = ", ".join(
[bazel.sanitised_repo_library_label(ir.name, repo_prefix=repo_prefix) for ir, _ in install_req_and_lines]
)
all_whl_requirements = ", ".join(
[bazel.sanitised_repo_file_label(ir.name, repo_prefix=repo_prefix) for ir, _ in install_req_and_lines]
repo_names_and_reqs = repo_names_and_requirements(
install_req_and_lines, args["repo_prefix"]
)
all_requirements = ", ".join([
bazel.sanitised_repo_library_label(ir.name, repo_prefix=args["repo_prefix"])
for ir, _ in install_req_and_lines
])
all_whl_requirements = ", ".join([
bazel.sanitised_repo_file_label(ir.name, repo_prefix=args["repo_prefix"])
for ir, _ in install_req_and_lines
])
return textwrap.dedent("""\
load("@rules_python//python/pip_install:pip_repository.bzl", "whl_library")

Expand Down Expand Up @@ -112,7 +115,7 @@ def install_deps():
all_whl_requirements=all_whl_requirements,
repo_names_and_reqs=repo_names_and_reqs,
args=args,
repo_prefix=repo_prefix,
repo_prefix=args["repo_prefix"],
py_library_label=bazel.PY_LIBRARY_LABEL,
wheel_file_label=bazel.WHEEL_FILE_LABEL,
data_label=bazel.DATA_LABEL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def main() -> None:

pip_args = (
[sys.executable, "-m", "pip"] +
(["--isolated"] if args.isolated else []) +
(["--isolated"] if args.isolated else []) +
["wheel", "--no-deps"] +
deserialized_args["extra_pip_args"]
)
Expand Down Expand Up @@ -67,5 +67,5 @@ def main() -> None:
deserialized_args["pip_data_exclude"],
args.enable_implicit_namespace_pkgs,
incremental=True,
incremental_repo_prefix=bazel.whl_library_repo_prefix(args.repo)
repo_prefix=args.repo_prefix,
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from python.pip_install.parse_requirements_to_bzl import generate_parsed_requirements_contents
from python.pip_install.extract_wheels.lib.bazel import (
sanitised_repo_library_label,
whl_library_repo_prefix,
sanitised_repo_file_label
)

Expand All @@ -21,7 +20,7 @@ def test_generated_requirements_bzl(self) -> None:
requirements_lock.flush()
args = argparse.Namespace()
args.requirements_lock = requirements_lock.name
args.repo = "pip_parsed_deps"
args.repo_prefix = "pip_parsed_deps_pypi__"
extra_pip_args = ["--index-url=pypi.org/simple"]
pip_data_exclude = ["**.foo"]
args.extra_pip_args = json.dumps({"arg": extra_pip_args})
Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.