Skip to content

Commit

Permalink
Added setup_py_script macro to pip_parse and pip_install.
Browse files Browse the repository at this point in the history
  • Loading branch information
UebelAndre committed Mar 13, 2022
1 parent 884afdc commit 669d55e
Show file tree
Hide file tree
Showing 10 changed files with 229 additions and 2 deletions.
22 changes: 22 additions & 0 deletions docs/pip.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ alias(
)
```

Similar to the `entry_point` macro, `setup_py_script` allows accessing
[`setup.py` generated scripts][scripts]:
```python
load("@pip_deps//:requirements.bzl", "setup_py_script")
alias(
name = "flake8",
actual = setup_py_script("flake8"),
)
```
[scripts]: https://docs.python.org/3/distutils/setupscript.html#installing-scripts


**PARAMETERS**

Expand Down Expand Up @@ -218,6 +229,17 @@ alias(
)
```

Similar to the `entry_point` macro, `setup_py_script` allows accessing
[`setup.py` generated scripts][scripts]:
```python
load("@pip_deps//:requirements.bzl", "setup_py_script")
alias(
name = "flake8",
actual = setup_py_script("flake8"),
)
```
[scripts]: https://docs.python.org/3/distutils/setupscript.html#installing-scripts


**PARAMETERS**

Expand Down
8 changes: 8 additions & 0 deletions examples/pip_install/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ load(
"dist_info_requirement",
"entry_point",
"requirement",
"setup_py_script",
)
load("@rules_python//python:defs.bzl", "py_binary", "py_test")
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
Expand Down Expand Up @@ -58,6 +59,11 @@ alias(
actual = entry_point("yamllint"),
)

alias(
name = "s3cmd",
actual = setup_py_script("s3cmd"),
)

# Check that our compiled requirements are up-to-date
compile_pip_requirements(
name = "requirements",
Expand All @@ -69,11 +75,13 @@ py_test(
name = "pip_install_test",
srcs = ["pip_install_test.py"],
data = [
":s3cmd",
":yamllint",
data_requirement("s3cmd"),
dist_info_requirement("boto3"),
],
env = {
"S3CMD_SETUP_PY_SCRIPT": "$(rootpath :s3cmd)",
"WHEEL_DATA_CONTENTS": "$(rootpaths {})".format(data_requirement("s3cmd")),
"WHEEL_DIST_INFO_CONTENTS": "$(rootpaths {})".format(dist_info_requirement("boto3")),
"YAMLLINT_ENTRY_POINT": "$(rootpath :yamllint)",
Expand Down
23 changes: 23 additions & 0 deletions examples/pip_install/pip_install_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3

import os
import platform
import subprocess
import unittest
from pathlib import Path
Expand Down Expand Up @@ -31,6 +32,28 @@ def test_entry_point(self):
)
self.assertEqual(proc.stdout.decode("utf-8").strip(), "yamllint 1.26.3")

@unittest.skipIf(
platform.system() == "Windows",
"The `setup_py_script` macro does not currently support windows",
)
def test_setup_py_script_s3cmd(self):
env = os.environ.get("S3CMD_SETUP_PY_SCRIPT")
self.assertIsNotNone(env)

r = runfiles.Create()

# To find an external target, this must use `{workspace_name}/$(rootpath @external_repo//:target)`
script = Path(r.Rlocation("rules_python_pip_install_example/{}".format(env)))
self.assertTrue(script.exists())

proc = subprocess.run(
[str(script), "--version"],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
self.assertEqual(proc.stdout.decode("utf-8").strip(), "s3cmd version 2.1.0")

def test_data(self):
env = os.environ.get("WHEEL_DATA_CONTENTS")
self.assertIsNotNone(env)
Expand Down
8 changes: 8 additions & 0 deletions examples/pip_parse/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ load(
"data_requirement",
"dist_info_requirement",
"entry_point",
"setup_py_script",
)
load("@rules_python//python:defs.bzl", "py_binary", "py_test")
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
Expand Down Expand Up @@ -55,6 +56,11 @@ alias(
actual = entry_point("yamllint"),
)

alias(
name = "s3cmd",
actual = setup_py_script("s3cmd"),
)

# This rule adds a convenient way to update the requirements file.
compile_pip_requirements(
name = "requirements",
Expand All @@ -68,11 +74,13 @@ py_test(
name = "pip_parse_test",
srcs = ["pip_parse_test.py"],
data = [
":s3cmd",
":yamllint",
data_requirement("s3cmd"),
dist_info_requirement("requests"),
],
env = {
"S3CMD_SETUP_PY_SCRIPT": "$(rootpath :s3cmd)",
"WHEEL_DATA_CONTENTS": "$(rootpaths {})".format(data_requirement("s3cmd")),
"WHEEL_DIST_INFO_CONTENTS": "$(rootpaths {})".format(dist_info_requirement("requests")),
"YAMLLINT_ENTRY_POINT": "$(rootpath :yamllint)",
Expand Down
23 changes: 23 additions & 0 deletions examples/pip_parse/pip_parse_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3

import os
import platform
import subprocess
import unittest
from pathlib import Path
Expand Down Expand Up @@ -29,6 +30,28 @@ def test_entry_point(self):
)
self.assertEqual(proc.stdout.decode("utf-8").strip(), "yamllint 1.26.3")

@unittest.skipIf(
platform.system() == "Windows",
"The `setup_py_script` macro does not currently support windows",
)
def test_setup_py_script_s3cmd(self):
env = os.environ.get("S3CMD_SETUP_PY_SCRIPT")
self.assertIsNotNone(env)

r = runfiles.Create()

# To find an external target, this must use `{workspace_name}/$(rootpath @external_repo//:target)`
script = Path(r.Rlocation("rules_python_pip_parse_example/{}".format(env)))
self.assertTrue(script.exists())

proc = subprocess.run(
[str(script), "--version"],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
self.assertEqual(proc.stdout.decode("utf-8").strip(), "s3cmd version 2.1.0")

def test_data(self):
env = os.environ.get("WHEEL_DATA_CONTENTS")
self.assertIsNotNone(env)
Expand Down
22 changes: 22 additions & 0 deletions python/pip.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ def pip_install(requirements, name = "pip", **kwargs):
)
```
Similar to the `entry_point` macro, `setup_py_script` allows accessing
[`setup.py` generated scripts][scripts]:
```python
load("@pip_deps//:requirements.bzl", "setup_py_script")
alias(
name = "flake8",
actual = setup_py_script("flake8"),
)
```
[scripts]: https://docs.python.org/3/distutils/setupscript.html#installing-scripts
Args:
requirements (Label): A 'requirements.txt' pip requirements file.
name (str, optional): A unique name for the created external repository (default 'pip').
Expand Down Expand Up @@ -167,6 +178,17 @@ def pip_parse(requirements_lock, name = "pip_parsed_deps", **kwargs):
)
```
Similar to the `entry_point` macro, `setup_py_script` allows accessing
[`setup.py` generated scripts][scripts]:
```python
load("@pip_deps//:requirements.bzl", "setup_py_script")
alias(
name = "flake8",
actual = setup_py_script("flake8"),
)
```
[scripts]: https://docs.python.org/3/distutils/setupscript.html#installing-scripts
Args:
requirements_lock (Label): A fully resolved 'requirements.txt' pip requirement file
containing the transitive set of your dependencies. If this file is passed instead
Expand Down
3 changes: 3 additions & 0 deletions python/pip_install/extract_wheels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ def main() -> None:
enable_implicit_namespace_pkgs=args.enable_implicit_namespace_pkgs,
repo_prefix=args.repo_prefix,
annotation=annotations.get(name),
# Only `pip_install` uses this path so the `repo` arg
# is what's expected by this parameter.
pip_install_repo_name=args.repo,
),
)
for whl, name in reqs.items()
Expand Down
Loading

0 comments on commit 669d55e

Please sign in to comment.