hatch_jupyter_builder-0.8.3/.pre-commit-config.yaml0000644000000000000000000000170513615410400017305 0ustar00ci: autoupdate_schedule: monthly repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: - id: check-case-conflict - id: check-ast - id: check-docstring-first - id: check-executables-have-shebangs - id: check-added-large-files - id: check-case-conflict - id: check-merge-conflict - id: check-json - id: check-toml - id: check-yaml - id: debug-statements - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema rev: 0.22.0 hooks: - id: check-github-workflows - repo: https://github.com/executablebooks/mdformat rev: 0.7.16 hooks: - id: mdformat - repo: https://github.com/psf/black rev: 23.3.0 hooks: - id: black - repo: https://github.com/charliermarsh/ruff-pre-commit rev: v0.0.260 hooks: - id: ruff args: ["--fix"] hatch_jupyter_builder-0.8.3/.readthedocs.yml0000644000000000000000000000030513615410400016105 0ustar00 version: 2 sphinx: configuration: docs/conf.py python: version: 3.8 install: # install itself with pip install . - method: pip path: . extra_requirements: - docs hatch_jupyter_builder-0.8.3/CHANGELOG.md0000644000000000000000000006022313615410400014635 0ustar00# Changelog ## 0.8.3 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/v0.8.2...110ef7d5cc4b6118d21c130965f6e88ddf31ff22)) ### Maintenance and upkeep improvements - Use local coverage [#114](https://github.com/jupyterlab/hatch-jupyter-builder/pull/114) ([@blink1073](https://github.com/blink1073)) - Add more linting [#106](https://github.com/jupyterlab/hatch-jupyter-builder/pull/106) ([@blink1073](https://github.com/blink1073)) - Fix test typing [#104](https://github.com/jupyterlab/hatch-jupyter-builder/pull/104) ([@blink1073](https://github.com/blink1073)) - Add more ci checks [#102](https://github.com/jupyterlab/hatch-jupyter-builder/pull/102) ([@blink1073](https://github.com/blink1073)) ### Documentation improvements - Add license classifier [#111](https://github.com/jupyterlab/hatch-jupyter-builder/pull/111) ([@fcollonval](https://github.com/fcollonval)) - Add full api docs [#103](https://github.com/jupyterlab/hatch-jupyter-builder/pull/103) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-12-13&to=2023-04-14&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ablink1073+updated%3A2022-12-13..2023-04-14&type=Issues) | [@codecov](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Acodecov+updated%3A2022-12-13..2023-04-14&type=Issues) | [@fcollonval](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Afcollonval+updated%3A2022-12-13..2023-04-14&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Apre-commit-ci+updated%3A2022-12-13..2023-04-14&type=Issues) ## 0.8.2 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/v0.8.1...dacbd9ba0115b0991870bf2b7d741ada0d1d4ffd)) ### Enhancements made - Adopt ruff and reduce pre-commit usage [#97](https://github.com/jupyterlab/hatch-jupyter-builder/pull/97) ([@blink1073](https://github.com/blink1073)) ### Bugs fixed - Fix shared data path handling in migration [#101](https://github.com/jupyterlab/hatch-jupyter-builder/pull/101) ([@blink1073](https://github.com/blink1073)) - Handle no pyproject file in migration [#100](https://github.com/jupyterlab/hatch-jupyter-builder/pull/100) ([@blink1073](https://github.com/blink1073)) ### Maintenance and upkeep improvements - Allow releasing from repo [#99](https://github.com/jupyterlab/hatch-jupyter-builder/pull/99) ([@blink1073](https://github.com/blink1073)) - Use base setup dependency type [#95](https://github.com/jupyterlab/hatch-jupyter-builder/pull/95) ([@blink1073](https://github.com/blink1073)) - More CI Cleanup [#93](https://github.com/jupyterlab/hatch-jupyter-builder/pull/93) ([@blink1073](https://github.com/blink1073)) - Cleanup workflows [#92](https://github.com/jupyterlab/hatch-jupyter-builder/pull/92) ([@blink1073](https://github.com/blink1073)) - Bump Python Version Support to 3.8-3.11 [#89](https://github.com/jupyterlab/hatch-jupyter-builder/pull/89) ([@blink1073](https://github.com/blink1073)) - Maintenance updates [#85](https://github.com/jupyterlab/hatch-jupyter-builder/pull/85) ([@blink1073](https://github.com/blink1073)) - Remove flake8 file [#83](https://github.com/jupyterlab/hatch-jupyter-builder/pull/83) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-10-14&to=2022-12-13&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ablink1073+updated%3A2022-10-14..2022-12-13&type=Issues) | [@codecov](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Acodecov+updated%3A2022-10-14..2022-12-13&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Apre-commit-ci+updated%3A2022-10-14..2022-12-13&type=Issues) ## 0.8.1 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/v0.8.0...8257c8561d946def6193ad63afa446e0b261cb39)) ### Bugs fixed - Fix handling of bool args [#82](https://github.com/jupyterlab/hatch-jupyter-builder/pull/82) ([@blink1073](https://github.com/blink1073)) ### Maintenance and upkeep improvements ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-10-10&to=2022-10-14&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ablink1073+updated%3A2022-10-10..2022-10-14&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Apre-commit-ci+updated%3A2022-10-10..2022-10-14&type=Issues) ## 0.8.0 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/v0.7.1...e1876a30d1df8e475aa4c2db347beb4f9a261e4d)) ### Enhancements made - Add optional-editable-build [#80](https://github.com/jupyterlab/hatch-jupyter-builder/pull/80) ([@blink1073](https://github.com/blink1073)) ### Maintenance and upkeep improvements - Use hatch envs [#79](https://github.com/jupyterlab/hatch-jupyter-builder/pull/79) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-10-03&to=2022-10-10&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ablink1073+updated%3A2022-10-03..2022-10-10&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Apre-commit-ci+updated%3A2022-10-03..2022-10-10&type=Issues) ## 0.7.1 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/v0.7.0...55af542dae3a7cf7e35e9642a9a8879d5bdfee9f)) ### Bugs fixed - Only install pre-commit hook if it does not exist [#76](https://github.com/jupyterlab/hatch-jupyter-builder/pull/76) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-09-28&to=2022-10-03&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ablink1073+updated%3A2022-09-28..2022-10-03&type=Issues) ## 0.7.0 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/v0.6.2...0a59d72aabb3aa5153f50a5d10303e3d03befeed)) ### Enhancements made - Allow skipping the build plugin [#74](https://github.com/jupyterlab/hatch-jupyter-builder/pull/74) ([@blink1073](https://github.com/blink1073)) ### Maintenance and upkeep improvements - Use hatch for version [#71](https://github.com/jupyterlab/hatch-jupyter-builder/pull/71) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-09-13&to=2022-09-28&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ablink1073+updated%3A2022-09-13..2022-09-28&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Apre-commit-ci+updated%3A2022-09-13..2022-09-28&type=Issues) ## 0.6.2 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/0.6.1...53dc001dacfdb82109466f9428210fb76bb0f008)) ### Bugs fixed - Fix editable build kwargs [#68](https://github.com/jupyterlab/hatch-jupyter-builder/pull/68) ([@fcollonval](https://github.com/fcollonval)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-09-12&to=2022-09-13&type=c)) [@fcollonval](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Afcollonval+updated%3A2022-09-12..2022-09-13&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Awelcome+updated%3A2022-09-12..2022-09-13&type=Issues) ## 0.6.1 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/v0.6.0...f63bd99da493aff214e7bacdd574d24d11c41b20)) ### Bugs fixed - Fix plugin and add integration test [#66](https://github.com/jupyterlab/hatch-jupyter-builder/pull/66) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-09-08&to=2022-09-12&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ablink1073+updated%3A2022-09-08..2022-09-12&type=Issues) ## 0.6.0 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/v0.5.3...fc91c954d1ba9fff579436fc2efe6bea0a68fff9)) ### Enhancements made - feature: CLI dispatcher [#63](https://github.com/jupyterlab/hatch-jupyter-builder/pull/63) ([@flying-sheep](https://github.com/flying-sheep)) ### Bugs fixed - Use version_template for package.json [#49](https://github.com/jupyterlab/hatch-jupyter-builder/pull/49) ([@blink1073](https://github.com/blink1073)) ### Maintenance and upkeep improvements - \[pre-commit.ci\] pre-commit autoupdate [#61](https://github.com/jupyterlab/hatch-jupyter-builder/pull/61) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - \[pre-commit.ci\] pre-commit autoupdate [#59](https://github.com/jupyterlab/hatch-jupyter-builder/pull/59) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - \[pre-commit.ci\] pre-commit autoupdate [#57](https://github.com/jupyterlab/hatch-jupyter-builder/pull/57) ([@pre-commit-ci](https://github.com/pre-commit-ci)) ### Documentation improvements - Fix page title [#60](https://github.com/jupyterlab/hatch-jupyter-builder/pull/60) ([@blink1073](https://github.com/blink1073)) - More documentation cleanup [#58](https://github.com/jupyterlab/hatch-jupyter-builder/pull/58) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-08-19&to=2022-09-08&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ablink1073+updated%3A2022-08-19..2022-09-08&type=Issues) | [@flying-sheep](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Aflying-sheep+updated%3A2022-08-19..2022-09-08&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Apre-commit-ci+updated%3A2022-08-19..2022-09-08&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Awelcome+updated%3A2022-08-19..2022-09-08&type=Issues) ## 0.5.3 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/v0.5.2...c73212c3e88c7fe203df94b8d07100219baa8d89)) ### Enhancements made - Add logging and handle editable npm arg [#41](https://github.com/jupyterlab/hatch-jupyter-builder/pull/41) ([@blink1073](https://github.com/blink1073)) - Add handling of create_cmdclass [#40](https://github.com/jupyterlab/hatch-jupyter-builder/pull/40) ([@blink1073](https://github.com/blink1073)) - Handle license file in migration [#37](https://github.com/jupyterlab/hatch-jupyter-builder/pull/37) ([@blink1073](https://github.com/blink1073)) - Add jupyter_packaging conversion wrapper [#36](https://github.com/jupyterlab/hatch-jupyter-builder/pull/36) ([@blink1073](https://github.com/blink1073)) ### Bugs fixed - Fix command in `install_pre_commit_hook` [#55](https://github.com/jupyterlab/hatch-jupyter-builder/pull/55) ([@jtpio](https://github.com/jtpio)) - Use version_template for pyproject.toml [#48](https://github.com/jupyterlab/hatch-jupyter-builder/pull/48) ([@blink1073](https://github.com/blink1073)) - Fix compare script [#35](https://github.com/jupyterlab/hatch-jupyter-builder/pull/35) ([@blink1073](https://github.com/blink1073)) ### Maintenance and upkeep improvements - \[pre-commit.ci\] pre-commit autoupdate [#53](https://github.com/jupyterlab/hatch-jupyter-builder/pull/53) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - Fix flake8 v5 compat [#52](https://github.com/jupyterlab/hatch-jupyter-builder/pull/52) ([@blink1073](https://github.com/blink1073)) - \[pre-commit.ci\] pre-commit autoupdate [#51](https://github.com/jupyterlab/hatch-jupyter-builder/pull/51) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - \[pre-commit.ci\] pre-commit autoupdate [#50](https://github.com/jupyterlab/hatch-jupyter-builder/pull/50) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - \[pre-commit.ci\] pre-commit autoupdate [#47](https://github.com/jupyterlab/hatch-jupyter-builder/pull/47) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - Do not use dev version yet [#46](https://github.com/jupyterlab/hatch-jupyter-builder/pull/46) ([@blink1073](https://github.com/blink1073)) - \[pre-commit.ci\] pre-commit autoupdate [#44](https://github.com/jupyterlab/hatch-jupyter-builder/pull/44) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - Add sphinx docs stub [#42](https://github.com/jupyterlab/hatch-jupyter-builder/pull/42) ([@blink1073](https://github.com/blink1073)) - \[pre-commit.ci\] pre-commit autoupdate [#39](https://github.com/jupyterlab/hatch-jupyter-builder/pull/39) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - Rename migration scripts [#38](https://github.com/jupyterlab/hatch-jupyter-builder/pull/38) ([@blink1073](https://github.com/blink1073)) ### Documentation improvements - Start adding more docs [#45](https://github.com/jupyterlab/hatch-jupyter-builder/pull/45) ([@blink1073](https://github.com/blink1073)) - Add docs scaffolding [#43](https://github.com/jupyterlab/hatch-jupyter-builder/pull/43) ([@blink1073](https://github.com/blink1073)) - Add sphinx docs stub [#42](https://github.com/jupyterlab/hatch-jupyter-builder/pull/42) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-06-21&to=2022-08-19&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ablink1073+updated%3A2022-06-21..2022-08-19&type=Issues) | [@jtpio](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ajtpio+updated%3A2022-06-21..2022-08-19&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Apre-commit-ci+updated%3A2022-06-21..2022-08-19&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Awelcome+updated%3A2022-06-21..2022-08-19&type=Issues) ## 0.5.2 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/v0.5.1...979babceb148f3c6a6ff823bacfd88e94b8a0c22)) ### Bugs fixed - Preserve other build reqs [#33](https://github.com/jupyterlab/hatch-jupyter-builder/pull/33) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-06-20&to=2022-06-20&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ablink1073+updated%3A2022-06-20..2022-06-20&type=Issues) ## 0.5.1 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/v0.5.0...766fcddec85c1ca1d49f806539f9177feadb1f48)) ### Maintenance and upkeep improvements - \[pre-commit.ci\] pre-commit autoupdate [#31](https://github.com/jupyterlab/hatch-jupyter-builder/pull/31) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - Migration cleanup [#29](https://github.com/jupyterlab/hatch-jupyter-builder/pull/29) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-06-20&to=2022-06-20&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ablink1073+updated%3A2022-06-20..2022-06-20&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Apre-commit-ci+updated%3A2022-06-20..2022-06-20&type=Issues) ## 0.5.0 ([Full Changelog](https://github.com/jupyterlab/hatch-jupyter-builder/compare/v0.4.0...38f709fd38fce179dcdbe6da78e64fbb38a89658)) ### Enhancements made - Make npm skip explicit [#28](https://github.com/jupyterlab/hatch-jupyter-builder/pull/28) ([@blink1073](https://github.com/blink1073)) - Add a setup.py shim in migration script [#27](https://github.com/jupyterlab/hatch-jupyter-builder/pull/27) ([@blink1073](https://github.com/blink1073)) - Add migration and compare script [#21](https://github.com/jupyterlab/hatch-jupyter-builder/pull/21) ([@blink1073](https://github.com/blink1073)) ### Bugs fixed - Fix handling of skip-if-exists [#20](https://github.com/jupyterlab/hatch-jupyter-builder/pull/20) ([@blink1073](https://github.com/blink1073)) ### Maintenance and upkeep improvements - \[pre-commit.ci\] pre-commit autoupdate [#26](https://github.com/jupyterlab/hatch-jupyter-builder/pull/26) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - Chore: fix metadata for Source in pyproject.toml [#23](https://github.com/jupyterlab/hatch-jupyter-builder/pull/23) ([@agoose77](https://github.com/agoose77)) - \[pre-commit.ci\] pre-commit autoupdate [#22](https://github.com/jupyterlab/hatch-jupyter-builder/pull/22) ([@pre-commit-ci](https://github.com/pre-commit-ci)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch-jupyter-builder/graphs/contributors?from=2022-05-31&to=2022-06-20&type=c)) [@agoose77](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Aagoose77+updated%3A2022-05-31..2022-06-20&type=Issues) | [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Ablink1073+updated%3A2022-05-31..2022-06-20&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Apre-commit-ci+updated%3A2022-05-31..2022-06-20&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch-jupyter-builder+involves%3Awelcome+updated%3A2022-05-31..2022-06-20&type=Issues) ## 0.4.0 ([Full Changelog](https://github.com/jupyterlab/hatch_jupyter_builder/compare/v0.3.3...ab1b495716c502cb72e43cbd4e712ec40cb2e360)) ### Enhancements made - Add skip-if-exists capability [#18](https://github.com/jupyterlab/hatch_jupyter_builder/pull/18) ([@blink1073](https://github.com/blink1073)) ### Maintenance and upkeep improvements - \[pre-commit.ci\] pre-commit autoupdate [#17](https://github.com/jupyterlab/hatch_jupyter_builder/pull/17) ([@pre-commit-ci](https://github.com/pre-commit-ci)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch_jupyter_builder/graphs/contributors?from=2022-05-25&to=2022-05-31&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch_jupyter_builder+involves%3Ablink1073+updated%3A2022-05-25..2022-05-31&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch_jupyter_builder+involves%3Apre-commit-ci+updated%3A2022-05-25..2022-05-31&type=Issues) ## 0.3.3 ([Full Changelog](https://github.com/jupyterlab/hatch_jupyter_builder/compare/v0.3.1...8a4f0ff37caa506dc695c20bd4ade0402bc5744f)) ### Bugs fixed - Fix handling of pre_commit hook install [#15](https://github.com/jupyterlab/hatch_jupyter_builder/pull/15) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch_jupyter_builder/graphs/contributors?from=2022-05-25&to=2022-05-25&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch_jupyter_builder+involves%3Ablink1073+updated%3A2022-05-25..2022-05-25&type=Issues) ## 0.3.1 ([Full Changelog](https://github.com/jupyterlab/hatch_jupyter_builder/compare/v0.3.0...2427c2e4df754453f348e66da27d3079e882d497)) ### Bugs fixed - Fix logging and git checkout check [#13](https://github.com/jupyterlab/hatch_jupyter_builder/pull/13) ([@blink1073](https://github.com/blink1073)) ### Maintenance and upkeep improvements - \[pre-commit.ci\] pre-commit autoupdate [#12](https://github.com/jupyterlab/hatch_jupyter_builder/pull/12) ([@pre-commit-ci](https://github.com/pre-commit-ci)) - Update project metadata [#11](https://github.com/jupyterlab/hatch_jupyter_builder/pull/11) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/jupyterlab/hatch_jupyter_builder/graphs/contributors?from=2022-05-21&to=2022-05-25&type=c)) [@blink1073](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch_jupyter_builder+involves%3Ablink1073+updated%3A2022-05-21..2022-05-25&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyterlab%2Fhatch_jupyter_builder+involves%3Apre-commit-ci+updated%3A2022-05-21..2022-05-25&type=Issues) ## 0.3.0 ([Full Changelog](https://github.com/blink1073/hatch_jupyter_builder/compare/v0.2.2...3990b4e71d439753a6b237c0570a3df8f41407ed)) ### Enhancements made - Add editable build kwargs [#9](https://github.com/blink1073/hatch_jupyter_builder/pull/9) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/blink1073/hatch_jupyter_builder/graphs/contributors?from=2022-05-18&to=2022-05-21&type=c)) [@blink1073](https://github.com/search?q=repo%3Ablink1073%2Fhatch_jupyter_builder+involves%3Ablink1073+updated%3A2022-05-18..2022-05-21&type=Issues) ## 0.2.2 ([Full Changelog](https://github.com/blink1073/hatch_jupyter_builder/compare/v0.2.0...880241f6537ecd3e1ad7fc202cb410dc8545f9fc)) ### Bugs fixed - Make the hook a bash script [#7](https://github.com/blink1073/hatch_jupyter_builder/pull/7) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/blink1073/hatch_jupyter_builder/graphs/contributors?from=2022-05-18&to=2022-05-18&type=c)) [@blink1073](https://github.com/search?q=repo%3Ablink1073%2Fhatch_jupyter_builder+involves%3Ablink1073+updated%3A2022-05-18..2022-05-18&type=Issues) ## 0.2.0 ([Full Changelog](https://github.com/blink1073/hatch_jupyter_builder/compare/v0.1.0...a2d21ea9e635db39fd8917a3f89e1b52a7b8b15c)) ### Enhancements made - Clean up and add pre-commit option [#5](https://github.com/blink1073/hatch_jupyter_builder/pull/5) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/blink1073/hatch_jupyter_builder/graphs/contributors?from=2022-05-14&to=2022-05-18&type=c)) [@blink1073](https://github.com/search?q=repo%3Ablink1073%2Fhatch_jupyter_builder+involves%3Ablink1073+updated%3A2022-05-14..2022-05-18&type=Issues) ## 0.1.0 ([Full Changelog](https://github.com/blink1073/hatch_jupyter_builder/compare/e5628cbc0407fa230ceea54cc12ef946cc1281e2...acf4d62bd0158d5344055eba9418c1c8e18b14a6)) ### Maintenance and upkeep improvements - Finish Initial Implementation [#3](https://github.com/blink1073/hatch_jupyter_builder/pull/3) ([@blink1073](https://github.com/blink1073)) - Add utils tests and clean up option names [#2](https://github.com/blink1073/hatch_jupyter_builder/pull/2) ([@blink1073](https://github.com/blink1073)) - More cleanup and front matter [#1](https://github.com/blink1073/hatch_jupyter_builder/pull/1) ([@blink1073](https://github.com/blink1073)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/blink1073/hatch_jupyter_builder/graphs/contributors?from=2022-05-13&to=2022-05-14&type=c)) [@blink1073](https://github.com/search?q=repo%3Ablink1073%2Fhatch_jupyter_builder+involves%3Ablink1073+updated%3A2022-05-13..2022-05-14&type=Issues) hatch_jupyter_builder-0.8.3/RELEASE.md0000644000000000000000000000155713615410400014433 0ustar00# Making a Hatch Jupyter Builder Release ## Using `jupyter_releaser` The recommended way to make a release is to use [`jupyter_releaser`](https://jupyter-releaser.readthedocs.io/en/latest/get_started/making_release_from_repo.html). Note that we must use manual versions since Jupyter Releaser does not yet support "next" or "patch" when dev versions are used. ## Manual Release To create a manual release, perform the following steps: ### Set up ```bash pip install hatch twine git pull origin $(git branch --show-current) git clean -dffx ``` ### Update the version and apply the tag ```bash echo "Enter new version" read new_version hatch version ${new_version} git tag -a ${new_version} -m "Release ${new_version}" ``` ### Build the artifacts ```bash rm -rf dist hatch build ``` ### Publish the artifacts to pypi ```bash twine check dist/* twine upload dist/* ``` hatch_jupyter_builder-0.8.3/.github/workflows/enforce-label.yml0000644000000000000000000000050013615410400021632 0ustar00name: Enforce PR label on: pull_request: types: [labeled, unlabeled, opened, edited, synchronize] jobs: enforce-label: runs-on: ubuntu-latest permissions: pull-requests: write steps: - name: enforce-triage-label uses: jupyterlab/maintainer-tools/.github/actions/enforce-label@v1 hatch_jupyter_builder-0.8.3/.github/workflows/prep-release.yml0000644000000000000000000000265713615410400021537 0ustar00name: "Step 1: Prep Release" on: workflow_dispatch: inputs: version_spec: description: "New Version Specifier" default: "next" required: false branch: description: "The branch to target" required: false post_version_spec: description: "Post Version Specifier" required: false since: description: "Use PRs with activity since this date or git reference" required: false since_last_stable: description: "Use PRs with activity since the last stable git tag" required: false type: boolean jobs: prep_release: runs-on: ubuntu-latest steps: - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Prep Release id: prep-release uses: jupyter-server/jupyter_releaser/.github/actions/prep-release@v2 with: token: ${{ secrets.ADMIN_GITHUB_TOKEN }} version_spec: ${{ github.event.inputs.version_spec }} post_version_spec: ${{ github.event.inputs.post_version_spec }} target: ${{ github.event.inputs.target }} branch: ${{ github.event.inputs.branch }} since: ${{ github.event.inputs.since }} since_last_stable: ${{ github.event.inputs.since_last_stable }} - name: "** Next Step **" run: | echo "Optional): Review Draft Release: ${{ steps.prep-release.outputs.release_url }}" hatch_jupyter_builder-0.8.3/.github/workflows/publish-release.yml0000644000000000000000000000347613615410400022237 0ustar00name: "Step 2: Publish Release" on: workflow_dispatch: inputs: branch: description: "The target branch" required: false release_url: description: "The URL of the draft GitHub release" required: false steps_to_skip: description: "Comma separated list of steps to skip" required: false jobs: publish_release: runs-on: ubuntu-latest steps: - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Populate Release id: populate-release uses: jupyter-server/jupyter_releaser/.github/actions/populate-release@v2 with: token: ${{ secrets.ADMIN_GITHUB_TOKEN }} target: ${{ github.event.inputs.target }} branch: ${{ github.event.inputs.branch }} release_url: ${{ github.event.inputs.release_url }} steps_to_skip: ${{ github.event.inputs.steps_to_skip }} - name: Finalize Release id: finalize-release env: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} PYPI_TOKEN_MAP: ${{ secrets.PYPI_TOKEN_MAP }} TWINE_USERNAME: __token__ NPM_TOKEN: ${{ secrets.NPM_TOKEN }} uses: jupyter-server/jupyter-releaser/.github/actions/finalize-release@v2 with: token: ${{ secrets.ADMIN_GITHUB_TOKEN }} target: ${{ github.event.inputs.target }} release_url: ${{ steps.populate-release.outputs.release_url }} - name: "** Next Step **" if: ${{ success() }} run: | echo "Verify the final release" echo ${{ steps.finalize-release.outputs.release_url }} - name: "** Failure Message **" if: ${{ failure() }} run: | echo "Failed to Publish the Draft Release Url:" echo ${{ steps.populate-release.outputs.release_url }} hatch_jupyter_builder-0.8.3/.github/workflows/tests.yml0000644000000000000000000001131213615410400020301 0ustar00name: Tests on: push: branches: [main] pull_request: schedule: # Run weekly # * is a special character in YAML so you have to quote this string - cron: "0 0 * * 0" defaults: run: shell: bash -eux {0} jobs: build: runs-on: ubuntu-latest strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] python-version: ["3.8", "3.11"] include: - os: windows-latest python-version: "3.9" - os: ubuntu-latest python-version: "pypy-3.8" - os: macos-latest python-version: "3.10" steps: - uses: actions/checkout@v2 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Run tests run: hatch run cov:test - name: Run cli checks run: | pip install -e . hatch-jupyter-builder -h hatch-jupyter-builder migrate -h hatch-jupyter-builder compare-migrated -h - uses: jupyterlab/maintainer-tools/.github/actions/upload-coverage@v1 coverage: runs-on: ubuntu-latest needs: - build steps: - uses: actions/checkout@v3 - uses: jupyterlab/maintainer-tools/.github/actions/report-coverage@v1 check_release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v2 with: token: ${{ secrets.GITHUB_TOKEN }} check_links: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1 with: ignore_glob: "tests/data/**/README.md" migration: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Run Migration Tests run: hatch run migration:test test_docs: runs-on: windows-latest steps: - uses: actions/checkout@v2 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Build API docs run: | hatch run docs:api # If this fails run `hatch run docs:api` locally # and commit. git status --porcelain git status -s | grep "A" && exit 1 git status -s | grep "M" && exit 1 echo "API docs done" - run: hatch run docs:build test_lint: name: Test Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Run Linters run: | hatch run typing:test hatch run lint:style pipx run interrogate -v . pipx run doc8 --max-line-length=200 --ignore-path=docs/source/other/full-config.rst test_minimum_versions: name: Test Minimum Versions timeout-minutes: 20 runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 with: dependency_type: minimum - name: Run the unit tests run: | hatch run test:test test_prereleases: name: Test Prereleases runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v2 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 with: dependency_type: pre - name: Run the tests run: hatch run test:test make_sdist: name: Make SDist runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@v2 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyterlab/maintainer-tools/.github/actions/make-sdist@v1 test_sdist: runs-on: ubuntu-latest needs: [make_sdist] name: Install from SDist and Test timeout-minutes: 20 steps: - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyterlab/maintainer-tools/.github/actions/test-sdist@v1 with: test_command: hatch run test:test tests_check: # This job does nothing and is only used for the branch protection if: always() needs: - coverage - migration - test_lint - test_docs - test_minimum_versions - test_prereleases - check_links - check_release - test_sdist runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }} hatch_jupyter_builder-0.8.3/docs/Makefile0000644000000000000000000000117213615410400015412 0ustar00# Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) hatch_jupyter_builder-0.8.3/docs/conf.py0000644000000000000000000000536713615410400015263 0ustar00# Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # # import os # import sys # sys.path.insert(0, os.path.abspath('.')) from importlib.metadata import version as package_version # -- Project information ----------------------------------------------------- project = "hatch-jupyter-builder" copyright = "2022, Project Jupyter" author = "Project Jupyter" # The full version, including alpha/beta/rc tags __version__ = package_version("hatch_jupyter_builder") # The short X.Y version. version_parsed = tuple(__version__.split(".")) version = ".".join(version_parsed[:2]) # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ "sphinx.ext.napoleon", "sphinx.ext.autodoc", "myst_parser", "sphinx_autodoc_typehints", ] try: import enchant # type:ignore # noqa extensions += ["sphinxcontrib.spelling"] except ImportError: pass myst_enable_extensions = ["html_image"] # Add any paths that contain templates here, relative to this directory. # templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = "pydata_sphinx_theme" # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {"python": {"https://docs.python.org/3/": None}} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". # html_static_path = ["_static"] import os.path as osp import shutil HERE = osp.abspath(osp.dirname(__file__)) def setup(app): dest = osp.join(HERE, "source", "reference", "changelog.md") shutil.copy(osp.join(HERE, "..", "CHANGELOG.md"), dest) hatch_jupyter_builder-0.8.3/docs/index.rst0000644000000000000000000000111513615410400015610 0ustar00.. hatch-jupyter-builder documentation master file, created by sphinx-quickstart on Mon Jul 4 07:51:40 2022. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Welcome to hatch-jupyter-builder's documentation! ================================================= .. toctree:: :maxdepth: 2 :caption: Contents: source/background/index source/get_started/index source/how_to_guides/index source/reference/index Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` hatch_jupyter_builder-0.8.3/docs/make.bat0000644000000000000000000000144013615410400015355 0ustar00@ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=. set BUILDDIR=_build %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.https://www.sphinx-doc.org/ exit /b 1 ) if "%1" == "" goto help %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end popd hatch_jupyter_builder-0.8.3/docs/source/background/index.rst0000644000000000000000000000141013615410400021225 0ustar00Background ========== Explanation. Clarification and discussion of key topics. Hatch Jupyter Builder is a plugin for the `hatchling` Python build backend. It is primarily targeted for package authors who are providing JavaScript as part of their Python packages. Typical use cases are Jupyter Lab Extensions and Jupyter Widgets. The ``hatchling`` build backend is part of the `hatch `_ project, a member of the Python Packaging Authority. It provides a simple build backend that is compliant with the relevant Python Enhancement Proposals, but also provides many useful features such as `shared-data `_, which can be used to provide Jupyter configuration and runtime files. hatch_jupyter_builder-0.8.3/docs/source/get_started/config.md0000644000000000000000000000511613615410400021350 0ustar00# Configuration The [build hook plugin](https://hatch.pypa.io/latest/plugins/build-hook/) name is `jupyter-builder`. The minimal set of options is: - **_pyproject.toml_** ```toml [tool.hatch.build.hooks.jupyter-builder] dependencies = ["hatch-jupyter-builder"] build-function = "hatch_jupyter_builder.npm_builder" ``` Or with all options given: - **_pyproject.toml_** ```toml [tool.hatch.build.hooks.jupyter-builder] dependencies = ["hatch-jupyter-builder"] build-function = "hatch_jupyter_builder.npm_builder" ensured-targets = ["foo/generated.txt"] skip-if-exists = ["foo/generated.txt"] install-pre-commit-hook = true optional-editable-build = true [tool.hatch.build.hooks.jupyter-builder.build-kwargs] build_cmd = "build:src" [tool.hatch.build.hooks.jupyter-builder.editable-build-kwargs] build_cmd = "build" ``` ## Options ### build-function The build function is defined as an importable string with a module and a function name, separated by a period. The function must accept a `target_name` (either "wheel" or "sdist"), and a `version` (either "standard" or "editable") as its only positional arguments. E.g. - **_builder.py_** ```python def build_func(target_name, version): ... ``` Would be defined as `build-function = "builder.build_func"` ### ensured-targets The optional `ensured-targets` is a list of expected file paths after building a "standard" version sdist or wheel. ### skip-if-exsits The optional `skip-if-exists` is a list of paths whose presence would cause the build step to be skipped. This option is ignored in `editable` mode. The `ensured-targets` will still be checked, if given. ### build-kwargs The optional `build-kwargs` is a set of keyword arguments to pass to the build function. ### editable-build-kwargs You can also use `editable-build-kwargs` if the parameters should differ in editable mode. If only the build command is different, you can use `editable_build_cmd` in `build-kwargs` instead. ### optional-editable-build The optional `optional-editable-build` parameter can be set to `true` to show a warning instead of erroring if the build fails in editable mode. This can be used when build artifacts are optional for local development. ### install-pre-commit-hook The optional `install-pre-commit-hook` boolean causes a `pre-commit` hook to be installed during an editable install. ## Npm Builder Function This library provides a convenenice `npm_builder` function which can be used to build `npm` assets as part of the build. See the :ref:`npm_builder_function` for more information on usage. hatch_jupyter_builder-0.8.3/docs/source/get_started/index.rst0000644000000000000000000000074013615410400021420 0ustar00Getting Started =============== Tutorials. A hands-on introduction to Hatch Jupyter Builder for maintainers. .. toctree:: :maxdepth: 1 :caption: Contents: config If starting from a new project, use `hatch new "my project name"`, and follow along with the prompts. Then add the appropriate [configuration](./config) for `hatch_jupyter_builder` in your `pyproject.toml` flag. If migrating from existing project, find the appropriate [how to guides](../how_to_guides). hatch_jupyter_builder-0.8.3/docs/source/how_to_guides/index.rst0000644000000000000000000000033513615410400021752 0ustar00How-to Guides ============= Step-by-step guides. Covers key tasks and operations and common problems .. toctree:: :maxdepth: 1 :caption: Contents: migrating_javascript_projects migrating_data_files_projects hatch_jupyter_builder-0.8.3/docs/source/how_to_guides/migrating_data_files_projects.md0000644000000000000000000000521613615410400026503 0ustar00# Migrating Python Projects that used Data Files For existing projects that used `setuptools` and optionally the `get_data_files()` function from `jupyter_packaging`, we offer a migration script that will convert your project to use `hatchling`. These projects can include Jupyter Kernels or Jupyter Server Extensions that ship with `data_files`. Create a new branch for your migration and run the following: ```bash pip install hatch_jupyter_builder python -m hatch_jupyter_builder.migrate . ``` The migration script will do its best to convert metadata from `setup.py` and `setup.cfg` into appropriate modernized `pyproject.toml` metadata. Much of the migration is done by `hatch` itself, including the mapping of `data-files` configuration to [`shared-data`](https://hatch.pypa.io/latest/plugins/builder/wheel/#options). If there are things that are found that cannot be automatically migrated, a warning will print at the end of the migration script. Typically this will be a notice to put the actual version string in your `_version.py` file. The migration assumes that you will be using [`tbump`](https://github.com/your-tools/tbump) to manage versions. `tbump` is a project that is used by many of the core Jupyter projects to maintain version for a project. For example, if you have a `_version.py` and a `package.json` file that are meant to share a version, `tbump` can handle keeping them in sync. If some other custom logic that was in your `setup.py`, you may need to include a `hatch_build.py` file, similar to the one used by [`ipykernel`](https://github.com/ipython/ipykernel/blob/main/hatch_build.py). You will need to add a [custom metadata hook](https://hatch.pypa.io/latest/plugins/metadata-hook/custom/#custom-metadata-hook) as well. As an additional assurance, you can compare the files produced by the migrated configuration to those you previously produced. To do this, clone your repository to another folder, and run the following: ```bash python -m hatch_jupyter_builder.compare_migrated . wheel ``` This will build the wheel in both directories and compare their contents. You can repeat the process with the `sdist` option as well. For some other examples of migrated packages, see - [ipyparallel](https://github.com/ipython/ipyparallel/blob/main/pyproject.toml) (includes a `hatch_build.py` file with a custom script to provide a Lab and Notebook extension) - [jupyter-server-terminals](https://github.com/jupyter-server/jupyter_server_terminals/blob/main/pyproject.toml) - a Jupyter Server extension - [jupyter_client](https://github.com/jupyter/jupyter_client/blob/main/pyproject.toml) (regular python package with no `shared-data`) hatch_jupyter_builder-0.8.3/docs/source/how_to_guides/migrating_javascript_projects.md0000644000000000000000000000436513615410400026562 0ustar00# Migrating Python Projects that used JavaScript For existing projects that shipped with JavaScript, which includes Jupyter Lab Extensions, Jupyter Widgets, and Jupyter Notebook Extensions, we provide a script to help automate the process. Create a new branch for your migration and run the following: ```bash pip install hatch_jupyter_builder python -m hatch_jupyter_builder.migrate . ``` The migration script will do its best to convert metadata from `setup.py` and `setup.cfg` into appropriate modernized `pyproject.toml` metadata. Much of the migration is done by `hatch` itself, including the mapping of `data-files` configuration to [`shared-data`](https://hatch.pypa.io/latest/plugins/builder/wheel/#options). If the package was using `jupyter_packaging`, we also provide appropriate `hatch_jupyter_builder` config. If there are things that are found that cannot be automatically migrated, a warning will print at the end of the migration script. Typically this will be a notice to put the actual version string in your `_version.py` file. The migration assumes that you will be using [`tbump`](https://github.com/your-tools/tbump) to manage versions. `tbump` is a project that is used by many of the core Jupyter projects to maintain version for a project. For example, if you have a `_version.py` and a `package.json` file that are meant to share a version, `tbump` can handle keeping them in sync. The configuration and behavior of the `npm_builder` helper function is similar to the one provided by `jupyter_packaging`. As an additional assurance, you can compare the files produced by the migrated configuration to those you previously produced. To do this, clone your repository to another folder, and run the following: ```bash python -m hatch_jupyter_builder.compare_migrated . wheel ``` This will build the wheel in both directories and compare their contents. You can repeat the process with the `sdist` option as well. For some examples of migrated packages that provide JavaScript, see: - [notebook](https://github.com/jupyter/notebook/blob/main/pyproject.toml) (JupyterLab and Server Extensions) - [jupyter_server](https://github.com/jupyter-server/jupyter_server/blob/main/pyproject.toml) (build step to include CSS for default pages). hatch_jupyter_builder-0.8.3/docs/source/reference/index.rst0000644000000000000000000000027013615410400021047 0ustar00Reference ========= Technical reference. Covers tools, components, commands and resources. .. toctree:: :maxdepth: 1 :caption: Contents: API Docs changelog hatch_jupyter_builder-0.8.3/docs/source/reference/api/hatch_jupyter_builder.compare_migrated.rst0000644000000000000000000000057513615410400030401 0ustar00hatch\_jupyter\_builder.compare\_migrated package ================================================= Submodules ---------- .. automodule:: hatch_jupyter_builder.compare_migrated.cli :members: :undoc-members: :show-inheritance: Module contents --------------- .. automodule:: hatch_jupyter_builder.compare_migrated :members: :undoc-members: :show-inheritance: hatch_jupyter_builder-0.8.3/docs/source/reference/api/hatch_jupyter_builder.migrate.rst0000644000000000000000000000052713615410400026524 0ustar00hatch\_jupyter\_builder.migrate package ======================================= Submodules ---------- .. automodule:: hatch_jupyter_builder.migrate.cli :members: :undoc-members: :show-inheritance: Module contents --------------- .. automodule:: hatch_jupyter_builder.migrate :members: :undoc-members: :show-inheritance: hatch_jupyter_builder-0.8.3/docs/source/reference/api/hatch_jupyter_builder.rst0000644000000000000000000000134713615410400025076 0ustar00hatch\_jupyter\_builder package =============================== Subpackages ----------- .. toctree:: :maxdepth: 4 hatch_jupyter_builder.compare_migrated hatch_jupyter_builder.migrate Submodules ---------- .. automodule:: hatch_jupyter_builder.cli :members: :undoc-members: :show-inheritance: .. automodule:: hatch_jupyter_builder.hooks :members: :undoc-members: :show-inheritance: .. automodule:: hatch_jupyter_builder.plugin :members: :undoc-members: :show-inheritance: .. automodule:: hatch_jupyter_builder.utils :members: :undoc-members: :show-inheritance: Module contents --------------- .. automodule:: hatch_jupyter_builder :members: :undoc-members: :show-inheritance: hatch_jupyter_builder-0.8.3/docs/source/reference/api/modules.rst0000644000000000000000000000014413615410400022161 0ustar00hatch_jupyter_builder ===================== .. toctree:: :maxdepth: 4 hatch_jupyter_builder hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/__init__.py0000644000000000000000000000011513615410400021506 0ustar00from .utils import is_stale, npm_builder # noqa F401 __version__ = "0.8.3" hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/__main__.py0000644000000000000000000000012113615410400021464 0ustar00"""The cli entry point for hatch_jupyter_builder.""" from .cli import run run() hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/cli.py0000644000000000000000000000221413615410400020520 0ustar00"""The cli implementation for hatch_jupyter_builder.""" import argparse import sys from typing import Optional from .compare_migrated import cli as compare_cli from .migrate import cli as migrate_cli def make_parser( parser: Optional[argparse.ArgumentParser] = None, prog: Optional[str] = None ) -> argparse.ArgumentParser: """Make an arg parser.""" if parser is None: parser = argparse.ArgumentParser(prog=prog) parsers = parser.add_subparsers() migrate_parser = parsers.add_parser("migrate") migrate_cli.make_parser(migrate_parser) migrate_parser.set_defaults(func=migrate_cli.run) compare_parser = parsers.add_parser("compare-migrated") compare_cli.make_parser(compare_parser) compare_parser.set_defaults(func=compare_cli.run) return parser def run(args: Optional[argparse.Namespace] = None) -> None: """Run the main script.""" if args is None: prog = ( f"{sys.executable} -m hatch_jupyter_builder" if sys.argv[0].endswith("__main__.py") else None ) parser = make_parser(prog=prog) args = parser.parse_args() args.func() hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/hooks.py0000644000000000000000000000034113615410400021073 0ustar00"""Register hooks for the plugin.""" from hatchling.plugin import hookimpl from .plugin import JupyterBuildHook @hookimpl def hatch_register_build_hook(): """Get the hook implementation.""" return JupyterBuildHook hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/plugin.py0000644000000000000000000000651013615410400021252 0ustar00"""The main plugin for hatch_jupyter_builder.""" import os import typing as t import warnings from dataclasses import dataclass, field, fields from hatchling.builders.hooks.plugin.interface import BuildHookInterface from .utils import ( _get_log, ensure_targets, get_build_func, install_pre_commit_hook, normalize_kwargs, should_skip, ) @dataclass class JupyterBuildConfig: """Build config values for Hatch Jupyter Builder.""" install_pre_commit_hook: str = "" build_function: t.Optional[str] = None build_kwargs: t.Mapping[str, str] = field(default_factory=dict) editable_build_kwargs: t.Mapping[str, str] = field(default_factory=dict) ensured_targets: t.List[str] = field(default_factory=list) skip_if_exists: t.List[str] = field(default_factory=list) optional_editable_build: str = "" class JupyterBuildHook(BuildHookInterface): """The hatch jupyter builder build hook.""" PLUGIN_NAME = "jupyter-builder" def initialize(self, version, build_data): """Initialize the plugin.""" log = _get_log() log.info("Running jupyter-builder") if self.target_name not in ["wheel", "sdist"]: log.info(f"ignoring target name {self.target_name}") return False if os.getenv("SKIP_JUPYTER_BUILDER"): log.info("Skipping the build hook since SKIP_JUPYTER_BUILDER was set") return False kwargs = normalize_kwargs(self.config) available_fields = [f.name for f in fields(JupyterBuildConfig)] for key in list(kwargs): if key not in available_fields: del kwargs[key] config = JupyterBuildConfig(**kwargs) should_install_hook = config.install_pre_commit_hook.lower() == "true" if version == "editable" and should_install_hook: install_pre_commit_hook() build_kwargs = config.build_kwargs if version == "editable": build_kwargs = config.editable_build_kwargs or build_kwargs should_skip_build = False if not config.build_function: log.warning("No build function found") should_skip_build = True elif config.skip_if_exists and version == "standard": should_skip_build = should_skip(config.skip_if_exists) if should_skip_build: log.info("Skip-if-exists file(s) found") # Get build function and call it with normalized parameter names. if not should_skip_build and config.build_function: build_func = get_build_func(config.build_function) build_kwargs = normalize_kwargs(build_kwargs) log.info(f"Building with {config.build_function}") log.info(f"With kwargs: {build_kwargs}") try: build_func(self.target_name, version, **build_kwargs) except Exception as e: if version == "editable" and config.optional_editable_build.lower() == "true": warnings.warn(f"Encountered build error:\n{e}") # noqa B028 else: raise e else: log.info("Skipping build") # Ensure targets in distributable dists. if version == "standard": ensure_targets(config.ensured_targets) log.info("Finished running jupyter-builder") return True hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/utils.py0000644000000000000000000002103213615410400021110 0ustar00"""Utilities for hatch_jupyter_builder.""" import importlib import logging import os import shlex import subprocess import sys from pathlib import Path from shutil import which from typing import Any, Callable, Dict, List, Mapping, Optional, Union if sys.platform == "win32": # pragma: no cover from subprocess import list2cmdline else: def list2cmdline(cmd_list): """Implementation of list2cmdline for posix systems.""" return " ".join(map(shlex.quote, cmd_list)) _logger = None def _get_log() -> logging.Logger: global _logger # noqa if _logger: return _logger _logger = logging.getLogger(__name__) _logger.setLevel(logging.INFO) logging.basicConfig(level=logging.INFO) return _logger def npm_builder( target_name: str, version: str, path: str = ".", build_dir: Optional[str] = None, source_dir: Optional[str] = None, build_cmd: Optional[str] = "build", force: bool = False, npm: Optional[Union[str, List]] = None, editable_build_cmd: Optional[str] = None, ) -> None: """Build function for managing an npm installation. Parameters ---------- target_name: str The build target name ("wheel" or "sdist"). version: str The version name ("standard" or "editable"). path: str, optional The base path of the node package. Defaults to the current directory. build_dir: str, optional The target build directory. If this and source_dir are given, the JavaScript will only be built if necessary. source_dir: str, optional The source code directory. build_cmd: str, optional The npm command to build assets to the build_dir. editable_build_cmd: str, optional. The npm command to build assets to the build_dir when building in editable mode. npm: str or list, optional. The npm executable name, or a tuple of ['node', executable]. Notes ----- The function is a no-op if the `--skip-npm` cli flag is used or HATCH_JUPYTER_BUILDER_SKIP_NPM env is set. """ # Check if we are building a wheel from an sdist. abs_path = Path(path).resolve() log = _get_log() if "--skip-npm" in sys.argv or os.environ.get("HATCH_JUPYTER_BUILDER_SKIP_NPM") == "1": log.info("Skipping npm install as requested.") skip_npm = True if "--skip-npm" in sys.argv: sys.argv.remove("--skip-npm") else: skip_npm = False if skip_npm: log.info("Skipping npm-installation") return if version == "editable": build_cmd = editable_build_cmd or build_cmd if isinstance(npm, str): npm = [npm] # Find a suitable default for the npm command. if npm is None: is_yarn = (abs_path / "yarn.lock").exists() if is_yarn and not which("yarn"): log.warning("yarn not found, ignoring yarn.lock file") is_yarn = False npm = ["yarn"] if is_yarn else ["npm"] npm_cmd = normalize_cmd(npm) if build_dir and source_dir and not force: should_build = is_stale(build_dir, source_dir) else: should_build = True if should_build: log.info("Installing build dependencies with npm. This may take a while...") run([*npm_cmd, "install"], cwd=str(abs_path)) if build_cmd: run([*npm_cmd, "run", build_cmd], cwd=str(abs_path)) else: log.info("No build required") def is_stale(target: Union[str, Path], source: Union[str, Path]) -> bool: """Test whether the target file/directory is stale based on the source file/directory. """ if not Path(source).exists(): return False if not Path(target).exists(): return True target_mtime = recursive_mtime(target) or 0 return compare_recursive_mtime(source, cutoff=target_mtime) def compare_recursive_mtime(path: Union[str, Path], cutoff: float, newest: bool = True) -> bool: """Compare the newest/oldest mtime for all files in a directory. Cutoff should be another mtime to be compared against. If an mtime that is newer/older than the cutoff is found it will return True. E.g. if newest=True, and a file in path is newer than the cutoff, it will return True. """ path = Path(path) if path.is_file(): mt = mtime(path) if newest: if mt > cutoff: return True elif mt < cutoff: return True for dirname, _, filenames in os.walk(str(path), topdown=False): for filename in filenames: mt = mtime(Path(dirname) / filename) if newest: # Put outside of loop? if mt > cutoff: return True elif mt < cutoff: return True return False def recursive_mtime(path: Union[str, Path], newest: bool = True) -> float: """Gets the newest/oldest mtime for all files in a directory.""" path = Path(path) if path.is_file(): return mtime(path) current_extreme = -1.0 for dirname, _, filenames in os.walk(str(path), topdown=False): for filename in filenames: mt = mtime(Path(dirname) / filename) if newest: # Put outside of loop? if mt >= (current_extreme or mt): current_extreme = mt elif mt <= (current_extreme or mt): current_extreme = mt return current_extreme def mtime(path: Union[str, Path]) -> float: """shorthand for mtime""" return Path(path).stat().st_mtime def get_build_func(build_func_str: str) -> Callable[..., None]: """Get a build function by name.""" # Get the build function by importing it. mod_name, _, func_name = build_func_str.rpartition(".") # If the module fails to import, try importing as a local script. try: sys.path.insert(0, str(Path.cwd())) mod = importlib.import_module(mod_name) finally: sys.path.pop(0) return getattr(mod, func_name) def normalize_cmd(cmd: Union[str, list]) -> List[str]: """Normalize a subprocess command.""" if not isinstance(cmd, (list, tuple)): cmd = shlex.split(cmd, posix=os.name != "nt") if not Path(cmd[0]).is_absolute(): # If a command is not an absolute path find it first. cmd_path = which(cmd[0]) if not cmd_path: msg = ( f"Aborting. Could not find cmd ({cmd[0]}) in path. " "If command is not expected to be in user's path, " "use an absolute path." ) raise ValueError(msg) cmd[0] = cmd_path return cmd def normalize_kwargs(kwargs: Mapping[str, str]) -> Dict[str, Any]: """Normalize the key names in a kwargs input dictionary""" result = {} for key, value in kwargs.items(): if isinstance(value, bool): value = str(value) # noqa result[key.replace("-", "_")] = value return result def run(cmd: Union[str, list], **kwargs: Any) -> int: """Echo a command before running it.""" kwargs.setdefault("shell", os.name == "nt") cmd = normalize_cmd(cmd) log = _get_log() log.info(f"> {list2cmdline(cmd)}") return subprocess.check_call(cmd, **kwargs) def ensure_targets(ensured_targets: List[str]) -> None: """Ensure that target files are available""" for target in ensured_targets: if not Path(target).exists(): msg = f'Ensured target "{target}" does not exist' raise ValueError(msg) _get_log().info("Ensured target(s) exist!") def should_skip(skip_if_exists): """Detect whether all the paths in skip_if_exists exist""" if not isinstance(skip_if_exists, list) or not len(skip_if_exists): return False return all(os.path.exists(p) for p in skip_if_exists) def install_pre_commit_hook(): """Install a pre-commit hook.""" data = f"""#!/usr/bin/env bash INSTALL_PYTHON={sys.executable} ARGS=(hook-impl --config=.pre-commit-config.yaml --hook-type=pre-commit) HERE="$(cd "$(dirname "$0")" && pwd)" ARGS+=(--hook-dir "$HERE" -- "$@") exec "$INSTALL_PYTHON" -m pre_commit "${{ARGS[@]}}" """ log = _get_log() if not os.path.exists(".git"): log.warning("Refusing to install pre-commit hook since this is not a git repository") return path = Path(".git/hooks/pre-commit") if not path.exists(): log.info("Writing pre-commit hook") with open(path, "w") as fid: fid.write(data) else: log.warning("Refusing to overwrite pre-commit hook") mode = os.stat(path).st_mode mode |= (mode & 0o444) >> 2 # copy R bits to X os.chmod(path, mode) hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/compare_migrated/__init__.py0000644000000000000000000000000013615410400025001 0ustar00hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/compare_migrated/__main__.py0000644000000000000000000000011413615410400024770 0ustar00"""The cli entry point for compare_migrated.""" from .cli import run run() hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/compare_migrated/cli.py0000644000000000000000000000574513615410400024036 0ustar00"""Compare the dist file created by a migrated package to one created by the original.""" import argparse import glob import logging import os import shutil import subprocess import sys import tarfile import zipfile from typing import Optional def build_file(dirname, dist_name): """Build a dist file in a directory.""" orig_dir = os.getcwd() os.chdir(dirname) if os.path.exists("dist"): shutil.rmtree("dist") subprocess.check_call([sys.executable, "-m", "build", f"--{dist_name}"]) os.chdir(orig_dir) def get_tar_names(dirname): """Get the tarball names in a directory.""" dist_file = glob.glob(f"{dirname}/dist/*.tar.gz")[0] tarf = tarfile.open(dist_file, "r:gz") return set(tarf.getnames()) def get_zip_names(dirname): """Get the zip (wheel) file names in a directory.""" wheel_file = glob.glob(f"{dirname}/dist/*.whl")[0] with zipfile.ZipFile(wheel_file, "r") as f: return set(f.namelist()) def filter_file(path): """Filter a file path for interesting files.""" if "egg-info" in path: return True _, ext = os.path.splitext(path) if not ext: return True if os.path.basename(path) in [path, "setup.py", "setup.cfg", "MANIFEST.in"]: return True return False def main(source_dir, target_dir, dist_name): """The main script.""" subprocess.check_call([sys.executable, "-m", "pip", "install", "build"]) logger = logging.getLogger(__name__) logging.basicConfig() build_file(source_dir, dist_name) build_file(target_dir, dist_name) if dist_name == "sdist": source_names = get_tar_names(source_dir) target_names = get_tar_names(target_dir) else: source_names = get_zip_names(source_dir) target_names = get_zip_names(target_dir) removed = source_names - target_names removed = [r for r in removed if not filter_file(r)] if removed: logger.info("\nRemoved_files:") [logger.info(f) for f in removed] # type:ignore added = target_names - source_names added = [a for a in added if not filter_file(a)] if added: logger.info("\nAdded files:") [logger.info(f) for f in added] # type:ignore logger.info("") return {"added": added, "removed": removed} def make_parser( parser: Optional[argparse.ArgumentParser] = None, prog: Optional[str] = None ) -> argparse.ArgumentParser: """Make an arg parser.""" if parser is None: parser = argparse.ArgumentParser(prog=prog) parser.add_argument(dest="source_dir", help="Source Directory") parser.add_argument(dest="target_dir", help="Target Directory") parser.add_argument(dest="dist_name", help="Dist name") return parser def run(args: Optional[argparse.Namespace] = None) -> None: """Run the cli.""" if args is None: parser = make_parser(prog=f"{sys.executable} -m hatch_jupyter_builder.compare_migrated") args = parser.parse_args() main(args.source_dir, args.target_dir, args.dist_name) hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/migrate/__init__.py0000644000000000000000000000000013615410400023127 0ustar00hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/migrate/__main__.py0000644000000000000000000000010113615410400023112 0ustar00"""Entry point for migration cli.""" from .cli import run run() hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/migrate/_migrate.py0000644000000000000000000001771713615410400023206 0ustar00"""Handle migration.""" import json import logging import os import subprocess import sys from pathlib import Path import tomli import tomli_w from packaging import version logger = logging.getLogger(__name__) logging.basicConfig() # Handle the version. # If it is a dev version, use the previous minor version. builder_version = version.parse(sys.argv[1]) if builder_version.is_devrelease: assert isinstance(builder_version, version.Version) builder_version_str = f">={builder_version.major}.{builder_version.minor - 1}.0" else: builder_version_str = f">={builder_version}" if "BUILDER_VERSION_SPEC" in os.environ: builder_version_str = os.environ["BUILDER_VERSION_SPEC"] logger.info("\n\nStarting pyproject.toml migration") warnings = [] # Read pyproject before migration to get old build requirements. pyproject = Path("pyproject.toml") if pyproject.exists(): data = tomli.loads(pyproject.read_text("utf-8")) requires = data["build-system"]["requires"] # Install the old build reqs into this venv. subprocess.run([sys.executable, "-m", "pip", "install", *requires]) requires = [ r for r in requires if not r.startswith("jupyter-packaging") and not r.startswith("setuptools") and not r.startswith("jupyter_packaging") and not r.startswith("wheel") ] else: requires = [] # Extract the current version before beginning any migration. setup_py = Path("setup.py") if setup_py.exists(): current_version = ( subprocess.check_output([sys.executable, str(setup_py), "--version"]) .decode("utf-8") .strip() ) else: warnings.append("Fill in '[project][version]' in 'pyproject.toml'") current_version = "!!UNKONWN!!" # Run the hatch migration script. logger.info("Running hatch migration") subprocess.run([sys.executable, "-m", "hatch", "new", "--init"]) # Run the jupyter-packaging migration script - must be done after # hatch migration to avoid conflicts. logger.info("Running jupyter-packaging migration") here = os.path.abspath(os.path.dirname(__file__)) prev_pythonpath = os.environ.get("PYTHONPATH", "") if prev_pythonpath: os.environ["PYTHONPATH"] = f"{here}{os.pathsep}{prev_pythonpath}" else: os.environ["PYTHONPATH"] = here subprocess.run([sys.executable, "setup.py", "--version"], capture_output=True) os.environ["PYTHONPATH"] = prev_pythonpath # Handle setup.cfg # Move flake8 config to separate file, preserving comments. # Add .flake8 file to git. setup_cfg = Path("setup.cfg") flake8 = ["[flake8]"] if setup_cfg.exists(): lines = setup_cfg.read_text("utf-8").splitlines() matches = False for line in lines: if line.strip() == "[flake8]": matches = True continue if not matches: continue if matches and line.startswith("["): break flake8.append(line) if matches: Path(".flake8").write_text("\n".join(flake8) + "\n", "utf-8") subprocess.run(["git", "add", ".flake"]) # Migrate and remove unused config. # Read in the project.toml after auto migration. logger.info("Migrating static data") data = tomli.loads(pyproject.read_text("utf-8")) tool_table = data.setdefault("tool", {}) # Handle license file. for lic_name in ["LICENSE", "COPYING.md", "LICENSE.txt"]: for fname in os.listdir("."): if fname.lower() == lic_name.lower(): data["project"]["license"] = {"file": fname} # Add the other build requirements. data["build-system"]["requires"].extend(requires) # Remove old check-manifest config. if "check-manifest" in tool_table: del tool_table["check-manifest"] # Build up the hatch config. hatch_table = tool_table.setdefault("hatch", {}) build_table = hatch_table.setdefault("build", {}) targets_table = build_table.setdefault("targets", {}) # Remove the dynamic version. if current_version and "version" in hatch_table: del hatch_table["version"] # Remove any auto-generated sdist config. if "sdist" in targets_table: del targets_table["sdist"] # Exclude the .github folder by default. targets_table["sdist"] = {"exclude": [".github"]} hooks_table = build_table.setdefault("hooks", {}) builder_table = hooks_table.setdefault("jupyter-builder", {}) builder_table["dependencies"] = [f"hatch-jupyter-builder{builder_version_str}"] builder_table["build-function"] = "hatch_jupyter_builder.npm_builder" # Migrate the jupyter-packaging static data. if "jupyter-packaging" in tool_table: packaging_table = tool_table.get("jupyter-packaging", {}) del tool_table["jupyter-packaging"] options_table = packaging_table.setdefault("options", {}) build_args_table = packaging_table.setdefault("build-args", {}) for option in ["ensured-targets", "skip-if-exists"]: if option in options_table: builder_table[option] = options_table[option] if build_args_table: builder_table["build-kwargs"] = build_args_table.copy() if build_args_table.get("npm") and "editable-build-kwargs" in builder_table: builder_table["editable-build-kwargs"]["npm"] = build_args_table["npm"] # Add artifacts config for package data that would be ignored. project_name = data.get("project", {}).get("name", "") gitignore = Path(".gitignore") artifacts = [] if gitignore.exists() and project_name and Path(project_name).exists(): text = gitignore.read_text("utf-8") for line in text.splitlines(): if line.startswith(project_name): artifacts.append(f"{line}") if artifacts: build_table["artifacts"] = artifacts # Handle setup.py - pre-commit config. if setup_py.exists(): text = setup_py.read_text("utf-8") if "pre-commit" in text: builder_table["install-pre-commit"] = True # Handle versioning with tbump - allows for static versioning and makes # it easier to use jupyter_releaser. data["project"]["version"] = current_version data["project"].pop("dynamic", None) tbump_table = tool_table.setdefault("tbump", {}) tbump_table["version"] = { "current": current_version, "regex": r""" (?P\d+)\.(?P\d+)\.(?P\d+)((?Pa|b|rc|.dev)(?P\d+))? """.strip(), } tbump_table["git"] = { "message_template": r"Bump to {new_version}", "tag_template": r"v{new_version}", } tbump_table["field"] = [{"name": "channel", "default": ""}, {"name": "release", "default": ""}] tbump_table["file"] = [ { "src": "pyproject.toml", "version_template": 'version = "{major}.{minor}.{patch}{channel}{release}"', } ] # Add entry for _version.py if it exists. version_py = Path(project_name) / "_version.py" if version_py.exists(): tbump_table["file"].append({"src": str(version_py)}) text = version_py.read_text(encoding="utf-8") if current_version not in text: warnings.append( f'Add the static version string "{current_version}" to "{version_py}" instead of dynamic version handling' ) # Add entry for package.json if it exists and has the same version. package_json = Path("package.json") if package_json.exists(): text = package_json.read_text(encoding="utf-8") npm_version = json.loads(text)["version"] if npm_version == current_version: tbump_table["file"].append( { "src": "package.json", "version_template": '"version": "{major}.{minor}.{patch}{channel}{release}"', } ) # Add a setup.py shim. shim_text = """# setup.py shim for use with applications that require it. __import__("setuptools").setup() """ setup_py.write_text(shim_text, encoding="utf-8") # Remove old files for fname in ["MANIFEST.in", "setup.cfg"]: if os.path.exists(fname): os.remove(fname) # Write out the new config. logger.info("\n\nWriting pyproject.toml") pyproject.write_text(tomli_w.dumps(data), "utf-8") if warnings: logger.info("\n\nWarning!! Not everything could be migrated automatically.") logger.info("Please address the following concerns:") for warning in warnings: logger.info(f" - {warning}") logger.info("\n\nMigration complete!") hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/migrate/cli.py0000644000000000000000000000346213615410400022156 0ustar00"""Migrate a Jupyter project from setuptools/jupyter-packaging to hatch and hatch_jupyter_builder.""" import argparse import logging import os import subprocess import sys import venv from pathlib import Path from tempfile import TemporaryDirectory from typing import Optional from hatch_jupyter_builder import __version__ as builder_version def main(td, target_dir): """Main script.""" logger = logging.getLogger(__name__) logging.basicConfig() venv.create(td, with_pip=True) python = Path(td) / "Scripts/python.exe" if os.name == "nt" else Path(td) / "bin/python" logger.info("Installing in temporary virtual environment...") # Create a virtual environment and use it to run the migration. runner = subprocess.check_call runner([python, "-m", "pip", "install", "build"]) runner([python, "-m", "pip", "install", "packaging"]) runner([python, "-m", "pip", "install", "tomli_w"]) runner([python, "-m", "pip", "install", "tomli"]) runner([python, "-m", "pip", "install", "hatch"]) runner([python, "-m", "build", target_dir, "--sdist"]) migrator = Path(__file__).parent / "_migrate.py" runner([python, migrator, builder_version], cwd=target_dir) def make_parser( parser: Optional[argparse.ArgumentParser] = None, prog: Optional[str] = None ) -> argparse.ArgumentParser: """Make a parser object.""" if parser is None: parser = argparse.ArgumentParser(prog=prog) parser.add_argument(dest="target_dir", help="Target Directory") return parser def run(args: Optional[argparse.Namespace] = None) -> None: """Run the migration.""" if args is None: parser = make_parser(prog=f"{sys.executable} -m hatch_jupyter_builder.migrate") args = parser.parse_args() with TemporaryDirectory() as td: main(td, args.target_dir) hatch_jupyter_builder-0.8.3/hatch_jupyter_builder/migrate/jupyter_packaging.py0000644000000000000000000001201213615410400025104 0ustar00"""Shim for jupyter packaging migration.""" import os import sys from pathlib import Path import tomli import tomli_w __this_shim = sys.modules.pop("jupyter_packaging") __current_directory = sys.path.pop(0) import jupyter_packaging as __real_jupyter_packaging # type:ignore sys.path.insert(0, __current_directory) sys.modules["jupyter_packaging"] = __this_shim def _write_config(path, data): pyproject = Path("pyproject.toml") top = tomli.loads(pyproject.read_text(encoding="utf-8")) current = top parts = path.split(".") for part in parts[:-1]: if part in current: current = current[part] else: current[part] = current = {} if parts[-1] in current: existing = current[parts[-1]] else: existing = current[parts[-1]] = {} existing.update(data) pyproject.write_text(tomli_w.dumps(top), encoding="utf-8") _npm_kwargs = ["path", "build_dir", "source_dir", "build_cmd", "npm"] def _normalize_path(path): path = str(path) cwd = os.getcwd() if path.startswith(cwd): return os.path.relpath(path, cwd) return path def _get_build_kwargs(**kwargs): build_kwargs = {} for name in _npm_kwargs: value = kwargs[name] if value is not None: if name in ["path", "build_dir", "source_dir"]: value = _normalize_path(value) build_kwargs[name] = value if kwargs.get("force"): build_kwargs["force"] = True return build_kwargs def skip_if_exists(paths, *args): """Shim for skip if exists""" if paths: data = {"skip-if-exists": [_normalize_path(p) for p in paths]} _write_config("tool.hatch.build.hooks.jupyter-builder", data) return __real_jupyter_packaging.skip_if_exists(paths, *args) def ensure_targets(targets): """Shim for ensure targets""" if targets: data = {"ensured-targets": [_normalize_path(t) for t in targets]} _write_config("tool.hatch.build.hooks.jupyter-builder", data) return __real_jupyter_packaging.ensure_targets(targets) def wrap_installers( pre_develop=None, pre_dist=None, post_develop=None, post_dist=None, ensured_targets=None, skip_if_exists=None, ): """Shim for wrap_installers.""" if pre_develop or post_develop: func = pre_develop or post_develop build_kwargs = _get_build_kwargs(**func.__kwargs) _write_config("tool.hatch.build.hooks.jupyter-builder.editable-build-kwargs", build_kwargs) if pre_dist or post_dist: func = pre_dist or post_dist build_kwargs = _get_build_kwargs(**func.__kwargs) _write_config("tool.hatch.build.hooks.jupyter-builder.build-kwargs", build_kwargs) if skip_if_exists: data = {"skip-if-exists": [_normalize_path(p) for p in skip_if_exists]} _write_config("tool.hatch.build.hooks.jupyter-builder", data) return __real_jupyter_packaging.wrap_installers( pre_develop=pre_develop, pre_dist=pre_dist, post_develop=post_develop, post_dist=post_dist, ensured_targets=ensured_targets, skip_if_exists=skip_if_exists, ) def create_cmdclass( prerelease_cmd=None, package_data_spec=None, data_files_spec=None, exclude=None ): """Shim for create_cmdclass.""" shared_data = {} if data_files_spec is not None: for path, dname, pattern in data_files_spec: if os.path.isabs(dname): dname = os.path.relpath(dname, os.getcwd()) # noqa if pattern == "**": shared_data[dname] = path else: shared_data[f"{dname}/{pattern}"] = f"{path}/{pattern}" _write_config("tool.hatch.build.targets.wheel.shared-data", shared_data) return __real_jupyter_packaging.create_cmdclass( prerelease_cmd=prerelease_cmd, package_data_spec=package_data_spec, data_files_spec=data_files_spec, exclude=exclude, ) def install_npm( path=None, build_dir=None, source_dir=None, build_cmd="build", force=False, npm=None ): """Shim for install_npm.""" build_kwargs = _get_build_kwargs(**locals()) if build_kwargs: _write_config("tool.hatch.build.hooks.jupyter-builder.build-kwargs", build_kwargs) return __real_jupyter_packaging.install_npm( path=path, build_dir=build_dir, source_dir=source_dir, build_cmd=build_cmd, force=force, npm=npm, ) def npm_builder( path=None, build_dir=None, source_dir=None, build_cmd="build", force=False, npm=None ): """Shim for npm_builder.""" func = __real_jupyter_packaging.npm_builder( path=path, build_dir=build_dir, source_dir=source_dir, build_cmd=build_cmd, force=force, npm=npm, ) func.__kwargs = {} for name in [*_npm_kwargs, "force"]: func.__kwargs[name] = locals()[name] return func def __getattr__(name): """Defer to the original for all others.""" return getattr(__real_jupyter_packaging, name) del __this_shim del __current_directory hatch_jupyter_builder-0.8.3/tests/__init__.py0000644000000000000000000000000013615410400016262 0ustar00hatch_jupyter_builder-0.8.3/tests/conftest.py0000644000000000000000000000146113615410400016364 0ustar00import pytest def pytest_addoption(parser): parser.addoption( "--migration-tests", default=False, type=bool, help="only run tests with the 'migration_test' pytest mark.", ) def pytest_configure(config): # register an additional marker config.addinivalue_line("markers", "migration_test") def pytest_runtest_setup(item): is_migration_test = any(mark for mark in item.iter_markers(name="migration_test")) if item.config.getoption("--migration-tests") is True: if not is_migration_test: pytest.skip("Only running tests marked as 'migration_test'.") elif is_migration_test: pytest.skip( "Skipping this test because it's marked 'migration_test'. Run integration tests using the `--migration-tests` flag." ) hatch_jupyter_builder-0.8.3/tests/test_hooks.py0000644000000000000000000000013713615410400016720 0ustar00from hatch_jupyter_builder.hooks import hatch_register_build_hook hatch_register_build_hook() hatch_jupyter_builder-0.8.3/tests/test_is_stale.py0000644000000000000000000000777113615410400017413 0ustar00from pytest import fixture from hatch_jupyter_builder import is_stale @fixture def source_dir(tmpdir): source = tmpdir.mkdir("source") source.join("file1.txt").write("original content") source.join("file2.txt").write("original content") sub = source.mkdir("sub") sub.join("subfile1.txt").write("original content") sub.join("subfile2.txt").write("original content") source.mkdir("node_modules") sub2 = source.mkdir("node_modules", "lol") sub2.join("index.js").write("use strict;") for p in source.visit(): p.setmtime(10000) return source @fixture def destination_dir(tmpdir): destination = tmpdir.mkdir("destination") destination.join("file1.rtf").write("original content") destination.join("file2.rtf").write("original content") sub = destination.mkdir("sub") sub.join("subfile1.rtf").write("original content") sub.join("subfile2.rtf").write("original content") destination.mkdir("sub2") sub2 = destination.mkdir("sub2", "lol") sub2.join("static.html").write("original content") for p in destination.visit(): p.setmtime(20000) return destination def test_destination_is_not_stale(source_dir, destination_dir): assert is_stale(str(destination_dir), str(source_dir)) is False def test_root_file_causes_stale(source_dir, destination_dir): source_dir.join("file1.txt").setmtime(30000) assert is_stale(str(destination_dir), str(source_dir)) is True def test_sub_file_causes_stale(source_dir, destination_dir): source_dir.join("sub", "subfile2.txt").setmtime(30000) assert is_stale(str(destination_dir), str(source_dir)) is True def test_folder_mtime_does_not_prevent_stale(source_dir, destination_dir): source_dir.join("sub", "subfile2.txt").setmtime(30000) destination_dir.setmtime(40000) destination_dir.join("sub").setmtime(40000) destination_dir.setmtime(40000) assert is_stale(str(destination_dir), str(source_dir)) is True def test_folder_mtime_does_not_cause_stale(source_dir, destination_dir): source_dir.setmtime(40000) source_dir.join("sub").setmtime(40000) source_dir.setmtime(40000) assert is_stale(str(destination_dir), str(source_dir)) is False # This behavior might not always be wanted? # The alternative is to check whether ALL files in destination is newer # than the newest file in source (more conservative). def test_only_newest_files_determine_stale(source_dir, destination_dir): source_dir.join("file1.txt").setmtime(30000) destination_dir.join("file1.rtf").setmtime(40000) assert is_stale(str(destination_dir), str(source_dir)) is False def test_unstale_on_equal(source_dir): assert is_stale(str(source_dir), str(source_dir)) is False def test_file_vs_dir(source_dir, destination_dir): assert is_stale(str(destination_dir.join("file1.rtf")), str(source_dir)) is False source_dir.join("file2.txt").setmtime(30000) assert is_stale(str(destination_dir.join("file1.rtf")), str(source_dir)) is True def test_dir_vs_file(source_dir, destination_dir): assert is_stale(str(destination_dir), str(source_dir.join("file1.txt"))) is False source_dir.join("file1.txt").setmtime(30000) assert is_stale(str(destination_dir), str(source_dir.join("file1.txt"))) is True def test_file_vs_file(source_dir, destination_dir): assert ( is_stale(str(destination_dir.join("file1.rtf")), str(source_dir.join("file1.txt"))) is False ) source_dir.join("file1.txt").setmtime(30000) assert ( is_stale(str(destination_dir.join("file1.rtf")), str(source_dir.join("file1.txt"))) is True ) def test_empty_dir(source_dir, tmpdir): empty_dir = tmpdir.mkdir("empty") assert is_stale(str(empty_dir), str(source_dir)) is True assert is_stale(str(source_dir), str(empty_dir)) is False assert is_stale(str(empty_dir), str(empty_dir)) is False def test_missing_dir(source_dir, destination_dir): assert not is_stale(destination_dir, "does_not_exist") assert is_stale("does_not_exist", source_dir) hatch_jupyter_builder-0.8.3/tests/test_migration.py0000644000000000000000000001233213615410400017566 0ustar00import glob import os import shutil import subprocess import sys import tempfile from pathlib import Path import pytest import tomli from hatch_jupyter_builder.compare_migrated.cli import main HERE = Path(__file__).parent.absolute() REPO_ROOT = str(HERE.parent).replace(os.sep, "/") @pytest.mark.migration_test def test_npm_builder_migration(): python = sys.executable os.environ["BUILDER_VERSION_SPEC"] = f"@file://{REPO_ROOT}" # Copy the source cookiecutter extension into two temporary directories. with tempfile.TemporaryDirectory() as td1, tempfile.TemporaryDirectory() as td2: source = HERE / "data" / "npm_builder" shutil.copytree(source / "myextension", Path(td1) / "myextension") shutil.copytree(source / "myextension", Path(td2) / "myextension") target1 = Path(td1) / "myextension" target2 = Path(td2) / "myextension" # Migrate the first extension and compare its migrated pyproject.toml # to the expected one. subprocess.check_call([python, "-m", "hatch_jupyter_builder.migrate", target1]) source_toml = source.joinpath("pyproject.toml").read_text(encoding="utf-8") target_toml = target1.joinpath("pyproject.toml").read_text(encoding="utf-8") source_data = tomli.loads(source_toml) target_data = tomli.loads(target_toml) # The hatchling and hatch_jupyter_builder versions might differ. source_data["build-system"]["requires"] = target_data["build-system"]["requires"] source_hooks = source_data["tool"]["hatch"]["build"]["hooks"] target_hooks = target_data["tool"]["hatch"]["build"]["hooks"] source_hooks["jupyter-builder"] = target_hooks["jupyter-builder"] assert source_data == target_data # Compare the produced wheel and sdist for the migrated and unmigrated # extensions. for asset in ["sdist", "wheel"]: results = main(target2, target1, asset) if asset == "sdist": for item in results["removed"]: assert "static/remoteEntry." in item for item in results["added"]: assert ".eslintrc.js" in item or "static/remoteEntry." in item else: for item in results["removed"]: assert "static/remoteEntry." in item or "top_level.txt" in item for item in results["added"]: assert "static/remoteEntry." in item # Check the produced dist file in strict mode. dist_files = glob.glob(str(target1 / "dist/*.*")) assert len(dist_files) == 1 subprocess.check_call([python, "-m", "twine", "check", "--strict", dist_files[0]]) @pytest.mark.migration_test def test_create_cmdclass_migration(): python = sys.executable os.environ["BUILDER_VERSION_SPEC"] = f"@file://{REPO_ROOT}" # Copy the source cookiecutter extension into two temporary directories. with tempfile.TemporaryDirectory() as td1, tempfile.TemporaryDirectory() as td2: source = HERE / "data" / "create_cmdclass" shutil.copytree(source / "myproject", Path(td1) / "myproject") shutil.copytree(source / "myproject", Path(td2) / "myproject") target1 = Path(td1) / "myproject" target2 = Path(td2) / "myproject" # Migrate the first extension and compare its migrated pyproject.toml # to the expected one. subprocess.check_call([python, "-m", "hatch_jupyter_builder.migrate", target1]) source_toml = source.joinpath("pyproject.toml").read_text(encoding="utf-8") target_toml = target1.joinpath("pyproject.toml").read_text(encoding="utf-8") source_data = tomli.loads(source_toml) target_data = tomli.loads(target_toml) # The hatchling and hatch_jupyter_builder versions might differ. source_data["build-system"]["requires"] = target_data["build-system"]["requires"] source_hooks = source_data["tool"]["hatch"]["build"]["hooks"] target_hooks = target_data["tool"]["hatch"]["build"]["hooks"] source_hooks["jupyter-builder"] = target_hooks["jupyter-builder"] assert source_data == target_data # Compare the produced wheel and sdist for the migrated and unmigrated # extensions. for asset in ["sdist", "wheel"]: results = main(target2, target1, asset) for item in results["removed"]: assert ( "remoteEntry." in item or "embed-bundle.js" in item or "dist-info/LICENSE.txt" in item or "dist-info/top_level.txt" in item ) if asset == "sdist": assert len(results["added"]) == 8 else: for item in results["added"]: assert ( "remoteEntry." in item or "licenses/LICENSE.txt" in item or "dist-info/entry_points.txt" in item ) # Check the produced dist file in strict mode. dist_files = glob.glob(str(target1 / "dist/*.*")) assert len(dist_files) == 1 subprocess.check_call([python, "-m", "twine", "check", "--strict", dist_files[0]]) hatch_jupyter_builder-0.8.3/tests/test_npm_builder.py0000644000000000000000000001062413615410400020077 0ustar00import os import sys from unittest.mock import call import pytest from hatch_jupyter_builder import npm_builder @pytest.fixture def repo(tmp_path): os.makedirs(os.path.join(tmp_path, ".git")) os.chdir(tmp_path) return tmp_path def test_npm_builder(mocker, repo): which = mocker.patch("hatch_jupyter_builder.utils.which") run = mocker.patch("hatch_jupyter_builder.utils.run") which.return_value = "foo" npm_builder("wheel", "standard", path=repo) run.assert_has_calls( [ call(["foo", "install"], cwd=str(repo)), call(["foo", "run", "build"], cwd=str(repo)), ] ) def test_npm_build_skip(mocker, repo): which = mocker.patch("hatch_jupyter_builder.utils.which") run = mocker.patch("hatch_jupyter_builder.utils.run") os.environ["HATCH_JUPYTER_BUILDER_SKIP_NPM"] = "1" which.return_value = "foo" npm_builder("wheel", "standard", path=repo) run.assert_not_called() del os.environ["HATCH_JUPYTER_BUILDER_SKIP_NPM"] sys.argv = [*sys.argv, "--skip-npm"] npm_builder("wheel", "standard", path=repo) run.assert_not_called() def test_npm_builder_yarn(mocker, repo): which = mocker.patch("hatch_jupyter_builder.utils.which") run = mocker.patch("hatch_jupyter_builder.utils.run") repo.joinpath("yarn.lock").write_text("hello") which.return_value = "foo" npm_builder("wheel", "standard", path=repo) run.assert_has_calls( [ call(["foo", "install"], cwd=str(repo)), call(["foo", "run", "build"], cwd=str(repo)), ] ) def test_npm_builder_missing_yarn(mocker, repo): which = mocker.patch("hatch_jupyter_builder.utils.which") run = mocker.patch("hatch_jupyter_builder.utils.run") repo.joinpath("yarn.lock").write_text("hello") which.side_effect = ["", "foo"] npm_builder("wheel", "standard", path=repo) run.assert_has_calls( [ call(["foo", "install"], cwd=str(repo)), call(["foo", "run", "build"], cwd=str(repo)), ] ) def test_npm_builder_path(mocker, tmp_path): which = mocker.patch("hatch_jupyter_builder.utils.which") run = mocker.patch("hatch_jupyter_builder.utils.run") which.return_value = "foo" npm_builder("wheel", "standard", path=tmp_path) run.assert_has_calls( [ call(["foo", "install"], cwd=str(tmp_path)), call(["foo", "run", "build"], cwd=str(tmp_path)), ] ) def test_npm_builder_editable(mocker, repo): which = mocker.patch("hatch_jupyter_builder.utils.which") run = mocker.patch("hatch_jupyter_builder.utils.run") which.return_value = "foo" npm_builder("wheel", "editable", path=repo, editable_build_cmd="foo") run.assert_has_calls( [ call(["foo", "install"], cwd=str(repo)), call(["foo", "run", "foo"], cwd=str(repo)), ] ) def test_npm_builder_npm_str(mocker, repo): which = mocker.patch("hatch_jupyter_builder.utils.which") run = mocker.patch("hatch_jupyter_builder.utils.run") which.return_value = "npm" npm_builder("wheel", "standard", path=repo, npm="npm") run.assert_has_calls( [ call(["npm", "install"], cwd=str(repo)), call(["npm", "run", "build"], cwd=str(repo)), ] ) def test_npm_builder_npm_build_command_none(mocker, repo): which = mocker.patch("hatch_jupyter_builder.utils.which") run = mocker.patch("hatch_jupyter_builder.utils.run") which.return_value = "npm" npm_builder("wheel", "standard", path=repo, build_cmd=None) run.assert_has_calls([call(["npm", "install"], cwd=str(repo))]) def test_npm_builder_not_stale(mocker, repo): which = mocker.patch("hatch_jupyter_builder.utils.which") run = mocker.patch("hatch_jupyter_builder.utils.run") is_stale = mocker.patch("hatch_jupyter_builder.utils.is_stale") is_stale.return_value = False which.return_value = "foo" npm_builder("wheel", "standard", path=repo, build_dir=repo, source_dir=repo) run.assert_not_called() def test_npm_builder_no_npm(mocker, repo): which = mocker.patch("hatch_jupyter_builder.utils.which") run = mocker.patch("hatch_jupyter_builder.utils.run") is_stale = mocker.patch("hatch_jupyter_builder.utils.is_stale") is_stale.return_value = False which.return_value = "" with pytest.raises(ValueError): npm_builder("wheel", "standard", path=repo) run.assert_not_called() hatch_jupyter_builder-0.8.3/tests/test_plugin.py0000644000000000000000000000744013615410400017077 0ustar00import os import platform import subprocess import sys import venv import warnings from pathlib import Path import pytest from hatchling.metadata.core import ProjectMetadata from hatchling.plugin.manager import PluginManager from hatch_jupyter_builder.plugin import JupyterBuildHook def test_build_hook(tmp_path): manager = PluginManager() meta = ProjectMetadata(".", manager, {}) if "SKIP_JUPYTER_BUILD" in os.environ: del os.environ["SKIP_JUPYTER_BUILD"] config = { "build-function": "test.foo", "ensured-targets": ["test.py"], "build-kwargs": {"foo-bar": "1", "fizz_buzz": "2"}, "install-pre-commit-hook": True, } os.chdir(tmp_path) test = Path("test.py") text = """ def foo(target_name, version, foo_bar=None, fizz_buzz=None): return(target_name) """ test.write_text(text, encoding="utf-8") os.makedirs(".git/hooks") hook = JupyterBuildHook(tmp_path, config, {}, meta, tmp_path, "wheel") assert hook.initialize("standard", {}) assert hook.initialize("editable", {}) hook = JupyterBuildHook(tmp_path, config, {}, meta, tmp_path, "sdist") assert hook.initialize("standard", {}) hook = JupyterBuildHook(tmp_path, {}, {}, meta, tmp_path, "wheel") assert hook.initialize("standard", {}) assert hook.initialize("editable", {}) config["skip-if-exists"] = ["foo", "bar"] assert hook.initialize("standard", {}) del config["skip-if-exists"] config["editable-build-kwargs"] = {"foo-bar": "2", "fizz_buzz": "3"} assert hook.initialize("editable", {}) hook = JupyterBuildHook(tmp_path, config, {}, meta, tmp_path, "foo") assert not hook.initialize("standard", {}) text = """ def foo(target_name, version, foo_bar=None, fizz_buzz=None): raise RuntimeError('trigger error') """ test.write_text(text, encoding="utf-8") # Force a re-import del sys.modules["test"] hook = JupyterBuildHook(tmp_path, config, {}, meta, tmp_path, "wheel") with pytest.raises(RuntimeError): hook.initialize("editable", {}) os.environ["SKIP_JUPYTER_BUILDER"] = "1" assert not hook.initialize("standard", {}) del os.environ["SKIP_JUPYTER_BUILDER"] config["optional-editable-build"] = "true" hook = JupyterBuildHook(tmp_path, config, {}, meta, tmp_path, "wheel") with warnings.catch_warnings(): warnings.simplefilter("ignore") assert hook.initialize("editable", {}) config["optional-editable-build"] = True hook = JupyterBuildHook(tmp_path, config, {}, meta, tmp_path, "wheel") with warnings.catch_warnings(): warnings.simplefilter("ignore") assert hook.initialize("editable", {}) del sys.modules["test"] HERE = Path(__file__).parent REPO_ROOT = str(HERE.parent).replace(os.sep, "/") TOML_CONTENT = f""" [build-system] requires = ["hatchling>=1.0"] build-backend = "hatchling.build" [project] name = "test" version = "0.6.0" [tool.hatch.build.hooks.jupyter-builder] dependencies = ["hatch-jupyter-builder@file://{REPO_ROOT}"] """ @pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="Does not work on PyPy") def test_hatch_build(tmp_path): venv.create(tmp_path, with_pip=True) if os.name == "nt": python = Path(tmp_path) / "Scripts/python.exe" else: python = Path(tmp_path) / "bin/python" pyproject = Path(tmp_path) / "pyproject.toml" pyproject.write_text(TOML_CONTENT, "utf-8") test = Path(tmp_path) / "test.py" test.write_text("print('hello')", "utf-8") env = os.environ.copy() # Handle running min version test. if "PIP_CONSTRAINT" in env: del env["PIP_CONSTRAINT"] subprocess.check_call([python, "-m", "pip", "install", "build"], cwd=tmp_path, env=env) subprocess.check_call([python, "-m", "build", "--sdist", "."], cwd=tmp_path, env=env) hatch_jupyter_builder-0.8.3/tests/test_utils.py0000644000000000000000000000412413615410400016735 0ustar00import os import shlex import sys from pathlib import Path import pytest from hatch_jupyter_builder import utils def test_ensure_targets(tmp_path): os.chdir(tmp_path) Path("foo.txt").touch() os.mkdir("bar") Path("bar/fizz.md").touch() utils.ensure_targets(["foo.txt", "bar/fizz.md"]) with pytest.raises(ValueError): utils.ensure_targets(["bar.txt"]) def test_run(): cmd = f"{sys.executable} --version" utils.run(cmd) utils.run(shlex.split(cmd)) def test_normalize_kwargs(): kwargs = {"foo-bar": "2", "fizz_buzz": "1"} result = utils.normalize_kwargs(kwargs) assert result == {"foo_bar": "2", "fizz_buzz": "1"} def test_normalize_cmd(): cmd = f"{sys.executable} --version" assert utils.normalize_cmd(cmd) == shlex.split(cmd) assert utils.normalize_cmd(shlex.split(cmd)) == shlex.split(cmd) with pytest.raises(ValueError): utils.normalize_cmd("does_not_exist") def test_get_build_func(tmp_path): os.chdir(tmp_path) test = Path("test.py") text = "def foo(target_name, version):\n return(target_name)\n" test.write_text(text, encoding="utf-8") callback = utils.get_build_func("test.foo") assert callback("fizz", "buzz") == "fizz" with pytest.raises(ImportError): utils.get_build_func("does_not_exist.bar") with pytest.raises(AttributeError): utils.get_build_func("test.bar") del sys.modules["test"] def test_should_skip(tmp_path): assert not utils.should_skip("a") assert not utils.should_skip([]) os.chdir(tmp_path) Path(tmp_path).joinpath("foo.txt").touch() assert utils.should_skip(["foo.txt"]) assert not utils.should_skip(["foo.txt", "bar.txt"]) Path(tmp_path).joinpath("bar.txt").touch() assert utils.should_skip(["bar.txt"]) assert utils.should_skip(["foo.txt", "bar.txt"]) def test_install_pre_commit_hook(tmp_path): os.chdir(tmp_path) utils.install_pre_commit_hook() assert not os.path.exists(".git/hooks") os.makedirs(".git/hooks") utils.install_pre_commit_hook() assert os.path.exists(".git/hooks/pre-commit") hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/pyproject.toml0000644000000000000000000000523413615410400023130 0ustar00[build-system] requires = [ "hatchling>=1.3.1", "jupyterlab==3.*", ] build-backend = "hatchling.build" [project] name = "myproject" description = "A Custom Jupyter Widget Library" readme = "README.md" license = { file = "LICENSE.txt" } requires-python = ">=3.6" authors = [ { name = "me", email = "me@me.com" }, ] keywords = [ "IPython", "Jupyter", "Widgets", ] classifiers = [ "Framework :: Jupyter", "Intended Audience :: Developers", "Intended Audience :: Science/Research", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", ] dependencies = [ "ipywidgets>=7.0.0", ] version = "0.1.0.dev0" [project.optional-dependencies] docs = [ "jupyter_sphinx", "nbsphinx", "nbsphinx-link", "pypandoc", "pytest_check_links", "recommonmark", "sphinx>=1.5", "sphinx_rtd_theme", ] examples = [] test = [ "nbval", "pytest-cov", "pytest>=4.6", ] [project.urls] Homepage = "https://github.com/myorg/myproject" [tool.hatch.build] artifacts = [ "myproject/nbextension/index.*", "myproject/labextension/*.tgz", "myproject/labextension", ] [tool.hatch.build.targets.wheel.shared-data] "myproject/nbextension" = "share/jupyter/nbextensions/myproject" "myproject/labextension" = "share/jupyter/labextensions/myproject" "./install.json" = "share/jupyter/labextensions/myproject/install.json" "./myproject.json" = "etc/jupyter/nbconfig/notebook.d/myproject.json" [tool.hatch.build.targets.sdist] exclude = [ ".github", ] [tool.hatch.build.hooks.jupyter-builder] build-function = "hatch_jupyter_builder.npm_builder" ensured-targets = [ "myproject/nbextension/index.js", "myproject/labextension/package.json", ] skip-if-exists = [ "myproject/nbextension/index.js", "myproject/labextension/package.json", ] dependencies = [ "hatch-jupyter-builder>=0.5.0", ] [tool.hatch.build.hooks.jupyter-builder.build-kwargs] path = "." build_cmd = "build:prod" [tool.tbump] field = [ { name = "channel", default = "" }, { name = "release", default = "" }, ] file = [ { src = "pyproject.toml", version_template = "version = \"{major}.{minor}.{patch}{channel}{release}\"" }, { src = "myproject/_version.py" }, ] [tool.tbump.version] current = "0.1.0.dev0" regex = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)((?Pa|b|rc|.dev)(?P\\d+))?" [tool.tbump.git] message_template = "Bump to {new_version}" tag_template = "v{new_version}" hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/.eslintignore0000644000000000000000000000005313615410400024725 0ustar00node_modules dist coverage **/*.d.ts tests hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/.eslintrc.js0000644000000000000000000000145513615410400024470 0ustar00module.exports = { extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended', ], parser: '@typescript-eslint/parser', parserOptions: { project: 'tsconfig.eslint.json', sourceType: 'module', }, plugins: ['@typescript-eslint'], rules: { '@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }], '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-namespace': 'off', '@typescript-eslint/no-use-before-define': 'off', '@typescript-eslint/quotes': [ 'error', 'single', { avoidEscape: true, allowTemplateLiterals: false }, ], curly: ['error', 'all'], eqeqeq: 'error', 'prefer-arrow-callback': 'error', }, }; hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/.gitignore0000644000000000000000000000370413615410400024220 0ustar00# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *,cover .hypothesis/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py # Flask instance folder instance/ # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ docs/source/_static/embed-bundle.js docs/source/_static/embed-bundle.js.map # PyBuilder target/ # IPython Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # dotenv .env # virtualenv venv/ ENV/ # Spyder project settings .spyderproject # Rope project settings .ropeproject # ========================= # Operating System Files # ========================= # OSX # ========================= .DS_Store .AppleDouble .LSOverride # Thumbnails ._* # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 .TemporaryItems .Trashes .VolumeIcon.icns # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk # Windows # ========================= # Windows image file caches Thumbs.db ehthumbs.db # Folder config file Desktop.ini # Recycle Bin used on file shares $RECYCLE.BIN/ # Windows Installer files *.cab *.msi *.msm *.msp # Windows shortcuts *.lnk # NPM # ---- **/node_modules/ myproject/nbextension/index.* myproject/labextension/*.tgz # Coverage data # ------------- **/coverage/ # Packed lab extensions myproject/labextension hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/.npmignore0000644000000000000000000000015313615410400024222 0ustar00.DS_Store node_modules/ tests/ .jshintrc # Ignore any build output from python: dist/*.tar.gz dist/*.wheel hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/.prettierignore0000644000000000000000000000006413615410400025267 0ustar00node_modules **/node_modules **/lib **/package.json hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/.prettierrc0000644000000000000000000000003213615410400024403 0ustar00{ "singleQuote": true } hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/LICENSE.txt0000644000000000000000000000271713615410400024056 0ustar00Copyright (c) 2022 me All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/MANIFEST.in0000644000000000000000000000122513615410400023762 0ustar00include LICENSE.txt include README.md include setup.py include pyproject.toml include pytest.ini include .coverage.rc include tsconfig.json include package.json include webpack.config.js include myproject/labextension/*.tgz # Documentation graft docs exclude docs/\#* prune docs/build prune docs/gh-pages prune docs/dist # Examples graft examples # Tests graft tests prune tests/build # Javascript files graft myproject/nbextension graft src graft css prune **/node_modules prune coverage prune lib # Patterns to exclude from any directory global-exclude *~ global-exclude *.pyc global-exclude *.pyo global-exclude .git global-exclude .ipynb_checkpoints hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/README.md0000644000000000000000000000420213615410400023501 0ustar00# myproject [![Build Status](https://travis-ci.org/myorg/myproject.svg?branch=master)](https://travis-ci.org/myorg/myproject) [![codecov](https://codecov.io/gh/myorg/myproject/branch/master/graph/badge.svg)](https://codecov.io/gh/myorg/myproject) A Custom Jupyter Widget Library ## Installation You can install using `pip`: ```bash pip install myproject ``` If you are using Jupyter Notebook 5.2 or earlier, you may also need to enable the nbextension: ```bash jupyter nbextension enable --py [--sys-prefix|--user|--system] myproject ``` ## Development Installation Create a dev environment: ```bash conda create -n myproject-dev -c conda-forge nodejs yarn python jupyterlab conda activate myproject-dev ``` Install the python. This will also build the TS package. ```bash pip install -e ".[test, examples]" ``` When developing your extensions, you need to manually enable your extensions with the notebook / lab frontend. For lab, this is done by the command: ``` jupyter labextension develop --overwrite . yarn run build ``` For classic notebook, you need to run: ``` jupyter nbextension install --sys-prefix --symlink --overwrite --py myproject jupyter nbextension enable --sys-prefix --py myproject ``` Note that the `--symlink` flag doesn't work on Windows, so you will here have to run the `install` command every time that you rebuild your extension. For certain installations you might also need another flag instead of `--sys-prefix`, but we won't cover the meaning of those flags here. ### How to see your changes #### Typescript: If you use JupyterLab to develop then you can watch the source directory and run JupyterLab at the same time in different terminals to watch for changes in the extension's source and automatically rebuild the widget. ```bash # Watch the source directory in one terminal, automatically rebuilding when needed yarn run watch # Run JupyterLab in another terminal jupyter lab ``` After a change wait for the build to finish and then refresh your browser and the changes should take effect. #### Python: If you make a change to the python code then you will need to restart the notebook kernel to have it take effect. hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/babel.config.js0000644000000000000000000000026113615410400025072 0ustar00module.exports = { sourceMap: 'inline', presets: [ [ '@babel/preset-env', { targets: { node: 'current', }, }, ], ], }; hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/codecov.yml0000644000000000000000000000033113615410400024366 0ustar00comment: off # show coverage in CI status, but never consider it a failure coverage: status: project: default: target: 0% patch: default: target: 0% ignore: - 'myproject/tests' hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/install.json0000644000000000000000000000026313615410400024566 0ustar00{ "packageManager": "python", "packageName": "myproject", "uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package myproject" } hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/jest.config.js0000644000000000000000000000075713615410400025004 0ustar00module.exports = { automock: false, moduleNameMapper: { '\\.(css|less|sass|scss)$': 'identity-obj-proxy', }, preset: 'ts-jest/presets/js-with-babel', moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], testPathIgnorePatterns: ['/lib/', '/node_modules/'], testRegex: '/__tests__/.*.spec.ts[x]?$', transformIgnorePatterns: ['/node_modules/(?!(@jupyter(lab|-widgets)/.*)/)'], globals: { 'ts-jest': { tsconfig: '/tsconfig.json', }, }, }; hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/myproject.json0000644000000000000000000000007713615410400025137 0ustar00{ "load_extensions": { "myproject/extension": true } } hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/package.json0000644000000000000000000000544413615410400024521 0ustar00{ "name": "myproject", "version": "0.1.0", "description": "A Custom Jupyter Widget Library", "keywords": [ "jupyter", "jupyterlab", "jupyterlab-extension", "widgets" ], "files": [ "lib/**/*.js", "dist/*.js", "css/*.css" ], "homepage": "https://github.com/myorg/myproject", "bugs": { "url": "https://github.com/myorg/myproject/issues" }, "license": "BSD-3-Clause", "author": { "name": "me", "email": "me@me.com" }, "main": "lib/index.js", "types": "./lib/index.d.ts", "repository": { "type": "git", "url": "https://github.com/myorg/myproject" }, "scripts": { "build": "npm run build:lib && npm run build:nbextension && npm run build:labextension:dev", "build:prod": "npm run build:lib && npm run build:nbextension && npm run build:labextension", "build:labextension": "jupyter labextension build .", "build:labextension:dev": "jupyter labextension build --development True .", "build:lib": "tsc", "build:nbextension": "webpack", "clean": "npm run clean:lib && npm run clean:nbextension && npm run clean:labextension", "clean:lib": "rimraf lib", "clean:labextension": "rimraf myproject/labextension", "clean:nbextension": "rimraf myproject/nbextension/static/index.js", "lint": "eslint . --ext .ts,.tsx --fix", "lint:check": "eslint . --ext .ts,.tsx", "prepack": "npm run build:lib", "test": "jest", "watch": "npm-run-all -p watch:*", "watch:lib": "tsc -w", "watch:nbextension": "webpack --watch --mode=development", "watch:labextension": "jupyter labextension watch ." }, "dependencies": { "@jupyter-widgets/base": "^1.1.10 || ^2.0.0 || ^3.0.0 || ^4.0.0" }, "devDependencies": { "@babel/core": "^7.5.0", "@babel/preset-env": "^7.5.0", "@jupyterlab/builder": "^3.0.0", "@phosphor/application": "^1.6.0", "@phosphor/widgets": "^1.6.0", "@types/jest": "^26.0.0", "@types/webpack-env": "^1.13.6", "@typescript-eslint/eslint-plugin": "^3.6.0", "@typescript-eslint/parser": "^3.6.0", "acorn": "^7.2.0", "css-loader": "^3.2.0", "eslint": "^7.4.0", "eslint-config-prettier": "^6.11.0", "eslint-plugin-prettier": "^3.1.4", "fs-extra": "^7.0.0", "identity-obj-proxy": "^3.0.0", "jest": "^26.0.0", "mkdirp": "^0.5.1", "npm-run-all": "^4.1.3", "prettier": "^2.0.5", "rimraf": "^2.6.2", "source-map-loader": "^1.1.3", "style-loader": "^1.0.0", "ts-jest": "^26.0.0", "ts-loader": "^8.0.0", "typescript": "~4.1.3", "webpack": "^5.61.0", "webpack-cli": "^4.0.0" }, "jupyterlab": { "extension": "lib/plugin", "outputDir": "myproject/labextension/", "sharedPackages": { "@jupyter-widgets/base": { "bundled": false, "singleton": true } } } } hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/pyproject.toml0000644000000000000000000000022113615410400025133 0ustar00[build-system] requires = ["jupyter_packaging==0.7.9", "jupyterlab==3.*", "setuptools>=40.8.0", "wheel"] build-backend = "setuptools.build_meta" hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/pytest.ini0000644000000000000000000000017613615410400024261 0ustar00[pytest] testpaths = myproject/tests examples norecursedirs = node_modules .ipynb_checkpoints addopts = --nbval --current-env hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/readthedocs.yml0000644000000000000000000000021413615410400025231 0ustar00type: sphinx python: version: 3.5 pip_install: true extra_requirements: - examples - docs conda: file: docs/environment.yml hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/setup.cfg0000644000000000000000000000022213615410400024041 0ustar00[bdist_wheel] universal=1 [metadata] long_description = file: README.md long_description_content_type = text/markdown license_file = LICENSE.txt hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/setup.py0000644000000000000000000000563413615410400023746 0ustar00#!/usr/bin/env python # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import os from glob import glob from os.path import join as pjoin from jupyter_packaging import ( combine_commands, create_cmdclass, ensure_targets, get_version, install_npm, skip_if_exists, ) from setuptools import find_packages, setup HERE = os.path.dirname(os.path.abspath(__file__)) # The name of the project name = "myproject" # Get the version version = get_version(pjoin(name, "_version.py")) # Representative files that should exist after a successful build jstargets = [ pjoin(HERE, name, "nbextension", "index.js"), pjoin(HERE, name, "labextension", "package.json"), ] package_data_spec = {name: ["nbextension/**js*", "labextension/**"]} data_files_spec = [ ("share/jupyter/nbextensions/myproject", "myproject/nbextension", "**"), ("share/jupyter/labextensions/myproject", "myproject/labextension", "**"), ("share/jupyter/labextensions/myproject", ".", "install.json"), ("etc/jupyter/nbconfig/notebook.d", ".", "myproject.json"), ] cmdclass = create_cmdclass( "jsdeps", package_data_spec=package_data_spec, data_files_spec=data_files_spec ) npm_install = combine_commands( install_npm(HERE, build_cmd="build:prod"), ensure_targets(jstargets), ) cmdclass["jsdeps"] = skip_if_exists(jstargets, npm_install) setup_args = dict( name=name, description="A Custom Jupyter Widget Library", version=version, scripts=glob(pjoin("scripts", "*")), cmdclass=cmdclass, packages=find_packages(), author="me", author_email="me@me.com", url="https://github.com/myorg/myproject", license="BSD", platforms="Linux, Mac OS X, Windows", keywords=["Jupyter", "Widgets", "IPython"], classifiers=[ "Intended Audience :: Developers", "Intended Audience :: Science/Research", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Framework :: Jupyter", ], include_package_data=True, python_requires=">=3.6", install_requires=[ "ipywidgets>=7.0.0", ], extras_require={ "test": [ "pytest>=4.6", "pytest-cov", "nbval", ], "examples": [ # Any requirements for the examples to run ], "docs": [ "jupyter_sphinx", "nbsphinx", "nbsphinx-link", "pytest_check_links", "pypandoc", "recommonmark", "sphinx>=1.5", "sphinx_rtd_theme", ], }, entry_points={}, ) if __name__ == "__main__": setup(**setup_args) hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/tsconfig.eslint.json0000644000000000000000000000014213615410400026225 0ustar00{ "extends": "./tsconfig.json", "include": ["src/**/*.ts", "src/**/*.tsx"], "exclude": [] } hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/tsconfig.json0000644000000000000000000000103513615410400024732 0ustar00{ "compilerOptions": { "declaration": true, "esModuleInterop": true, "lib": ["es2015", "dom"], "module": "commonjs", "moduleResolution": "node", "noEmitOnError": true, "noUnusedLocals": true, "outDir": "lib", "resolveJsonModule": true, "rootDir": "src", "skipLibCheck": true, "sourceMap": true, "strict": true, "strictPropertyInitialization": false, "target": "es2018", "types": ["jest"] }, "include": ["src/**/*.ts", "src/**/*.tsx"], "exclude": ["src/**/__tests__"] } hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/webpack.config.js0000644000000000000000000000410013615410400025435 0ustar00const path = require('path'); const version = require('./package.json').version; // Custom webpack rules const rules = [ { test: /\.ts$/, loader: 'ts-loader' }, { test: /\.js$/, loader: 'source-map-loader' }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }, ]; // Packages that shouldn't be bundled but loaded at runtime const externals = ['@jupyter-widgets/base']; const resolve = { // Add '.ts' and '.tsx' as resolvable extensions. extensions: ['.webpack.js', '.web.js', '.ts', '.js'], }; module.exports = [ /** * Notebook extension * * This bundle only contains the part of the JavaScript that is run on load of * the notebook. */ { entry: './src/extension.ts', output: { filename: 'index.js', path: path.resolve(__dirname, 'myproject', 'nbextension'), libraryTarget: 'amd', publicPath: '', }, module: { rules: rules, }, devtool: 'source-map', externals, resolve, }, /** * Embeddable myproject bundle * * This bundle is almost identical to the notebook extension bundle. The only * difference is in the configuration of the webpack public path for the * static assets. * * The target bundle is always `dist/index.js`, which is the path required by * the custom widget embedder. */ { entry: './src/index.ts', output: { filename: 'index.js', path: path.resolve(__dirname, 'dist'), libraryTarget: 'amd', library: 'myproject', publicPath: 'https://unpkg.com/myproject@' + version + '/dist/', }, devtool: 'source-map', module: { rules: rules, }, externals, resolve, }, /** * Documentation widget bundle * * This bundle is used to embed widgets in the package documentation. */ { entry: './src/index.ts', output: { filename: 'embed-bundle.js', path: path.resolve(__dirname, 'docs', 'source', '_static'), library: 'myproject', libraryTarget: 'amd', }, module: { rules: rules, }, devtool: 'source-map', externals, resolve, }, ]; hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/.github/workflows/build.yml0000644000000000000000000000304413615410400027444 0ustar00name: Build on: push: branches: main pull_request: branches: '*' jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Install node uses: actions/setup-node@v1 with: node-version: '12.x' - name: Install Python uses: actions/setup-python@v2 with: python-version: '3.7' architecture: 'x64' - name: Setup pip cache uses: actions/cache@v2 with: path: ~/.cache/pip key: pip-3.7-${{ hashFiles('package.json') }} restore-keys: | pip-3.7- pip- - name: Get npm cache directory id: npm-cache run: | echo "::set-output name=dir::$(npm config get cache)" - uses: actions/cache@v2 with: path: ${{ steps.npm-cache.outputs.dir }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node- - name: Install dependencies run: | python -m pip install -U pip setuptools codecov npm install -g codecov - name: Test the extension run: | python -m pip install --upgrade -v -e ".[test, examples, docs]" yarn run lint:check pytest yarn run test - name: Check docs can be build + links run: | sudo apt install -y pandoc pushd docs make html python -m pytest --check-links popd hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/css/widget.css0000644000000000000000000000011213615410400025003 0ustar00.custom-widget { background-color: lightseagreen; padding: 0px 2px; } hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/docs/Makefile0000644000000000000000000000114313615410400024613 0ustar00# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build SPHINXPROJ = myproject SOURCEDIR = source BUILDDIR = build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/docs/environment.yml0000644000000000000000000000025113615410400026241 0ustar00name: myproject_docs channels: - conda-forge dependencies: - python=3.* - nodejs - jupyter_sphinx - sphinx - sphinx_rtd_theme - nbsphinx - nbsphinx-link hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/docs/make.bat0000644000000000000000000000141513615410400024562 0ustar00@ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=source set BUILDDIR=build set SPHINXPROJ=myproject if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% :end popd hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/docs/source/conf.py0000644000000000000000000001422113615410400025753 0ustar00#!/usr/bin/env python3 # # myproject documentation build configuration file # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ "sphinx.ext.autodoc", "sphinx.ext.viewcode", "sphinx.ext.intersphinx", "sphinx.ext.napoleon", "sphinx.ext.todo", "nbsphinx", "jupyter_sphinx", "nbsphinx_link", ] # Set the nbsphinx JS path to empty to avoid showing twice of the widgets nbsphinx_requirejs_path = "" nbsphinx_widgets_path = "" # Ensure our extension is available: import sys from os.path import dirname from os.path import join as pjoin docs = dirname(dirname(__file__)) root = dirname(docs) sys.path.insert(0, root) sys.path.insert(0, pjoin(docs, "sphinxext")) # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = ".rst" # The master toctree document. master_doc = "index" # General information about the project. project = "myproject" copyright = "2022, me" author = "me" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. # get version from python package: import os here = os.path.dirname(__file__) repo = os.path.join(here, "..", "..") _version_py = os.path.join(repo, "myproject", "_version.py") version_ns = {} with open(_version_py) as f: exec(f.read(), version_ns) # noqa # The short X.Y version. version = "%i.%i" % version_ns["version_info"][:2] # The full version, including alpha/beta/rc tags. release = version_ns["__version__"] # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path exclude_patterns = ["**.ipynb_checkpoints"] # The name of the Pygments (syntax highlighting) style to use. pygments_style = "sphinx" # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ---------------------------------------------- # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] # -- Options for HTMLHelp output ------------------------------------------ # Output file base name for HTML help builder. htmlhelp_basename = "myprojectdoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, "myproject.tex", "myproject Documentation", "me", "manual"), ] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [(master_doc, "myproject", "myproject Documentation", [author], 1)] # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ( master_doc, "myproject", "myproject Documentation", author, "myproject", "A Custom Jupyter Widget Library", "Miscellaneous", ), ] # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {"https://docs.python.org/": None} # Read The Docs # on_rtd is whether we are on readthedocs.org, this line of code grabbed from # docs.readthedocs.org on_rtd = os.environ.get("READTHEDOCS", None) == "True" if not on_rtd: # only import and set the theme if we're building docs locally import sphinx_rtd_theme html_theme = "sphinx_rtd_theme" html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # otherwise, readthedocs.org uses their theme by default, so no need to specify it # Uncomment this line if you have know exceptions in your included notebooks # that nbsphinx complains about: # nbsphinx_allow_errors = True # exception ipstruct.py ipython_genutils from sphinx.util import logging logger = logging.getLogger(__name__) def setup(app): def add_scripts(app): for fname in ["helper.js", "embed-bundle.js"]: if not os.path.exists(os.path.join(here, "_static", fname)): logger.warning("missing javascript file: %s" % fname) app.add_js_file(fname) app.connect("builder-inited", add_scripts) hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/docs/source/develop-install.rst0000644000000000000000000000146413615410400030315 0ustar00 Developer install ================= To install a developer version of myproject, you will first need to clone the repository:: git clone https://github.com/myorg/myproject cd myproject Next, install it with a develop install using pip:: pip install -e . If you are planning on working on the JS/frontend code, you should also do a link installation of the extension:: jupyter nbextension install [--sys-prefix / --user / --system] --symlink --py myproject jupyter nbextension enable [--sys-prefix / --user / --system] --py myproject with the `appropriate flag`_. Or, if you are using Jupyterlab:: jupyter labextension install . .. links .. _`appropriate flag`: https://jupyter-notebook.readthedocs.io/en/stable/extending/frontend_extensions.html#installing-and-enabling-extensions hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/docs/source/index.rst0000644000000000000000000000116413615410400026317 0ustar00 myproject ===================================== Version: |release| A Custom Jupyter Widget Library Quickstart ---------- To get started with myproject, install with pip:: pip install myproject or with conda:: conda install myproject Contents -------- .. toctree:: :maxdepth: 2 :caption: Installation and usage installing introduction .. toctree:: :maxdepth: 1 examples/index .. toctree:: :maxdepth: 2 :caption: Development develop-install .. links .. _`Jupyter widgets`: https://jupyter.org/widgets.html .. _`notebook`: https://jupyter-notebook.readthedocs.io/en/latest/ hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/docs/source/installing.rst0000644000000000000000000000176313615410400027361 0ustar00 .. _installation: Installation ============ The simplest way to install myproject is via pip:: pip install myproject or via conda:: conda install myproject If you installed via pip, and notebook version < 5.3, you will also have to install / configure the front-end extension as well. If you are using classic notebook (as opposed to Jupyterlab), run:: jupyter nbextension install [--sys-prefix / --user / --system] --py myproject jupyter nbextension enable [--sys-prefix / --user / --system] --py myproject with the `appropriate flag`_. If you are using Jupyterlab, install the extension with:: jupyter labextension install myproject If you are installing using conda, these commands should be unnecessary, but If you need to run them the commands should be the same (just make sure you choose the `--sys-prefix` flag). .. links .. _`appropriate flag`: https://jupyter-notebook.readthedocs.io/en/stable/extending/frontend_extensions.html#installing-and-enabling-extensions hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/docs/source/introduction.rst0000644000000000000000000000015513615410400027730 0ustar00============= Introduction ============= .. todo:: add prose explaining project purpose and usage here hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/docs/source/_static/helper.js0000644000000000000000000000017113615410400027716 0ustar00var cache_require = window.require; window.addEventListener('load', function () { window.require = cache_require; }); hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/docs/source/examples/index.rst0000644000000000000000000000060113615410400030130 0ustar00 Examples ======== This section contains several examples generated from Jupyter notebooks. The widgets have been embedded into the page for demonstrative purposes. .. todo:: Add links to notebooks in examples folder similar to the initial one. This is a manual step to ensure only those examples that are suited for inclusion are used. .. toctree:: :glob: * ././@PaxHeader0000000000000000000000000000016300000000000010215 xustar00115 path=hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/docs/source/examples/introduction.nblink hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/docs/source/examples/introduction.n0000644000000000000000000000006513615410400031173 0ustar00{ "path": "../../../examples/introduction.ipynb" } hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/examples/introduction.ipynb0000644000000000000000000000175213615410400027633 0ustar00{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import myproject" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "w = myproject.ExampleWidget()\n", "w" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "assert w.value == \"Hello World\"" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.3" } }, "nbformat": 4, "nbformat_minor": 2 } hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/myproject/__init__.py0000644000000000000000000000351413615410400026354 0ustar00#!/usr/bin/env python # Copyright (c) me. # Distributed under the terms of the Modified BSD License. from ._version import __version__, version_info # noqa from .example import ExampleWidget # noqa def _jupyter_labextension_paths(): """Called by Jupyter Lab Server to detect if it is a valid labextension and to install the widget Returns ======= src: Source directory name to copy files from. Webpack outputs generated files into this directory and Jupyter Lab copies from this directory during widget installation dest: Destination directory name to install widget files to. Jupyter Lab copies from `src` directory into /labextensions/ directory during widget installation """ return [ { "src": "labextension", "dest": "myproject", } ] def _jupyter_nbextension_paths(): """Called by Jupyter Notebook Server to detect if it is a valid nbextension and to install the widget Returns ======= section: The section of the Jupyter Notebook Server to change. Must be 'notebook' for widget extensions src: Source directory name to copy files from. Webpack outputs generated files into this directory and Jupyter Notebook copies from this directory during widget installation dest: Destination directory name to install widget files to. Jupyter Notebook copies from `src` directory into /nbextensions/ directory during widget installation require: Path to importable AMD Javascript module inside the /nbextensions/ directory """ return [ { "section": "notebook", "src": "nbextension", "dest": "myproject", "require": "myproject/extension", } ] hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/myproject/_frontend.py0000644000000000000000000000033313615410400026567 0ustar00#!/usr/bin/env python # Copyright (c) me. # Distributed under the terms of the Modified BSD License. """ Information about the frontend package of the widgets. """ module_name = "myproject" module_version = "^0.1.0" hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/myproject/_version.py0000644000000000000000000000026613615410400026442 0ustar00#!/usr/bin/env python # Copyright (c) me. # Distributed under the terms of the Modified BSD License. version_info = (0, 1, 0, "dev") __version__ = ".".join(map(str, version_info)) hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/myproject/example.py0000644000000000000000000000133313615410400026245 0ustar00#!/usr/bin/env python # Copyright (c) me. # Distributed under the terms of the Modified BSD License. """ TODO: Add module docstring """ from ipywidgets import DOMWidget from traitlets import Unicode from ._frontend import module_name, module_version class ExampleWidget(DOMWidget): """TODO: Add docstring here""" _model_name = Unicode("ExampleModel").tag(sync=True) _model_module = Unicode(module_name).tag(sync=True) _model_module_version = Unicode(module_version).tag(sync=True) _view_name = Unicode("ExampleView").tag(sync=True) _view_module = Unicode(module_name).tag(sync=True) _view_module_version = Unicode(module_version).tag(sync=True) value = Unicode("Hello World").tag(sync=True) hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/myproject/nbextension/extension.js0000644000000000000000000000055613615410400031154 0ustar00// Entry point for the notebook bundle containing custom model definitions. // define(function () { 'use strict'; window['requirejs'].config({ map: { '*': { myproject: 'nbextensions/myproject/index', }, }, }); // Export the required load_ipython_extension function return { load_ipython_extension: function () {}, }; }); hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/myproject/tests/__init__.py0000644000000000000000000000000013615410400027501 0ustar00hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/myproject/tests/conftest.py0000644000000000000000000000253613615410400027607 0ustar00#!/usr/bin/env python # Copyright (c) me. # Distributed under the terms of the Modified BSD License. import pytest from ipykernel.comm import Comm from ipywidgets import Widget class MockComm(Comm): """A mock Comm object. Can be used to inspect calls to Comm's open/send/close methods. """ comm_id = "a-b-c-d" kernel = "Truthy" def __init__(self, *args, **kwargs): self.log_open = [] self.log_send = [] self.log_close = [] super().__init__(*args, **kwargs) def open(self, *args, **kwargs): self.log_open.append((args, kwargs)) def send(self, *args, **kwargs): self.log_send.append((args, kwargs)) def close(self, *args, **kwargs): self.log_close.append((args, kwargs)) _widget_attrs = {} undefined = object() @pytest.fixture def mock_comm(): _widget_attrs["_comm_default"] = getattr(Widget, "_comm_default", undefined) Widget._comm_default = lambda self: MockComm() _widget_attrs["_ipython_display_"] = Widget._ipython_display_ def raise_not_implemented(*args, **kwargs): raise NotImplementedError() Widget._ipython_display_ = raise_not_implemented yield MockComm() for attr, value in _widget_attrs.items(): if value is undefined: delattr(Widget, attr) else: setattr(Widget, attr, value) hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/myproject/tests/test_example.py0000644000000000000000000000035413615410400030450 0ustar00#!/usr/bin/env python # Copyright (c) me. # Distributed under the terms of the Modified BSD License. from ..example import ExampleWidget def test_example_creation_blank(): w = ExampleWidget() assert w.value == "Hello World" ././@PaxHeader0000000000000000000000000000016300000000000010215 xustar00115 path=hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/myproject/tests/test_nbextension_path.py hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/myproject/tests/test_nbextension_pa0000644000000000000000000000066413615410400031406 0ustar00#!/usr/bin/env python # Copyright (c) me. # Distributed under the terms of the Modified BSD License. def test_nbextension_path(): # Check that magic function can be imported from package root: from myproject import _jupyter_nbextension_paths # Ensure that it can be called without incident: path = _jupyter_nbextension_paths() # Some sanity checks: assert len(path) == 1 assert isinstance(path[0], dict) hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/src/extension.ts0000644000000000000000000000115113615410400025375 0ustar00// Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. // Entry point for the notebook bundle containing custom model definitions. // // Setup notebook base URL // // Some static assets may be required by the custom widget javascript. The base // url for the notebook is not known at build time and is therefore computed // dynamically. // eslint-disable-next-line @typescript-eslint/no-non-null-assertion (window as any).__webpack_public_path__ = document.querySelector('body')!.getAttribute('data-base-url') + 'nbextensions/myproject'; export * from './index'; hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/src/index.ts0000644000000000000000000000020613615410400024470 0ustar00// Copyright (c) me // Distributed under the terms of the Modified BSD License. export * from './version'; export * from './widget'; hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/src/plugin.ts0000644000000000000000000000212413615410400024660 0ustar00// Copyright (c) me // Distributed under the terms of the Modified BSD License. import { Application, IPlugin } from '@phosphor/application'; import { Widget } from '@phosphor/widgets'; import { IJupyterWidgetRegistry } from '@jupyter-widgets/base'; import * as widgetExports from './widget'; import { MODULE_NAME, MODULE_VERSION } from './version'; const EXTENSION_ID = 'myproject:plugin'; /** * The example plugin. */ const examplePlugin: IPlugin, void> = { id: EXTENSION_ID, requires: [IJupyterWidgetRegistry], activate: activateWidgetExtension, autoStart: true, } as unknown as IPlugin, void>; // the "as unknown as ..." typecast above is solely to support JupyterLab 1 // and 2 in the same codebase and should be removed when we migrate to Lumino. export default examplePlugin; /** * Activate the widget extension. */ function activateWidgetExtension( app: Application, registry: IJupyterWidgetRegistry, ): void { registry.registerWidget({ name: MODULE_NAME, version: MODULE_VERSION, exports: widgetExports, }); } hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/src/version.ts0000644000000000000000000000106213615410400025047 0ustar00// Copyright (c) me // Distributed under the terms of the Modified BSD License. // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore // eslint-disable-next-line @typescript-eslint/no-var-requires const data = require('../package.json'); /** * The _model_module_version/_view_module_version this package implements. * * The html widget manager assumes that this is the same as the npm package * version number. */ export const MODULE_VERSION = data.version; /* * The current package name. */ export const MODULE_NAME = data.name; hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/src/widget.ts0000644000000000000000000000261613615410400024653 0ustar00// Copyright (c) me // Distributed under the terms of the Modified BSD License. import { DOMWidgetModel, DOMWidgetView, ISerializers, } from '@jupyter-widgets/base'; import { MODULE_NAME, MODULE_VERSION } from './version'; // Import the CSS import '../css/widget.css'; export class ExampleModel extends DOMWidgetModel { defaults() { return { ...super.defaults(), _model_name: ExampleModel.model_name, _model_module: ExampleModel.model_module, _model_module_version: ExampleModel.model_module_version, _view_name: ExampleModel.view_name, _view_module: ExampleModel.view_module, _view_module_version: ExampleModel.view_module_version, value: 'Hello World', }; } static serializers: ISerializers = { ...DOMWidgetModel.serializers, // Add any extra serializers here }; static model_name = 'ExampleModel'; static model_module = MODULE_NAME; static model_module_version = MODULE_VERSION; static view_name = 'ExampleView'; // Set to null if no view static view_module = MODULE_NAME; // Set to null if no view static view_module_version = MODULE_VERSION; } export class ExampleView extends DOMWidgetView { render() { this.el.classList.add('custom-widget'); this.value_changed(); this.model.on('change:value', this.value_changed, this); } value_changed() { this.el.textContent = this.model.get('value'); } } hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/src/__tests__/index.spec.ts0000644000000000000000000000147513615410400027370 0ustar00// Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. // Add any needed widget imports here (or from controls) // import {} from '@jupyter-widgets/base'; import { createTestModel } from './utils'; import { ExampleModel } from '..'; describe('Example', () => { describe('ExampleModel', () => { it('should be createable', () => { const model = createTestModel(ExampleModel); expect(model).toBeInstanceOf(ExampleModel); expect(model.get('value')).toEqual('Hello World'); }); it('should be createable with a value', () => { const state = { value: 'Foo Bar!' }; const model = createTestModel(ExampleModel, state); expect(model).toBeInstanceOf(ExampleModel); expect(model.get('value')).toEqual('Foo Bar!'); }); }); }); hatch_jupyter_builder-0.8.3/tests/data/create_cmdclass/myproject/src/__tests__/utils.ts0000644000000000000000000000545313615410400026470 0ustar00// Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. import * as widgets from '@jupyter-widgets/base'; import * as services from '@jupyterlab/services'; let numComms = 0; export class MockComm implements widgets.IClassicComm { constructor() { this.comm_id = `mock-comm-id-${numComms}`; numComms += 1; } on_close(fn: ((x?: any) => void) | null): void { this._on_close = fn; } on_msg(fn: (x?: any) => void): void { this._on_msg = fn; } _process_msg(msg: services.KernelMessage.ICommMsgMsg): void | Promise { if (this._on_msg) { return this._on_msg(msg); } else { return Promise.resolve(); } } close(): string { if (this._on_close) { this._on_close(); } return 'dummy'; } send(): string { return 'dummy'; } open(): string { return 'dummy'; } comm_id: string; target_name = 'dummy'; _on_msg: ((x?: any) => void) | null = null; _on_close: ((x?: any) => void) | null = null; } export class DummyManager extends widgets.ManagerBase { constructor() { super(); this.el = window.document.createElement('div'); } display_view( msg: services.KernelMessage.IMessage, view: widgets.DOMWidgetView, options: any, ) { // TODO: make this a spy // TODO: return an html element return Promise.resolve(view).then((view) => { this.el.appendChild(view.el); view.on('remove', () => console.log('view removed', view)); return view.el; }); } protected loadClass( className: string, moduleName: string, moduleVersion: string, ): Promise { if (moduleName === '@jupyter-widgets/base') { if ((widgets as any)[className]) { return Promise.resolve((widgets as any)[className]); } else { return Promise.reject(`Cannot find class ${className}`); } } else if (moduleName === 'jupyter-datawidgets') { if (this.testClasses[className]) { return Promise.resolve(this.testClasses[className]); } else { return Promise.reject(`Cannot find class ${className}`); } } else { return Promise.reject(`Cannot find module ${moduleName}`); } } _get_comm_info() { return Promise.resolve({}); } _create_comm() { return Promise.resolve(new MockComm()); } el: HTMLElement; testClasses: { [key: string]: any } = {}; } export interface Constructor { new (attributes?: any, options?: any): T; } export function createTestModel( constructor: Constructor, attributes?: any, ): T { const id = widgets.uuid(); const widget_manager = new DummyManager(); const modelOptions = { widget_manager: widget_manager, model_id: id, }; return new constructor(attributes, modelOptions); } hatch_jupyter_builder-0.8.3/tests/data/npm_builder/pyproject.toml0000644000000000000000000000541513615410400022315 0ustar00[build-system] requires = [ "hatchling>=1.3.1", "jupyterlab~=3.1" ] build-backend = "hatchling.build" [project] name = "myextension" description = "A JupyterLab extension." readme = "README.md" license = { file = "LICENSE" } requires-python = ">=3.7" authors = [ { name = "me", email = "me@me.com" }, ] keywords = [ "Jupyter", "JupyterLab", "JupyterLab3", ] classifiers = [ "Framework :: Jupyter", "Framework :: Jupyter :: JupyterLab", "Framework :: Jupyter :: JupyterLab :: 3", "Framework :: Jupyter :: JupyterLab :: Extensions", "Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", ] dependencies = [] version = "0.1.0" [project.urls] Homepage = "https://github.com/github_username/myextension" [tool.hatch.build] artifacts = [ "myextension/labextension", ] [tool.hatch.build.targets.wheel.shared-data] "myextension/labextension/static" = "share/jupyter/labextensions/myextension/static" "install.json" = "share/jupyter/labextensions/myextension/install.json" "myextension/labextension/package.json" = "share/jupyter/labextensions/myextension/package.json" "myextension/labextension/schemas/myextension" = "share/jupyter/labextensions/myextension/schemas/myextension" [tool.hatch.build.targets.sdist] exclude = [ ".github" ] [tool.hatch.build.hooks.jupyter-builder] dependencies = [ "hatch-jupyter-builder>=0.5.0", ] build-function = "hatch_jupyter_builder.npm_builder" ensured-targets = [ "myextension/labextension/static/style.js", "myextension/labextension/package.json", ] skip-if-exists = [ "myextension/labextension/static/style.js", ] [tool.hatch.build.hooks.jupyter-builder.build-kwargs] build_cmd = "build:prod" npm = [ "jlpm", ] [tool.hatch.build.hooks.jupyter-builder.editable-build-kwargs] build_cmd = "install:extension" source_dir = "src" build_dir = "myextension/labextension" npm = [ "jlpm", ] [tool.tbump] field = [ { name = "channel", default = "" }, { name = "release", default = "" }, ] file = [ { src = "pyproject.toml", version_template = "version = \"{major}.{minor}.{patch}{channel}{release}\"" }, { src = "myextension/_version.py" }, { src = "package.json", version_template = '"version": "{major}.{minor}.{patch}{channel}{release}"' }, ] [tool.tbump.version] current = "0.1.0" regex = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)((?Pa|b|rc|.dev)(?P\\d+))?" [tool.tbump.git] message_template = "Bump to {new_version}" tag_template = "v{new_version}" hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/.eslintignore0000644000000000000000000000005313615410400024457 0ustar00node_modules dist coverage **/*.d.ts tests hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/.eslintrc.js0000644000000000000000000000216113615410400024215 0ustar00module.exports = { // extends: [ // 'eslint:recommended', // 'plugin:@typescript-eslint/eslint-recommended', // 'plugin:@typescript-eslint/recommended', // 'plugin:prettier/recommended' // ], // parser: '@typescript-eslint/parser', // parserOptions: { // project: 'tsconfig.json', // sourceType: 'module' // }, // plugins: ['@typescript-eslint'], // rules: { // '@typescript-eslint/naming-convention': [ // 'error', // { // selector: 'interface', // format: ['PascalCase'], // custom: { // regex: '^I[A-Z]', // match: true // } // } // ], // '@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }], // '@typescript-eslint/no-explicit-any': 'off', // '@typescript-eslint/no-namespace': 'off', // '@typescript-eslint/no-use-before-define': 'off', // '@typescript-eslint/quotes': [ // 'error', // 'single', // { avoidEscape: true, allowTemplateLiterals: false } // ], // curly: ['error', 'all'], // eqeqeq: 'error', // 'prefer-arrow-callback': 'error' // } }; hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/.gitignore0000644000000000000000000000267313615410400023756 0ustar00*.bundle.* lib/ node_modules/ .eslintcache .stylelintcache *.egg-info/ .ipynb_checkpoints *.tsbuildinfo myextension/labextension # Created by https://www.gitignore.io/api/python # Edit at https://www.gitignore.io/?templates=python ### Python ### # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # Mr Developer .mr.developer.cfg .project .pydevproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # End of https://www.gitignore.io/api/python # OSX files .DS_Store hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/.prettierignore0000644000000000000000000000010013615410400025010 0ustar00node_modules **/node_modules **/lib **/package.json myextension hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/.prettierrc0000644000000000000000000000014613615410400024143 0ustar00{ "singleQuote": true, "trailingComma": "none", "arrowParens": "avoid", "endOfLine": "auto" } hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/.stylelintrc0000644000000000000000000000040413615410400024331 0ustar00{ "extends": [ "stylelint-config-recommended", "stylelint-config-standard", "stylelint-prettier/recommended" ], "rules": { "property-no-vendor-prefix": null, "selector-no-vendor-prefix": null, "value-no-vendor-prefix": null } } hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/CHANGELOG.md0000644000000000000000000000012613615410400023566 0ustar00# Changelog hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/LICENSE0000644000000000000000000000274613615410400022774 0ustar00BSD 3-Clause License Copyright (c) 2022, me All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/MANIFEST.in0000644000000000000000000000064213615410400023516 0ustar00include LICENSE include *.md include pyproject.toml include package.json include install.json include ts*.json include yarn.lock graft myextension/labextension # Javascript files graft src graft style graft schema prune **/node_modules prune lib prune binder # Patterns to exclude from any directory global-exclude *~ global-exclude *.pyc global-exclude *.pyo global-exclude .git global-exclude .ipynb_checkpoints hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/README.md0000644000000000000000000000445213615410400023242 0ustar00# myextension [![Github Actions Status](https://github.com/github_username/myextension/workflows/Build/badge.svg)](https://github.com/github_username/myextension/actions/workflows/build.yml) A JupyterLab extension. ## Requirements - JupyterLab >= 3.0 ## Install To install the extension, execute: ```bash pip install myextension ``` ## Uninstall To remove the extension, execute: ```bash pip uninstall myextension ``` ## Contributing ### Development install Note: You will need NodeJS to build the extension package. The `jlpm` command is JupyterLab's pinned version of [yarn](https://yarnpkg.com/) that is installed with JupyterLab. You may use `yarn` or `npm` in lieu of `jlpm` below. ```bash # Clone the repo to your local environment # Change directory to the myextension directory # Install package in development mode pip install -e . # Link your development version of the extension with JupyterLab jupyter labextension develop . --overwrite # Rebuild extension Typescript source after making changes jlpm build ``` You can watch the source directory and run JupyterLab at the same time in different terminals to watch for changes in the extension's source and automatically rebuild the extension. ```bash # Watch the source directory in one terminal, automatically rebuilding when needed jlpm watch # Run JupyterLab in another terminal jupyter lab ``` With the watch command running, every saved change will immediately be built locally and available in your running JupyterLab. Refresh JupyterLab to load the change in your browser (you may need to wait several seconds for the extension to be rebuilt). By default, the `jlpm build` command generates the source maps for this extension to make it easier to debug using the browser dev tools. To also generate source maps for the JupyterLab core extensions, you can run the following command: ```bash jupyter lab build --minimize=False ``` ### Development uninstall ```bash pip uninstall myextension ``` In development mode, you will also need to remove the symlink created by `jupyter labextension develop` command. To find its location, you can run `jupyter labextension list` to figure out where the `labextensions` folder is located. Then you can remove the symlink named `myextension` within that folder. ### Packaging the extension See [RELEASE](RELEASE.md) hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/RELEASE.md0000644000000000000000000000354513615410400023367 0ustar00# Making a new release of myextension The extension can be published to `PyPI` and `npm` manually or using the [Jupyter Releaser](https://github.com/jupyter-server/jupyter_releaser). ## Manual release ### Python package This extension can be distributed as Python packages. All of the Python packaging instructions in the `pyproject.toml` file to wrap your extension in a Python package. Before generating a package, we first need to install `build`. ```bash pip install build twine ``` To create a Python source package (`.tar.gz`) and the binary package (`.whl`) in the `dist/` directory, do: ```bash python -m build ``` > `python setup.py sdist bdist_wheel` is deprecated and will not work for this package. Then to upload the package to PyPI, do: ```bash twine upload dist/* ``` ### NPM package To publish the frontend part of the extension as a NPM package, do: ```bash npm login npm publish --access public ``` ## Automated releases with the Jupyter Releaser The extension repository should already be compatible with the Jupyter Releaser. Check out the [workflow documentation](https://github.com/jupyter-server/jupyter_releaser#typical-workflow) for more information. Here is a summary of the steps to cut a new release: - Fork the [`jupyter-releaser` repo](https://github.com/jupyter-server/jupyter_releaser) - Add `ADMIN_GITHUB_TOKEN`, `PYPI_TOKEN` and `NPM_TOKEN` to the Github Secrets in the fork - Go to the Actions panel - Run the "Draft Changelog" workflow - Merge the Changelog PR - Run the "Draft Release" workflow - Run the "Publish Release" workflow ## Publishing to `conda-forge` If the package is not on conda forge yet, check the documentation to learn how to add it: https://conda-forge.org/docs/maintainer/adding_pkgs.html Otherwise a bot should pick up the new version publish to PyPI, and open a new PR on the feedstock repository automatically. hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/install.json0000644000000000000000000000026713615410400024324 0ustar00{ "packageManager": "python", "packageName": "myextension", "uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package myextension" } hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/package.json0000644000000000000000000000631113615410400024245 0ustar00{ "name": "myextension", "version": "0.1.0", "description": "A JupyterLab extension.", "keywords": [ "jupyter", "jupyterlab", "jupyterlab-extension" ], "homepage": "https://github.com/github_username/myextension", "bugs": { "url": "https://github.com/github_username/myextension/issues" }, "license": "BSD-3-Clause", "author": { "name": "me", "email": "me@me.com" }, "files": [ "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}", "style/**/*.{css,js,eot,gif,html,jpg,json,png,svg,woff2,ttf}", "schema/*.json" ], "main": "lib/index.js", "types": "lib/index.d.ts", "style": "style/index.css", "repository": { "type": "git", "url": "https://github.com/github_username/myextension.git" }, "scripts": { "build": "jlpm build:lib && jlpm build:labextension:dev", "build:prod": "jlpm clean && jlpm build:lib && jlpm build:labextension", "build:labextension": "jupyter labextension build .", "build:labextension:dev": "jupyter labextension build --development True .", "build:lib": "tsc", "clean": "jlpm clean:lib", "clean:lib": "rimraf lib tsconfig.tsbuildinfo", "clean:lintcache": "rimraf .eslintcache .stylelintcache", "clean:labextension": "rimraf myextension/labextension", "clean:all": "jlpm clean:lib && jlpm clean:labextension && jlpm clean:lintcache", "eslint": "jlpm eslint:check --fix", "eslint:check": "eslint . --cache --ext .ts,.tsx", "install:extension": "jlpm build", "lint": "jlpm stylelint && jlpm prettier && jlpm eslint", "lint:check": "jlpm stylelint:check && jlpm prettier:check && jlpm eslint:check", "prettier": "jlpm prettier:base --write --list-different", "prettier:base": "prettier \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md}\"", "prettier:check": "jlpm prettier:base --check", "stylelint": "jlpm stylelint:check --fix", "stylelint:check": "stylelint --cache \"style/**/*.css\"", "watch": "run-p watch:src watch:labextension", "watch:src": "tsc -w", "watch:labextension": "jupyter labextension watch ." }, "dependencies": { "@jupyterlab/application": "^3.1.0", "@jupyterlab/settingregistry": "^3.1.0" }, "devDependencies": { "@jupyterlab/builder": "^3.1.0", "@typescript-eslint/eslint-plugin": "^4.8.1", "@typescript-eslint/parser": "^4.8.1", "eslint": "^7.14.0", "eslint-config-prettier": "^6.15.0", "eslint-plugin-prettier": "^3.1.4", "npm-run-all": "^4.1.5", "prettier": "^2.1.1", "rimraf": "^3.0.2", "stylelint": "^14.3.0", "stylelint-config-prettier": "^9.0.3", "stylelint-config-recommended": "^6.0.0", "stylelint-config-standard": "~24.0.0", "stylelint-prettier": "^2.0.0", "typescript": "~4.1.3" }, "sideEffects": [ "style/*.css", "style/index.js" ], "styleModule": "style/index.js", "publishConfig": { "access": "public" }, "jupyterlab": { "extension": true, "outputDir": "myextension/labextension", "schemaDir": "schema" }, "jupyter-releaser": { "hooks": { "before-build-npm": [ "python -m pip install jupyterlab~=3.1", "jlpm" ], "before-build-python": [ "jlpm clean:all" ] } } } hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/pyproject.toml0000644000000000000000000000110313615410400024665 0ustar00[build-system] requires = ["jupyter_packaging~=0.10,<2", "jupyterlab~=3.1"] build-backend = "jupyter_packaging.build_api" [tool.jupyter-packaging.options] skip-if-exists = ["myextension/labextension/static/style.js"] ensured-targets = ["myextension/labextension/static/style.js", "myextension/labextension/package.json"] [tool.jupyter-packaging.builder] factory = "jupyter_packaging.npm_builder" [tool.jupyter-packaging.build-args] build_cmd = "build:prod" npm = ["jlpm"] [tool.check-manifest] ignore = ["myextension/labextension/**", "yarn.lock", ".*", "package-lock.json"] hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/setup.py0000644000000000000000000000537013615410400023475 0ustar00""" myextension setup """ import json import sys from pathlib import Path import setuptools HERE = Path(__file__).parent.resolve() # Get the package info from package.json pkg_json = json.loads((HERE / "package.json").read_bytes()) # The name of the project name = "myextension" lab_path = HERE / pkg_json["jupyterlab"]["outputDir"] # Representative files that should exist after a successful build ensured_targets = [str(lab_path / "package.json"), str(lab_path / "static/style.js")] labext_name = pkg_json["name"] data_files_spec = [ ("share/jupyter/labextensions/%s" % labext_name, str(lab_path.relative_to(HERE)), "**"), ("share/jupyter/labextensions/%s" % labext_name, ".", "install.json"), ] long_description = (HERE / "README.md").read_text() version = pkg_json["version"].replace("-alpha.", "a").replace("-beta.", "b").replace("-rc.", "rc") setup_args = dict( name=name, version=version, url=pkg_json["homepage"], author=pkg_json["author"]["name"], author_email=pkg_json["author"]["email"], description=pkg_json["description"], license=pkg_json["license"], license_file="LICENSE", long_description=long_description, long_description_content_type="text/markdown", packages=setuptools.find_packages(), install_requires=[], zip_safe=False, include_package_data=True, python_requires=">=3.7", platforms="Linux, Mac OS X, Windows", keywords=["Jupyter", "JupyterLab", "JupyterLab3"], classifiers=[ "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Framework :: Jupyter", "Framework :: Jupyter :: JupyterLab", "Framework :: Jupyter :: JupyterLab :: 3", "Framework :: Jupyter :: JupyterLab :: Extensions", "Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt", ], ) try: from jupyter_packaging import get_data_files, npm_builder, wrap_installers post_develop = npm_builder(build_cmd="install:extension", source_dir="src", build_dir=lab_path) setup_args["cmdclass"] = wrap_installers( post_develop=post_develop, ensured_targets=ensured_targets ) setup_args["data_files"] = get_data_files(data_files_spec) except ImportError as e: import logging logging.basicConfig(format="%(levelname)s: %(message)s") logging.warning("Build tool `jupyter-packaging` is missing. Install it with pip or conda.") if not ("--name" in sys.argv or "--version" in sys.argv): raise e if __name__ == "__main__": setuptools.setup(**setup_args) hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/tsconfig.json0000644000000000000000000000105213615410400024463 0ustar00{ "compilerOptions": { "allowSyntheticDefaultImports": true, "composite": true, "declaration": true, "esModuleInterop": true, "incremental": true, "jsx": "react", "module": "esnext", "moduleResolution": "node", "noEmitOnError": true, "noImplicitAny": true, "noUnusedLocals": true, "preserveWatchOutput": true, "resolveJsonModule": true, "outDir": "lib", "rootDir": "src", "strict": true, "strictNullChecks": true, "target": "es2018", "types": [] }, "include": ["src/*"] } hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/.github/workflows/build.yml0000644000000000000000000000340513615410400027177 0ustar00name: Build on: push: branches: main pull_request: branches: '*' jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Base Setup uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Install dependencies run: python -m pip install -U jupyterlab~=3.1 check-manifest - name: Build the extension run: | set -eux jlpm jlpm lint:check python -m pip install . jupyter labextension list 2>&1 | grep -ie "myextension.*OK" python -m jupyterlab.browser_check check-manifest -v pip install build python -m build --sdist cp dist/*.tar.gz myextension.tar.gz pip uninstall -y "myextension" jupyterlab rm -rf myextension - uses: actions/upload-artifact@v2 with: name: myextension-sdist path: myextension.tar.gz test_isolated: needs: build runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Install Python uses: actions/setup-python@v2 with: python-version: '3.8' architecture: 'x64' - uses: actions/download-artifact@v2 with: name: myextension-sdist - name: Install and Test run: | set -eux # Remove NodeJS, twice to take care of system and locally installed node versions. sudo rm -rf $(which node) sudo rm -rf $(which node) pip install myextension.tar.gz pip install jupyterlab jupyter labextension list 2>&1 | grep -ie "myextension.*OK" python -m jupyterlab.browser_check --no-chrome-test hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/.github/workflows/check-release.yml0000644000000000000000000000330613615410400030573 0ustar00name: Check Release on: push: branches: - main pull_request: branches: - main permissions: contents: write jobs: check_release: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Install Python uses: actions/setup-python@v2 with: python-version: 3.9 architecture: 'x64' - name: Install node uses: actions/setup-node@v2 with: node-version: '14.x' - name: Get pip cache dir id: pip-cache run: | echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip uses: actions/cache@v1 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('package.json') }} restore-keys: | ${{ runner.os }}-pip- - name: Cache checked links uses: actions/cache@v2 with: path: ~/.cache/pytest-link-check key: ${{ runner.os }}-linkcheck-${{ hashFiles('**/.md') }}-md-links restore-keys: | ${{ runner.os }}-linkcheck- - name: Upgrade packaging dependencies run: | pip install --upgrade pip setuptools wheel jupyter-packaging~=0.10 --user - name: Install Dependencies run: | pip install . - name: Check Release uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v1 with: token: ${{ secrets.GITHUB_TOKEN }} - name: Upload Distributions uses: actions/upload-artifact@v2 with: name: myextension-releaser-dist-${{ github.run_number }} path: .jupyter_releaser_checkout/dist hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/myextension/__init__.py0000644000000000000000000000046113615410400026452 0ustar00import json from pathlib import Path from ._version import __version__ # noqa HERE = Path(__file__).parent.resolve() with (HERE / "labextension" / "package.json").open() as fid: data = json.load(fid) def _jupyter_labextension_paths(): return [{"src": "labextension", "dest": data["name"]}] hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/myextension/_version.py0000644000000000000000000000104213615410400026533 0ustar00import json from pathlib import Path __all__ = ["__version__"] def _fetch_version(): HERE = Path(__file__).parent.resolve() for settings in HERE.rglob("package.json"): try: with settings.open() as f: version = json.load(f)["version"] return version.replace("-alpha.", "a").replace("-beta.", "b").replace("-rc.", "rc") except FileNotFoundError: pass raise FileNotFoundError(f"Could not find package.json under dir {HERE!s}") __version__ = _fetch_version() hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/schema/plugin.json0000644000000000000000000000025713615410400025413 0ustar00{ "jupyter.lab.shortcuts": [], "title": "myextension", "description": "myextension settings.", "type": "object", "properties": {}, "additionalProperties": false } hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/src/index.ts0000644000000000000000000000151213615410400024223 0ustar00import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application'; import { ISettingRegistry } from '@jupyterlab/settingregistry'; /** * Initialization data for the myextension extension. */ const plugin: JupyterFrontEndPlugin = { id: 'myextension:plugin', autoStart: true, optional: [ISettingRegistry], activate: ( app: JupyterFrontEnd, settingRegistry: ISettingRegistry | null ) => { console.log('JupyterLab extension myextension is activated!'); if (settingRegistry) { settingRegistry .load(plugin.id) .then(settings => { console.log('myextension settings loaded:', settings.composite); }) .catch(reason => { console.error('Failed to load settings for myextension.', reason); }); } } }; export default plugin; hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/style/base.css0000644000000000000000000000021213615410400024535 0ustar00/* See the JupyterLab Developer Guide for useful CSS Patterns: https://jupyterlab.readthedocs.io/en/stable/developer/css.html */ hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/style/index.css0000644000000000000000000000003113615410400024731 0ustar00@import url('base.css'); hatch_jupyter_builder-0.8.3/tests/data/npm_builder/myextension/style/index.js0000644000000000000000000000002713615410400024562 0ustar00//import './base.css'; hatch_jupyter_builder-0.8.3/.gitignore0000644000000000000000000000066513615410400015020 0ustar00MANIFEST build dist _build docs/man/*.gz docs/source/api/generated docs/source/config.rst docs/gh-pages node_modules *.py[co] __pycache__ *.egg-info *~ *.bak .ipynb_checkpoints .tox .DS_Store \#*# .#* .coverage* .pytest_cache *.swp *.map Read the Docs config.rst docs/source/reference/changelog.md /.project /.pydevproject # jetbrains ide stuff *.iml .idea/ # vscode ide stuff *.code-workspace .history .vscode/* !.vscode/*.template hatch_jupyter_builder-0.8.3/LICENSE.txt0000644000000000000000000000275113615410400014651 0ustar00Copyright (c) 2022 Project Jupyter Contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. hatch_jupyter_builder-0.8.3/README.md0000644000000000000000000000435213615410400014304 0ustar00# hatch-jupyter-builder [![PyPI - Version](https://img.shields.io/pypi/v/hatch-jupyter-builder.svg)](https://pypi.org/project/hatch-jupyter-builder) [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch) ______________________________________________________________________ This provides a [build hook](https://hatch.pypa.io/latest/config/build/#build-hooks) plugin for [Hatch](https://github.com/pypa/hatch) that adds a build step for use with Jupyter packages. **Table of Contents** - [Documentation](#documentation) - [Installation](#installation) - [License](#license) - [Usage and Configuration](#usage_and_configuration) - [Local Development](#local_development) ## Documentation The full documenation is available on [Read The Docs](https://hatch-jupyter-builder.readthedocs.io/en/latest/). ## Installation ```console pip install hatch-jupyter-builder ``` ## Local Development To test this package locally with another package, use the following: ```toml [tool.hatch.build.hooks.jupyter-builder] dependencies = ["hatch-jupyter-builder@file://"] ``` ## Skipping the Build You can skip the build by setting the `SKIP_JUPYTER_BUILDER` environment variable. ## Migration This library can be used to migrate from a `setuptools` based package to use `hatch_jupyter_builder`. It will attempt to migrate `jupyter-packaging` config as well, if present. To migrate, run the following: ```bash python -m hatch_jupyter_builder.migrate . ``` The migration script will do most of the migration automatically, but will prompt you for anything it cannot do itself. To compare dist files with a reference checkout, run the following: ```bash python -m hatch_jupyter_builder.compare_migration sdist ``` The migration scripts can also be used without installation, using `pipx`, e.g.: ```bash pipx hatch_jupyter_builder migrate . ``` Use `wheel` to compare wheel file contents. See the [documentation for more information on migration](https://hatch-jupyter-builder.readthedocs.io/en/latest/source/how_to_guides/index.html) for more details. ## License `hatch-jupyter-builder` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license. hatch_jupyter_builder-0.8.3/pyproject.toml0000644000000000000000000001277513615410400015751 0ustar00[build-system] requires = ["hatchling>=1.5"] build-backend = "hatchling.build" [project] name = "hatch-jupyter-builder" dynamic = ["version"] description = 'A hatch plugin to help build Jupyter packages' readme = "README.md" requires-python = ">=3.8" license = { file = "LICENSE.txt" } keywords = ["jupyter", "jupyterlab", "hatch"] authors = [ { name = "Jupyter Development Team", email = "jupyter@googlegroups.com" }, ] classifiers = [ "Development Status :: 4 - Beta", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", ] dependencies = ["hatchling>=1.5"] [project.urls] Documentation = "https://github.com/jupyterlab/hatch-jupyter-builder#readme" Issues = "https://github.com/jupyterlab/hatch-jupyter-builder/issues" Source = "https://github.com/jupyterlab/hatch-jupyter-builder" [project.optional-dependencies] test = ["pytest", "pytest-mock", "hatch", "pytest-cov", "tomli", "twine"] docs = ["pydata-sphinx-theme", "myst-parser", "hatch_jupyter_builder", "sphinxcontrib-spelling", "sphinx-autodoc-typehints"] [project.scripts] hatch-jupyter-builder = 'hatch_jupyter_builder.cli:run' [project.entry-points.hatch] jupyter = "hatch_jupyter_builder.hooks" [tool.hatch.version] path = "hatch_jupyter_builder/__init__.py" [tool.hatch.envs.docs] features = ["docs"] [tool.hatch.envs.docs.env-vars] SPHINXOPTS = "-W" [tool.hatch.envs.docs.scripts] build = "make -C docs html" api = "sphinx-apidoc -o docs/source/reference/api -f -E hatch_jupyter_builder hatch_jupyter_builder/migrate/jupyter_packaging.py" [tool.hatch.envs.test] features = ["test"] [tool.hatch.envs.test.scripts] test = "python -m pytest -vv {args}" nowarn = "python -m pytest -vv -W default {args}" [tool.hatch.envs.cov] features = ["test"] dependencies = ["coverage", "pytest-cov"] [tool.hatch.envs.cov.scripts] test = "python -m pytest -vv --cov hatch_jupyter_builder --cov-branch --cov-report term-missing:skip-covered {args}" [tool.hatch.envs.migration] features = ["test"] dependencies = ["pytest-xdist[psutil]"] [tool.hatch.envs.migration.scripts] test = "python -m pytest -n auto -vv --migration-tests True" [tool.hatch.envs.typing] features = ["test"] dependencies = ["mypy>=0.990"] [tool.hatch.envs.typing.scripts] test = "mypy --install-types --non-interactive {args:hatch_jupyter_builder/**/*.py tests/*.py}" [tool.hatch.envs.lint] dependencies = [ "black[jupyter]==23.3.0", "mdformat>0.7", "ruff==0.0.260", ] [tool.hatch.envs.lint.scripts] style = [ "ruff {args:.}", "black --check --diff {args:.}", "mdformat --check {args:docs/source *.md}" ] fmt = [ "black {args:.}", "ruff --fix {args:.}", "mdformat {args:docs/source *.md}" ] [tool.pytest.ini_options] addopts = "-raXs --durations 10 --color=yes --doctest-modules" testpaths = [ "tests/" ] norecursedirs = "tests/data/*" filterwarnings = [ "error" ] [tool.coverage.run] omit = [ "hatch_jupyter_builder/cli.py", "hatch_jupyter_builder/migrate/*", "hatch_jupyter_builder/compare_migrated/*" ] relative_files = true source = ["hatch_jupyter_builder"] [tool.mypy] check_untyped_defs = true disallow_incomplete_defs = true no_implicit_optional = true pretty = true show_error_context = true show_error_codes = true strict_equality = true warn_unused_configs = true warn_unused_ignores = true warn_redundant_casts = true exclude = ["tests/data/**/*.*"] [tool.black] line-length = 100 target-version = ["py38"] [tool.ruff] target-version = "py38" line-length = 100 select = [ "A", "B", "C", "DTZ", "E", "EM", "F", "FBT", "I", "ICN", "ISC", "N", "PLC", "PLE", "PLR", "PLW", "Q", "RUF", "S", "SIM", "T", "TID", "UP", "W", "YTT", ] ignore = [ # Allow non-abstract empty methods in abstract base classes "B027", # Ignore McCabe complexity "C901", # Allow boolean positional values in function calls, like `dict.get(... True)` "FBT003", # Use of `assert` detected "S101", # Line too long "E501", # Relative imports are banned "TID252", # Boolean ... in function definition "FBT001", "FBT002", # Module level import not at top of file "E402", # A001/A002/A003 .. is shadowing a python builtin "A001", "A002", "A003", # Possible hardcoded password "S105", "S106", # Variable `xxx` in function should be lowercase "N806", # Exception name `KernelSessionRecordConflict` should be named with an Error suffix "N818", # SIM105 Use `contextlib.suppress(...)` "SIM105", # PLR0913 Too many arguments to function call "PLR0913", # PLR0912 Too many branches "PLR0912", ] unfixable = [ # Don't touch print statements "T201", # Don't touch unused imports "F401", # Don't touch noqa lines "RUF100", ] [tool.ruff.per-file-ignores] # B011 Do not call assert False since python -O removes these calls # F841 local variable 'foo' is assigned to but never used # C408 Unnecessary `dict` call # E402 Module level import not at top of file # T201 `print` found # EM101 Exception must not use a string literal # PLR2004 Magic value used in comparison "tests/*" = ["B011", "F841", "C408", "E402", "T201", "EM101", "EM102", "EM103", "PLR2004"] [tool.interrogate] ignore-init-module=true ignore-private=true ignore-semiprivate=true ignore-property-decorators=true ignore-nested-functions=true ignore-nested-classes=true fail-under=100 exclude = ["docs", "tests"] hatch_jupyter_builder-0.8.3/PKG-INFO0000644000000000000000000001276113615410400014125 0ustar00Metadata-Version: 2.1 Name: hatch-jupyter-builder Version: 0.8.3 Summary: A hatch plugin to help build Jupyter packages Project-URL: Documentation, https://github.com/jupyterlab/hatch-jupyter-builder#readme Project-URL: Issues, https://github.com/jupyterlab/hatch-jupyter-builder/issues Project-URL: Source, https://github.com/jupyterlab/hatch-jupyter-builder Author-email: Jupyter Development Team License: Copyright (c) 2022 Project Jupyter Contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. License-File: LICENSE.txt Keywords: hatch,jupyter,jupyterlab Classifier: Development Status :: 4 - Beta Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Requires-Python: >=3.8 Requires-Dist: hatchling>=1.5 Provides-Extra: docs Requires-Dist: hatch-jupyter-builder; extra == 'docs' Requires-Dist: myst-parser; extra == 'docs' Requires-Dist: pydata-sphinx-theme; extra == 'docs' Requires-Dist: sphinx-autodoc-typehints; extra == 'docs' Requires-Dist: sphinxcontrib-spelling; extra == 'docs' Provides-Extra: test Requires-Dist: hatch; extra == 'test' Requires-Dist: pytest; extra == 'test' Requires-Dist: pytest-cov; extra == 'test' Requires-Dist: pytest-mock; extra == 'test' Requires-Dist: tomli; extra == 'test' Requires-Dist: twine; extra == 'test' Description-Content-Type: text/markdown # hatch-jupyter-builder [![PyPI - Version](https://img.shields.io/pypi/v/hatch-jupyter-builder.svg)](https://pypi.org/project/hatch-jupyter-builder) [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch) ______________________________________________________________________ This provides a [build hook](https://hatch.pypa.io/latest/config/build/#build-hooks) plugin for [Hatch](https://github.com/pypa/hatch) that adds a build step for use with Jupyter packages. **Table of Contents** - [Documentation](#documentation) - [Installation](#installation) - [License](#license) - [Usage and Configuration](#usage_and_configuration) - [Local Development](#local_development) ## Documentation The full documenation is available on [Read The Docs](https://hatch-jupyter-builder.readthedocs.io/en/latest/). ## Installation ```console pip install hatch-jupyter-builder ``` ## Local Development To test this package locally with another package, use the following: ```toml [tool.hatch.build.hooks.jupyter-builder] dependencies = ["hatch-jupyter-builder@file://"] ``` ## Skipping the Build You can skip the build by setting the `SKIP_JUPYTER_BUILDER` environment variable. ## Migration This library can be used to migrate from a `setuptools` based package to use `hatch_jupyter_builder`. It will attempt to migrate `jupyter-packaging` config as well, if present. To migrate, run the following: ```bash python -m hatch_jupyter_builder.migrate . ``` The migration script will do most of the migration automatically, but will prompt you for anything it cannot do itself. To compare dist files with a reference checkout, run the following: ```bash python -m hatch_jupyter_builder.compare_migration sdist ``` The migration scripts can also be used without installation, using `pipx`, e.g.: ```bash pipx hatch_jupyter_builder migrate . ``` Use `wheel` to compare wheel file contents. See the [documentation for more information on migration](https://hatch-jupyter-builder.readthedocs.io/en/latest/source/how_to_guides/index.html) for more details. ## License `hatch-jupyter-builder` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.