Skip to content

Commit bb94f11

Browse files
authored
Add handling of pydist resource paths (#306)
1 parent 0336b92 commit bb94f11

File tree

6 files changed

+88
-4
lines changed

6 files changed

+88
-4
lines changed

.github/workflows/test.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,17 @@ jobs:
130130
pushd docs
131131
make html
132132
popd
133+
134+
check: # This job does nothing and is only used for the branch protection
135+
if: always()
136+
needs:
137+
- check-links
138+
- test
139+
- docs
140+
- pre-commit
141+
runs-on: ubuntu-latest
142+
steps:
143+
- name: Decide whether the needed jobs succeeded or failed
144+
uses: re-actors/alls-green@release/v1
145+
with:
146+
jobs: ${{ toJSON(needs) }}

docs/source/how_to_guides/write_config.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,14 @@ post-version-spec = "dev"
8484
```
8585

8686
This will bump it to the next minor release with a `.dev0` suffix.
87+
88+
## Ensuring Python Resource Files
89+
90+
If you want to ensure that resource files are included in your installed Python
91+
package
92+
(from an sdist or a wheel), include configuration like the following:
93+
94+
```toml
95+
[tool.jupyter-releaser.options]
96+
pydist_resource_paths = ["my-package/img1.png", "my-package/foo.json"]
97+
```

jupyter_releaser/cli.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,13 @@ def main(force):
248248
envvar="RH_PYDIST_CHECK_CMD",
249249
default="twine check --strict",
250250
help="The command to use to check a python distribution file",
251-
)
251+
),
252+
click.option(
253+
"--pydist-resource-paths",
254+
envvar="RH_PYDIST_RESOURCE_PATHS",
255+
multiple=True,
256+
help="Resource paths that should be available when installed",
257+
),
252258
]
253259

254260

@@ -410,14 +416,19 @@ def build_python(dist_dir, python_packages):
410416
@add_options(check_imports_options)
411417
@add_options(pydist_check_options)
412418
@use_checkout_dir()
413-
def check_python(dist_dir, check_imports, pydist_check_cmd):
419+
def check_python(dist_dir, check_imports, pydist_check_cmd, pydist_resource_paths):
414420
"""Check Python dist files"""
415421
for dist_file in glob(f"{dist_dir}/*"):
416422
if Path(dist_file).suffix not in [".gz", ".whl"]:
417423
util.log(f"Skipping non-python dist file {dist_file}")
418424
continue
419425

420-
python.check_dist(dist_file, python_imports=check_imports, check_cmd=pydist_check_cmd)
426+
python.check_dist(
427+
dist_file,
428+
python_imports=check_imports,
429+
check_cmd=pydist_check_cmd,
430+
resource_paths=pydist_resource_paths,
431+
)
421432

422433

423434
@main.command()
@@ -589,6 +600,7 @@ def extract_release(
589600
release_url,
590601
npm_install_options,
591602
pydist_check_cmd,
603+
pydist_resource_paths,
592604
check_imports,
593605
):
594606
"""Download and verify assets from a draft GitHub release"""
@@ -599,6 +611,7 @@ def extract_release(
599611
release_url,
600612
npm_install_options,
601613
pydist_check_cmd,
614+
pydist_resource_paths,
602615
check_imports,
603616
)
604617

jupyter_releaser/lib.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ def extract_release(
313313
release_url,
314314
npm_install_options,
315315
pydist_check_cmd,
316+
pydist_resource_paths,
316317
python_imports,
317318
):
318319
"""Download and verify assets from a draft GitHub release"""
@@ -363,6 +364,7 @@ def extract_release(
363364
dist / asset.name,
364365
check_cmd=pydist_check_cmd,
365366
python_imports=python_imports,
367+
resource_paths=pydist_resource_paths,
366368
)
367369
elif suffix == ".tgz":
368370
pass # already handled

jupyter_releaser/python.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,15 @@ def build_dist(dist_dir, clean=True):
3232
util.run(f"python setup.py bdist_wheel --dist-dir {dest}", quiet=True)
3333

3434

35-
def check_dist(dist_file, test_cmd="", python_imports=None, check_cmd="twine check --strict"):
35+
def check_dist(
36+
dist_file,
37+
test_cmd="",
38+
python_imports=None,
39+
check_cmd="twine check --strict",
40+
resource_paths=None,
41+
):
3642
"""Check a Python package locally (not as a cli)"""
43+
resource_paths = resource_paths or []
3744
dist_file = util.normalize_path(dist_file)
3845
util.run(f"{check_cmd} {dist_file}")
3946

@@ -74,6 +81,18 @@ def check_dist(dist_file, test_cmd="", python_imports=None, check_cmd="twine che
7481
'You may need to set "check_imports" to appropriate Python package names in the config file.'
7582
)
7683
raise e
84+
for resource_path in resource_paths:
85+
name, _, rest = resource_path.partition("/")
86+
test_file = Path(td) / "test_path.py"
87+
test_text = f"""
88+
import importlib.resources
89+
with importlib.resources.path('{name}','{rest}') as resource_path:
90+
assert resource_path.exists()
91+
"""
92+
test_file.write_text(test_text, encoding="utf-8")
93+
test_file = util.normalize_path(test_file)
94+
cmd = f"{bin_path}/python {test_file}"
95+
util.run(cmd)
7796

7897

7998
def get_pypi_token(release_url, python_package):

jupyter_releaser/tests/test_cli.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ def test_list_envvars(runner):
161161
post-version-message: RH_POST_VERSION_MESSAGE
162162
post-version-spec: RH_POST_VERSION_SPEC
163163
pydist-check-cmd: RH_PYDIST_CHECK_CMD
164+
pydist-resource-paths: RH_PYDIST_RESOURCE_PATHS
164165
python-packages: RH_PYTHON_PACKAGES
165166
ref: RH_REF
166167
release-message: RH_RELEASE_MESSAGE
@@ -437,6 +438,30 @@ def test_check_python_different_names(
437438
monkeypatch, py_package_different_names, runner, build_mock, git_prep
438439
):
439440
monkeypatch.setenv("RH_CHECK_IMPORTS", "foobar")
441+
442+
443+
def test_check_python_resource_path(monkeypatch, py_package, runner, build_mock, git_prep):
444+
monkeypatch.setenv("RH_PYDIST_RESOURCE_PATHS", "foo/baz.txt")
445+
446+
# Convert the package to use a package dir.
447+
foo_dir = Path(util.CHECKOUT_NAME) / "foo"
448+
foo_dir.mkdir()
449+
shutil.move(Path(util.CHECKOUT_NAME) / "foo.py", foo_dir / "__init__.py")
450+
451+
path = foo_dir / "baz.txt"
452+
path.write_text("hello", encoding="utf-8")
453+
454+
manifest = Path(util.CHECKOUT_NAME) / "MANIFEST.in"
455+
manifest_text = manifest.read_text(encoding="utf-8")
456+
manifest_text += "\ninclude foo/baz.txt\n"
457+
manifest.write_text(manifest_text, encoding="utf-8")
458+
459+
setup_cfg_path = Path(util.CHECKOUT_NAME) / "setup.cfg"
460+
setup_cfg_text = setup_cfg_path.read_text(encoding="utf-8")
461+
setup_cfg_text = setup_cfg_text.replace("foo.__version__", "foo.__init__.__version__")
462+
setup_cfg_text = setup_cfg_text.replace("py_modules = foo", "")
463+
setup_cfg_path.write_text(setup_cfg_text, encoding="utf-8")
464+
440465
runner(["build-python"])
441466
runner(["check-python"])
442467

0 commit comments

Comments
 (0)