hatch_nodejs_version-0.3.2/.flake80000644000000000000000000000006313615410400014004 0ustar00[flake8] max-line-length = 88 extend-ignore = E203 hatch_nodejs_version-0.3.2/.pre-commit-config.yaml0000644000000000000000000000070513615410400017115 0ustar00repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.3.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/psf/black rev: 22.8.0 hooks: - id: black - repo: https://github.com/pycqa/isort rev: 5.10.1 hooks: - id: isort name: isort - repo: https://github.com/pycqa/flake8 rev: 5.0.4 hooks: - id: flake8 hatch_nodejs_version-0.3.2/CHANGELOG.md0000644000000000000000000000231213615410400014441 0ustar00# Changelog ## 0.3.2 ([Full Changelog](https://github.com/agoose77/hatch-nodejs-version/compare/v0.3.0...4d3c73d2f4e5ac927274dc810351bc0be95ef224)) ### Bugs fixed - Add a trailing newline to package.json when appropriate [#17](https://github.com/agoose77/hatch-nodejs-version/pull/17) ([@blink1073](https://github.com/blink1073)) ### Other merged PRs - Assume NPM person can be string [#20](https://github.com/agoose77/hatch-nodejs-version/pull/20) ([@vikramaditya91](https://github.com/vikramaditya91)) ### Contributors to this release ([GitHub contributors page for this release](https://github.com/agoose77/hatch-nodejs-version/graphs/contributors?from=2022-09-21&to=2023-09-06&type=c)) [@agoose77](https://github.com/search?q=repo%3Aagoose77%2Fhatch-nodejs-version+involves%3Aagoose77+updated%3A2022-09-21..2023-09-06&type=Issues) | [@blink1073](https://github.com/search?q=repo%3Aagoose77%2Fhatch-nodejs-version+involves%3Ablink1073+updated%3A2022-09-21..2023-09-06&type=Issues) | [@vikramaditya91](https://github.com/search?q=repo%3Aagoose77%2Fhatch-nodejs-version+involves%3Avikramaditya91+updated%3A2022-09-21..2023-09-06&type=Issues) hatch_nodejs_version-0.3.2/RELEASE.md0000644000000000000000000000411313615410400014233 0ustar00# Making a new release of jupyterlab_myst 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 are in the `pyproject.toml` file to wrap your extension in a Python package. Before generating a package, you first need to install some tools: ```bash pip install build twine hatch ``` Bump the version using `hatch`. By default this will create a tag. See the docs on [hatch-nodejs-version](https://github.com/agoose77/hatch-nodejs-version#semver) for details. ```bash hatch version ``` 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://jupyter-releaser.readthedocs.io/en/latest/get_started/making_release_from_repo.html) for more information. Here is a summary of the steps to cut a new release: - Add `ADMIN_GITHUB_TOKEN`, `PYPI_TOKEN` and `NPM_TOKEN` to the [Github Secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) in the repository - Go to the Actions panel - Run the "Step 1: Prep Release" workflow - Check the draft changelog - Run the "Step 2: 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_nodejs_version-0.3.2/pdm.lock0000644000000000000000000002370013615410400014266 0ustar00[[package]] name = "attrs" version = "22.1.0" requires_python = ">=3.5" summary = "Classes Without Boilerplate" [[package]] name = "colorama" version = "0.4.5" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" summary = "Cross-platform colored terminal text." [[package]] name = "editables" version = "0.3" requires_python = ">=3.7" summary = "Editable installations" [[package]] name = "hatchling" version = "1.8.1" requires_python = ">=3.7" summary = "Modern, extensible Python build backend" dependencies = [ "editables>=0.3", "importlib-metadata; python_version < \"3.8\"", "packaging>=21.3", "pathspec>=0.9", "pluggy>=1.0.0", "tomli>=1.2.2; python_version < \"3.11\"", ] [[package]] name = "importlib-metadata" version = "4.12.0" requires_python = ">=3.7" summary = "Read metadata from Python packages" dependencies = [ "typing-extensions>=3.6.4; python_version < \"3.8\"", "zipp>=0.5", ] [[package]] name = "iniconfig" version = "1.1.1" summary = "iniconfig: brain-dead simple config-ini parsing" [[package]] name = "packaging" version = "21.3" requires_python = ">=3.6" summary = "Core utilities for Python packages" dependencies = [ "pyparsing!=3.0.5,>=2.0.2", ] [[package]] name = "pathspec" version = "0.10.1" requires_python = ">=3.7" summary = "Utility library for gitignore style pattern matching of file paths." [[package]] name = "pluggy" version = "1.0.0" requires_python = ">=3.6" summary = "plugin and hook calling mechanisms for python" dependencies = [ "importlib-metadata>=0.12; python_version < \"3.8\"", ] [[package]] name = "py" version = "1.11.0" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" summary = "library with cross-python path, ini-parsing, io, code, log facilities" [[package]] name = "pyparsing" version = "3.0.9" requires_python = ">=3.6.8" summary = "pyparsing module - Classes and methods to define and execute parsing grammars" [[package]] name = "pytest" version = "7.1.3" requires_python = ">=3.7" summary = "pytest: simple powerful testing with Python" dependencies = [ "attrs>=19.2.0", "colorama; sys_platform == \"win32\"", "importlib-metadata>=0.12; python_version < \"3.8\"", "iniconfig", "packaging", "pluggy<2.0,>=0.12", "py>=1.8.2", "tomli>=1.0.0", ] [[package]] name = "tomli" version = "2.0.1" requires_python = ">=3.7" summary = "A lil' TOML parser" [[package]] name = "typing-extensions" version = "4.3.0" requires_python = ">=3.7" summary = "Backported and Experimental Type Hints for Python 3.7+" [[package]] name = "zipp" version = "3.8.1" requires_python = ">=3.7" summary = "Backport of pathlib-compatible object wrapper for zip files" [metadata] lock_version = "4.0" content_hash = "sha256:ff25367f17ca5a15ea993d1f5f73674ebe29ec849e75e2206fd866a604e705c5" [metadata.files] "attrs 22.1.0" = [ {url = "https://files.pythonhosted.org/packages/1a/cb/c4ffeb41e7137b23755a45e1bfec9cbb76ecf51874c6f1d113984ecaa32c/attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, {url = "https://files.pythonhosted.org/packages/f2/bc/d817287d1aa01878af07c19505fafd1165cd6a119e9d0821ca1d1c20312d/attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, ] "colorama 0.4.5" = [ {url = "https://files.pythonhosted.org/packages/2b/65/24d033a9325ce42ccbfa3ca2d0866c7e89cc68e5b9d92ecaba9feef631df/colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, {url = "https://files.pythonhosted.org/packages/77/8b/7550e87b2d308a1b711725dfaddc19c695f8c5fa413c640b2be01662f4e6/colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, ] "editables 0.3" = [ {url = "https://files.pythonhosted.org/packages/01/b0/a2a87db4b6cb8e7d57004b6836faa634e0747e3e39ded126cdbe5a33ba36/editables-0.3.tar.gz", hash = "sha256:167524e377358ed1f1374e61c268f0d7a4bf7dbd046c656f7b410cde16161b1a"}, {url = "https://files.pythonhosted.org/packages/ef/8c/87276afb1ba3193c4c05be83965a1e69b8a14821ce6d688464071b179383/editables-0.3-py3-none-any.whl", hash = "sha256:ee686a8db9f5d91da39849f175ffeef094dd0e9c36d6a59a2e8c7f92a3b80020"}, ] "hatchling 1.8.1" = [ {url = "https://files.pythonhosted.org/packages/19/93/bd81c789331a317351b2887a508843804de1414d9455a37bce78f6722c25/hatchling-1.8.1-py3-none-any.whl", hash = "sha256:09171ed1404e636ef572b370d34c5cb36a8029825c0a7859ac93989080ba2630"}, {url = "https://files.pythonhosted.org/packages/a1/e0/e22e343e7e5853b1d10c5f6fb5072ca3d38aa05e51c9920bb373d393e40c/hatchling-1.8.1.tar.gz", hash = "sha256:448b04b23faed669b2b565b998ac955af4feea66c5deed3a1212ac9399d2e1cd"}, ] "importlib-metadata 4.12.0" = [ {url = "https://files.pythonhosted.org/packages/1a/16/441080c907df829016729e71d8bdd42d99b9bdde48b01492ed08912c0aa9/importlib_metadata-4.12.0.tar.gz", hash = "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670"}, {url = "https://files.pythonhosted.org/packages/d2/a2/8c239dc898138f208dd14b441b196e7b3032b94d3137d9d8453e186967fc/importlib_metadata-4.12.0-py3-none-any.whl", hash = "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23"}, ] "iniconfig 1.1.1" = [ {url = "https://files.pythonhosted.org/packages/23/a2/97899f6bd0e873fed3a7e67ae8d3a08b21799430fb4da15cfedf10d6e2c2/iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, {url = "https://files.pythonhosted.org/packages/9b/dd/b3c12c6d707058fa947864b67f0c4e0c39ef8610988d7baea9578f3c48f3/iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, ] "packaging 21.3" = [ {url = "https://files.pythonhosted.org/packages/05/8e/8de486cbd03baba4deef4142bd643a3e7bbe954a784dc1bb17142572d127/packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, {url = "https://files.pythonhosted.org/packages/df/9e/d1a7217f69310c1db8fdf8ab396229f55a699ce34a203691794c5d1cad0c/packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] "pathspec 0.10.1" = [ {url = "https://files.pythonhosted.org/packages/24/9f/a9ae1e6efa11992dba2c4727d94602bd2f6ee5f0dedc29ee2d5d572c20f7/pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"}, {url = "https://files.pythonhosted.org/packages/63/82/2179fdc39bc1bb43296f638ae1dfe2581ec2617b4e87c28b0d23d44b997f/pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"}, ] "pluggy 1.0.0" = [ {url = "https://files.pythonhosted.org/packages/9e/01/f38e2ff29715251cf25532b9082a1589ab7e4f571ced434f98d0139336dc/pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {url = "https://files.pythonhosted.org/packages/a1/16/db2d7de3474b6e37cbb9c008965ee63835bba517e22cdb8c35b5116b5ce1/pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] "py 1.11.0" = [ {url = "https://files.pythonhosted.org/packages/98/ff/fec109ceb715d2a6b4c4a85a61af3b40c723a961e8828319fbcb15b868dc/py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, {url = "https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, ] "pyparsing 3.0.9" = [ {url = "https://files.pythonhosted.org/packages/6c/10/a7d0fa5baea8fe7b50f448ab742f26f52b80bfca85ac2be9d35cdd9a3246/pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, {url = "https://files.pythonhosted.org/packages/71/22/207523d16464c40a0310d2d4d8926daffa00ac1f5b1576170a32db749636/pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, ] "pytest 7.1.3" = [ {url = "https://files.pythonhosted.org/packages/a4/a7/8c63a4966935b0d0b039fd67ebf2e1ae00f1af02ceb912d838814d772a9a/pytest-7.1.3.tar.gz", hash = "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39"}, {url = "https://files.pythonhosted.org/packages/e3/b9/3541bbcb412a9fd56593005ff32183825634ef795a1c01ceb6dee86e7259/pytest-7.1.3-py3-none-any.whl", hash = "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7"}, ] "tomli 2.0.1" = [ {url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] "typing-extensions 4.3.0" = [ {url = "https://files.pythonhosted.org/packages/9e/1d/d128169ff58c501059330f1ad96ed62b79114a2eb30b8238af63a2e27f70/typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"}, {url = "https://files.pythonhosted.org/packages/ed/d6/2afc375a8d55b8be879d6b4986d4f69f01115e795e36827fd3a40166028b/typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"}, ] "zipp 3.8.1" = [ {url = "https://files.pythonhosted.org/packages/3b/e3/fb79a1ea5f3a7e9745f688855d3c673f2ef7921639a380ec76f7d4d83a85/zipp-3.8.1.tar.gz", hash = "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2"}, {url = "https://files.pythonhosted.org/packages/f0/36/639d6742bcc3ffdce8b85c31d79fcfae7bb04b95f0e5c4c6f8b206a038cc/zipp-3.8.1-py3-none-any.whl", hash = "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009"}, ] hatch_nodejs_version-0.3.2/.github/workflows/check-release.yml0000644000000000000000000000137113615410400021447 0ustar00name: Check Release on: push: branches: ["main"] pull_request: branches: ["*"] jobs: check_release: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Base Setup uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Install Dependencies run: | pip install -e . - name: Check Release uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v2 with: token: ${{ secrets.GITHUB_TOKEN }} - name: Upload Distributions uses: actions/upload-artifact@v3 with: name: jupyterlab_myst-releaser-dist-${{ github.run_number }} path: .jupyter_releaser_checkout/dist hatch_nodejs_version-0.3.2/.github/workflows/enforce-label.yml0000644000000000000000000000050013615410400021443 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_nodejs_version-0.3.2/.github/workflows/full-release.yml0000644000000000000000000000452113615410400021334 0ustar00name: "Steps 1 + 2: Full 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 steps_to_skip: description: "Comma separated list of steps to skip during Populate Release" required: false jobs: full_release: runs-on: ubuntu-latest permissions: # This is useful if you want to use PyPI trusted publisher # and NPM provenance id-token: write 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 }} branch: ${{ github.event.inputs.branch }} since: ${{ github.event.inputs.since }} since_last_stable: ${{ github.event.inputs.since_last_stable }} - name: Populate Release id: populate-release uses: jupyter-server/jupyter_releaser/.github/actions/populate-release@v2 with: token: ${{ secrets.ADMIN_GITHUB_TOKEN }} branch: ${{ github.event.inputs.branch }} release_url: ${{ steps.prep-release.outputs.release_url }} steps_to_skip: ${{ github.event.inputs.steps_to_skip }} - name: Finalize Release id: finalize-release uses: jupyter-server/jupyter-releaser/.github/actions/finalize-release@v2 with: token: ${{ secrets.ADMIN_GITHUB_TOKEN }} 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 }} hatch_nodejs_version-0.3.2/.github/workflows/prep-release.yml0000644000000000000000000000257313615410400021345 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 }} 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_nodejs_version-0.3.2/.github/workflows/publish-release.yml0000644000000000000000000000322213615410400022035 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 permissions: # This is useful if you want to use PyPI trusted publisher # and NPM provenance id-token: write 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 }} 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 uses: jupyter-server/jupyter-releaser/.github/actions/finalize-release@v2 with: token: ${{ secrets.ADMIN_GITHUB_TOKEN }} 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_nodejs_version-0.3.2/.github/workflows/tests.yml0000644000000000000000000000140313615410400020112 0ustar00name: Tests on: push: branches: ["master"] pull_request: # Run once a day. schedule: - cron: "0 8 * * *" concurrency: group: 'tests-${{ github.head_ref || github.run_id }}' cancel-in-progress: true jobs: build: runs-on: ubuntu-latest strategy: matrix: python-version: ["3.7", "3.8", "3.9", "3.10"] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip pip install -e . pip install pytest - name: Test with pytest run: | pytest hatch_nodejs_version-0.3.2/hatch_nodejs_version/__init__.py0000644000000000000000000000021613615410400021140 0ustar00# SPDX-FileCopyrightText: 2022-present Angus Hollands # # SPDX-License-Identifier: MIT from ._version import __version__ hatch_nodejs_version-0.3.2/hatch_nodejs_version/_version.py0000644000000000000000000000020213615410400021220 0ustar00# SPDX-FileCopyrightText: 2022-present Angus Hollands # # SPDX-License-Identifier: MIT __version__ = "0.3.2" hatch_nodejs_version-0.3.2/hatch_nodejs_version/hooks.py0000644000000000000000000000062113615410400020524 0ustar00# SPDX-FileCopyrightText: 2022-present Angus Hollands # # SPDX-License-Identifier: MIT from hatchling.plugin import hookimpl from .version_source import NodeJSVersionSource from .metadata_source import NodeJSMetadataHook @hookimpl def hatch_register_version_source(): return NodeJSVersionSource @hookimpl def hatch_register_metadata_hook(): return NodeJSMetadataHook hatch_nodejs_version-0.3.2/hatch_nodejs_version/metadata_source.py0000644000000000000000000001715413615410400022552 0ustar00# SPDX-FileCopyrightText: 2022-present Angus Hollands # # SPDX-License-Identifier: MIT from __future__ import annotations import json import os.path import re import urllib.parse from typing import Any, Union from hatchling.metadata.plugin.interface import MetadataHookInterface AUTHOR_PATTERN = r"^(?P[^<(]+?)?[ \t]*(?:<(?P[^>(]+?)>)?[ \t]*(?:\((?P[^)]+?)\)|$)" REPOSITORY_PATTERN = r"^(?:(gist|bitbucket|gitlab|github):)?(.*?)$" REPOSITORY_TABLE = { "gitlab": "https://gitlab.com", "github": "https://github.com", "gist": "https://gist.github.com", "bitbucket": "https://bitbucket.org", } class NodeJSMetadataHook(MetadataHookInterface): PLUGIN_NAME = "nodejs" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.__path = None self.__fields = None self.__contributors_as_maintainers = None self.__homepage_label = None self.__bugs_label = None self.__repository_label = None @property def path(self) -> str: if self.__path is None: version_file = self.config.get("path", "package.json") if not isinstance(version_file, str): raise TypeError( "Option `path` for metadata hook `{}` must be a string".format( self.PLUGIN_NAME ) ) self.__path = version_file return self.__path @property def fields(self) -> None | set[str]: if self.__fields is None: fields = self.config.get("fields", None) if fields is None: self.__fields = None else: if not ( isinstance(fields, list) and all(isinstance(f, str) for f in fields) ): raise TypeError( "Option `fields` for metadata hook `{}` " "must be a list of strings".format(self.PLUGIN_NAME) ) self.__fields = set(fields) return self.__fields @property def contributors_as_maintainers(self) -> bool: if self.__contributors_as_maintainers is None: contributors_as_maintainers = self.config.get( "contributors-as-maintainers", True ) if not isinstance(contributors_as_maintainers, bool): raise TypeError( "Option `contributors-as-maintainers` for metadata hook `{}` " "must be a boolean".format(self.PLUGIN_NAME) ) self.__contributors_as_maintainers = contributors_as_maintainers return self.__contributors_as_maintainers @property def homepage_label(self) -> bool: if self.__homepage_label is None: homepage_label = self.config.get("homepage-label", "Homepage") if not isinstance(homepage_label, str): raise TypeError( "Option `homepage-label` for metadata hook `{}` " "must be a string".format(self.PLUGIN_NAME) ) self.__homepage_label = homepage_label return self.__homepage_label @property def bugs_label(self) -> bool: if self.__bugs_label is None: bug_tracker_label = self.config.get("bugs-label", "Bug Tracker") if not isinstance(bug_tracker_label, str): raise TypeError( "Option `bugs-label` for metadata hook `{}` " "must be a string".format(self.PLUGIN_NAME) ) self.__bugs_label = bug_tracker_label return self.__bugs_label @property def repository_label(self) -> bool: if self.__repository_label is None: bug_tracker_label = self.config.get("repository-label", "Repository") if not isinstance(bug_tracker_label, str): raise TypeError( "Option `repository-label` for metadata hook `{}` " "must be a string".format(self.PLUGIN_NAME) ) self.__repository_label = bug_tracker_label return self.__repository_label def load_package_data(self): path = os.path.normpath(os.path.join(self.root, self.path)) if not os.path.isfile(path): raise OSError(f"file does not exist: {self.path}") with open(path, "r", encoding="utf-8") as f: return json.load(f) def _parse_bugs(self, bugs: str | dict[str, str]) -> str | None: if isinstance(bugs, str): return bugs if "url" not in bugs: return None return bugs["url"] def _parse_person(self, person: dict[str, str]) -> dict[str, str]: result = {} if isinstance(person, dict): if {"url", "email"} & person.keys(): result["name"] = person["name"] if "email" in person: result["email"] = person["email"] return result else: author = person["name"] else: author = person match = re.match(AUTHOR_PATTERN, author) if match is None: raise ValueError(f"Invalid author name: {author}") name, email, _ = match.groups() result = {"name": name} if email is not None: result["email"] = email return result def _parse_repository(self, repository: str | dict[str, str]) -> str: if isinstance(repository, str): match = re.match(REPOSITORY_PATTERN, repository) if match is None: raise ValueError(f"Invalid repository string: {repository}") kind, identifier = match.groups() if kind is None: kind = "github" return urllib.parse.urljoin(REPOSITORY_TABLE[kind], identifier) return repository["url"] def update(self, metadata: dict[str, Any]): package = self.load_package_data() new_metadata = {"name": package["name"]} authors = None maintainers = None if "author" in package: authors = [self._parse_person(package["author"])] if "contributors" in package: contributors = [self._parse_person(p) for p in package["contributors"]] if self.contributors_as_maintainers: maintainers = contributors else: authors = [*(authors or []), *contributors] if authors is not None: new_metadata["authors"] = authors if maintainers is not None: new_metadata["maintainers"] = maintainers if "keywords" in package: new_metadata["keywords"] = package["keywords"] if "description" in package: new_metadata["description"] = package["description"] if "license" in package: new_metadata["license"] = package["license"] # Construct URLs urls = {} if "homepage" in package: urls[self.homepage_label] = package["homepage"] if "bugs" in package: bugs_url = self._parse_bugs(package["bugs"]) if bugs_url is not None: urls[self.bugs_label] = bugs_url if "repository" in package: urls[self.repository_label] = self._parse_repository(package["repository"]) # Write URLs if urls: new_metadata["urls"] = urls # Only use required metadata metadata.update( { k: v for k, v in new_metadata.items() if (self.fields is None or k in self.fields) } ) hatch_nodejs_version-0.3.2/hatch_nodejs_version/version_source.py0000644000000000000000000001277613615410400022464 0ustar00# SPDX-FileCopyrightText: 2022-present Angus Hollands # # SPDX-License-Identifier: MIT import json import os import re from hatchling.version.source.plugin.interface import VersionSourceInterface # The Python-aware NodeJS version regex # This is very similar to `packaging.version.VERSION_PATTERN`, with a few changes: # - Don't accept underscores # - Only support four-component release, prerelease, and build segments # - Require - to indicate prerelease NODE_VERSION_PATTERN = r""" (?P[0-9]+) # major \. (?P[0-9]+) # minor \. (?P[0-9]+) # patch (?P
                                      # pre-release
        -
        (?P(a|b|c|rc|alpha|beta|pre|preview))
        [-\.]?
        (?P[0-9]+)?
    )?
    (?:
       \+
       (?P
            [0-9A-Za-z][0-9A-Za-z-_]*            # non-hyphen/dash leading identifier
            (?:
                (?:\.[0-9A-Za-z-_]+)*            # dot-prefixed identifier segments
            \.                                   # Final dot-delimited segment
                [0-9A-Za-z_-]*                   # non-hyphen/dash trailing identifier
                [0-9A-Za-z]
            )?
        )
   )?
"""

# The NodeJS-aware Python version regex
# This is very similar to `packaging.version.VERSION_PATTERN`, with a few changes:
# - Only support four-component release, prerelease, and build segments
PYTHON_VERSION_PATTERN = r"""
   v?
   (?:
       (?P[0-9]+)                           # major
       \.
       (?P[0-9]+)                           # minor
       \.
       (?P[0-9]+)                           # patch
       (?P
                                    # pre-release
           [-_\.]?
           (?P(alpha|beta|preview|a|b|c|rc|pre))
           [-_\.]?
           (?P[0-9]+)?
       )?
       (?:
           \+
           (?P
                [0-9A-Za-z][0-9A-Za-z-_]*          # non-hyphen/dash leading identifier
                (?:
                    (?:\.[0-9A-Za-z-_]+)*          # dot-prefixed identifier
                    \.
                    [0-9A-Za-z_-]*                 # non-hyphen/dash trailing identifier
                    [0-9A-Za-z]
                )?
            )
       )?
   )
"""


class NodeJSVersionSource(VersionSourceInterface):
    PLUGIN_NAME = "nodejs"

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.__path = None

    @property
    def path(self):
        if self.__path is None:
            version_file = self.config.get("path", "package.json")
            if not isinstance(version_file, (str, bytes, os.PathLike)):
                raise TypeError(
                    "Option `path` for version source `{}` must be a string".format(
                        self.PLUGIN_NAME
                    )
                )

            self.__path = os.fspath(version_file)

        return self.__path

    @staticmethod
    def node_version_to_python(version: str) -> str:
        # NodeJS version strings are a near superset of Python version strings
        match = re.match(
            r"^\s*" + NODE_VERSION_PATTERN + r"\s*$",
            version,
            re.VERBOSE | re.IGNORECASE,
        )
        if match is None:
            raise ValueError(f"Version {version!r} did not match regex")

        parts = ["{major}.{minor}.{patch}".format_map(match)]

        if match["pre"]:
            if match["pre_n"] is None:
                parts.append("{pre_l}".format_map(match))
            else:
                parts.append("{pre_l}{pre_n}".format_map(match))

        if match["build"]:
            parts.append("+{build}".format_map(match))

        return "".join(parts)

    @staticmethod
    def python_version_to_node(version: str) -> str:
        # NodeJS version strings are a near superset of Python version strings
        match = re.match(
            r"^\s*" + PYTHON_VERSION_PATTERN + r"\s*$",
            version,
            re.VERBOSE | re.IGNORECASE,
        )
        if match is None:
            raise ValueError(f"Version {version!r} did not match regex")

        parts = ["{major}.{minor}.{patch}".format_map(match)]

        if match["pre"]:
            if match["pre_n"] is None:
                parts.append("-{pre_l}".format_map(match))
            else:
                parts.append("-{pre_l}{pre_n}".format_map(match))

        if match["local"]:
            parts.append("+{local}".format_map(match))
        return "".join(parts)

    def get_version_data(self):
        path = os.path.normpath(os.path.join(self.root, self.path))
        if not os.path.isfile(path):
            raise OSError(f"file does not exist: {self.path}")

        with open(path, "r", encoding="utf-8") as f:
            data = json.load(f)

        return {"version": self.node_version_to_python(data["version"])}

    def set_version(self, version: str, version_data):
        path = os.path.normpath(os.path.join(self.root, self.path))
        if not os.path.isfile(path):
            raise OSError(f"file does not exist: {self.path}")

        # Read the original file so we can see if it has a trailing
        # newline character.
        with open(path, "r") as f:
            raw_data = f.read()

        data = json.loads(raw_data)

        data["version"] = self.python_version_to_node(version)
        with open(path, "w") as f:
            json.dump(data, f, indent=4)
            if raw_data.endswith('\n'):
                f.write('\n')
hatch_nodejs_version-0.3.2/tests/__init__.py0000644000000000000000000000017213615410400016105 0ustar00# SPDX-FileCopyrightText: 2022-present Angus Hollands 
#
# SPDX-License-Identifier: MIT
import pytest
hatch_nodejs_version-0.3.2/tests/conftest.py0000644000000000000000000000314413615410400016175 0ustar00# SPDX-FileCopyrightText: 2022-present Angus Hollands 
# SPDX-FileCopyrightText: 2022-present Ofek Lev 
#
# SPDX-License-Identifier: MIT
import errno
import os
import shutil
import stat
import tempfile
from contextlib import contextmanager
import pathlib

import pytest


def touch_file(path):
    with open(path, "a"):
        os.utime(path, None)


def create_file(path, contents):
    with open(path, "w") as f:
        f.write(contents)


@contextmanager
def create_project(directory):
    project_dir = directory / "my-app"
    os.mkdir(project_dir)

    package_dir = project_dir / "my_app"
    os.mkdir(package_dir)

    touch_file(package_dir / "__init__.py")
    touch_file(package_dir / "foo.py")
    touch_file(package_dir / "bar.py")
    touch_file(package_dir / "baz.py")

    origin = os.getcwd()
    os.chdir(project_dir)
    try:
        yield project_dir
    finally:
        os.chdir(origin)


def handle_remove_readonly(func, path, exc):  # no cov
    # PermissionError: [WinError 5] Access is denied: '...\\.git\\...'
    if func in (os.rmdir, os.remove, os.unlink) and exc[1].errno == errno.EACCES:
        os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
        func(path)
    else:
        raise


@pytest.fixture
def temp_dir():
    directory = tempfile.mkdtemp()
    try:
        directory = pathlib.Path(os.path.realpath(directory))
        yield directory
    finally:
        shutil.rmtree(directory, ignore_errors=False, onerror=handle_remove_readonly)


@pytest.fixture
def project(temp_dir):
    with create_project(temp_dir) as project:
        yield project
hatch_nodejs_version-0.3.2/tests/test_metadata_config.py0000644000000000000000000001345213615410400020517 0ustar00# SPDX-FileCopyrightText: 2022-present Angus Hollands 
#
# SPDX-License-Identifier: MIT
import pytest
import json

from hatch_nodejs_version.metadata_source import NodeJSMetadataHook

TRIVIAL_PYPROJECT_CONTENTS = """
[build-backend]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"
[project]
name = "my-app"
version = "0.0.0"
[tool.hatch.metadata.hooks.nodejs]
"""

TRIVIAL_PACKAGE_CONTENTS = """
{
  "name": "my-app",
  "version": "1.0.0",
  "description": "A terrible package",
  "keywords": [
    "what",
    "is",
    "the",
    "time"
  ],
  "homepage": "https://where-the-heart-is.com",
  "bugs": {
    "url": "https://www.send-help.com",
    "email": "funky@rider.com"
  },
  "license": "MIT",
  "author": {
    "name": "Alice Roberts",
    "email": "alice.roberts@bbc.lol"
  },
  "contributors": [
        {
        "name": "Isaac Newton",
        "email": "isaac.newton@apple.com"
      }
  ],
  "repository": {
    "type": "git",
    "url": "https://github.com/some/code.git"
  }
}
"""

TRIVIAL_EXPECTED_METADATA = {
    "license": "MIT",
    "urls": {
        "Bug Tracker": "https://www.send-help.com",
        "Repository": "https://github.com/some/code.git",
        "Homepage": "https://where-the-heart-is.com",
    },
    "authors": [
        {
            "name": "Alice Roberts",
            "email": "alice.roberts@bbc.lol",
        }
    ],
    "maintainers": [{"name": "Isaac Newton", "email": "isaac.newton@apple.com"}],
    "keywords": ["what", "is", "the", "time"],
    "description": "A terrible package",
    "name": "my-app",
}


class TestMetadata:
    @pytest.mark.parametrize(
        "alt_package_json",
        [None, "package-other.json"],
    )
    def test_all_metadata(self, project, alt_package_json):
        # Create a simple project
        package_json = "package.json" if alt_package_json is None else alt_package_json
        (project / "pyproject.toml").write_text(TRIVIAL_PYPROJECT_CONTENTS)
        (project / package_json).write_text(TRIVIAL_PACKAGE_CONTENTS)

        config = {} if alt_package_json is None else {"path": alt_package_json}
        metadata = {}
        metadata_source = NodeJSMetadataHook(project, config=config)
        metadata_source.update(metadata)

        assert metadata == TRIVIAL_EXPECTED_METADATA

    @pytest.mark.parametrize(
        "pyproject_field",
        [
            "urls",
            "description",
            "name",
            "keywords",
            "authors",
            "maintainers",
            "license",
        ],
    )
    def test_subset_metadata(self, project, pyproject_field):
        # Create a simple project
        (project / "pyproject.toml").write_text(TRIVIAL_PYPROJECT_CONTENTS)
        (project / "package.json").write_text(TRIVIAL_PACKAGE_CONTENTS)

        config = {"fields": [pyproject_field]}

        metadata = {}
        metadata_source = NodeJSMetadataHook(project, config=config)
        metadata_source.update(metadata)

        assert pyproject_field in metadata
        assert len(metadata) == len(config["fields"])
        assert metadata[pyproject_field] == TRIVIAL_EXPECTED_METADATA[pyproject_field]

    def test_contributors_as_maintainers(self, project):
        # Create a simple project
        (project / "pyproject.toml").write_text(TRIVIAL_PYPROJECT_CONTENTS)
        (project / "package.json").write_text(TRIVIAL_PACKAGE_CONTENTS)

        metadata = {}
        metadata_source = NodeJSMetadataHook(
            project, config={"contributors-as-maintainers": True}
        )
        metadata_source.update(metadata)

        assert metadata["authors"] == TRIVIAL_EXPECTED_METADATA["authors"]
        assert metadata["maintainers"] == TRIVIAL_EXPECTED_METADATA["maintainers"]

    def test_contributors_as_authors(self, project):
        # Create a simple project
        (project / "pyproject.toml").write_text(TRIVIAL_PYPROJECT_CONTENTS)
        (project / "package.json").write_text(TRIVIAL_PACKAGE_CONTENTS)

        metadata = {}
        metadata_source = NodeJSMetadataHook(
            project, config={"contributors-as-maintainers": False}
        )
        metadata_source.update(metadata)

        assert (
            metadata["authors"]
            == TRIVIAL_EXPECTED_METADATA["authors"]
            + TRIVIAL_EXPECTED_METADATA["maintainers"]
        )

    def test_labels(self, project):
        # Create a simple project
        (project / "pyproject.toml").write_text(TRIVIAL_PYPROJECT_CONTENTS)
        (project / "package.json").write_text(TRIVIAL_PACKAGE_CONTENTS)

        metadata = {}
        metadata_source = NodeJSMetadataHook(
            project,
            config={
                "repository-label": "the-repository",
                "bugs-label": "the-bug-tracker",
                "homepage-label": "the-homepage",
            },
        )
        metadata_source.update(metadata)

        urls = metadata["urls"]
        assert urls["the-repository"] == "https://github.com/some/code.git"
        assert urls["the-bug-tracker"] == "https://www.send-help.com"
        assert urls["the-homepage"] == "https://where-the-heart-is.com"

    def test_authors_accepted_as_strings(self, project):
        original_package_content = json.loads(TRIVIAL_PACKAGE_CONTENTS)
        updated_package_content = original_package_content.copy()
        author_as_string = f"{original_package_content['author']['name']} " \
                           f"<{original_package_content['author']['email']}>"
        updated_package_content['author'] = author_as_string
        (project / "pyproject.toml").write_text(TRIVIAL_PYPROJECT_CONTENTS)
        (project / "package.json").write_text(json.dumps(updated_package_content))

        config = {}
        metadata = {}
        metadata_source = NodeJSMetadataHook(project, config=config)
        metadata_source.update(metadata)
        assert metadata == TRIVIAL_EXPECTED_METADATA

hatch_nodejs_version-0.3.2/tests/test_version_config.py0000644000000000000000000000756413615410400020433 0ustar00# SPDX-FileCopyrightText: 2022-present Angus Hollands 
#
# SPDX-License-Identifier: MIT
import json

import pytest

from hatch_nodejs_version.version_source import NodeJSVersionSource

GOOD_NODE_PYTHON_VERSIONS = [
    ("1.4.5", "1.4.5"),
    ("1.4.5-a0", "1.4.5a0"),
    ("1.4.5-a", "1.4.5a"),
    ("1.4.5-b0", "1.4.5b0"),
    ("1.4.5-c1", "1.4.5c1"),
    ("1.4.5-rc0", "1.4.5rc0"),
    ("1.4.5-alpha0", "1.4.5alpha0"),
    ("1.4.5-beta0", "1.4.5beta0"),
    ("1.4.5-pre9", "1.4.5pre9"),
    ("1.4.5-preview0", "1.4.5preview0"),
    ("1.4.5-preview0+build1.0.0", "1.4.5preview0+build1.0.0"),
    ("1.4.5-preview0+build-1.0.0", "1.4.5preview0+build-1.0.0"),
    ("1.4.5-preview0+good-1_0.0", "1.4.5preview0+good-1_0.0"),
]


class TestVersion:
    @pytest.mark.parametrize(
        "python_version",
        [
            "1.4",
            "1.4.5ab",
            "1.4.5-c0.smoke2",
            "1.4.5rc.post1@dev2",
            "1.4.5rc0.post1+-bad",
            "1.4.5rc0.post1+bad_",
        ],
    )
    def test_parse_python_incorrect(self, python_version):
        with pytest.raises(ValueError, match=".* did not match regex"):
            NodeJSVersionSource.python_version_to_node(python_version)

    @pytest.mark.parametrize(
        "node_version",
        [
            "1.4",
            "1.4.5a0",
            "1.4.5-c0.post1",
            "1.4.5-rc0.post1.dev2",
            "1.4.5-rc0.post1+-bad",
            "1.4.5-rc0.post1+bad_",
        ],
    )
    def test_parse_node_incorrect(self, node_version):
        with pytest.raises(ValueError, match=".* did not match regex"):
            NodeJSVersionSource.node_version_to_python(node_version)

    @pytest.mark.parametrize(
        "node_version, python_version",
        GOOD_NODE_PYTHON_VERSIONS,
    )
    @pytest.mark.parametrize(
        "alt_package_json",
        [None, "package-other.json"],
    )
    def test_version_from_package(
        self, project, node_version, python_version, alt_package_json
    ):
        # Create a simple project
        (project / "pyproject.toml").write_text(
            """
[build-system]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"
[project]
name = "my-app"
dynamic = ["version"]
[tool.hatch.version]
source = "nodejs"
 """
        )
        package_json = "package.json" if alt_package_json is None else alt_package_json
        (project / package_json).write_text(
            f"""
{{
  "name": "my-app",
  "version": "{node_version}"
}}
"""
        )
        config = {} if alt_package_json is None else {"path": alt_package_json}
        version_source = NodeJSVersionSource(project, config=config)
        data = version_source.get_version_data()
        assert data["version"] == python_version

    @pytest.mark.parametrize(
        "node_version, python_version",
        GOOD_NODE_PYTHON_VERSIONS,
    )
    @pytest.mark.parametrize(
        "alt_package_json",
        [None, "package-other.json"],
    )
    def test_version_to_package(
        self, project, node_version, python_version, alt_package_json
    ):
        package_json = "package.json" if alt_package_json is None else alt_package_json
        (project / "pyproject.toml").write_text(
            """
[build-system]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"
[project]
name = "my-app"
dynamic = ["version"]
[tool.hatch.version]
source = "nodejs"
 """
        )
        (project / package_json).write_text(
            """
{
  "name": "my-app",
  "version": "0.0.0"
}
"""
        )
        config = {} if alt_package_json is None else {"path": alt_package_json}
        version_source = NodeJSVersionSource(project, config=config)
        version_data = version_source.get_version_data()
        version_source.set_version(python_version, version_data)

        written_package = json.loads((project / package_json).read_text())
        assert written_package["version"] == node_version
hatch_nodejs_version-0.3.2/.gitignore0000644000000000000000000000601313615410400014622 0ustar00# 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/
share/python-wheels/
*.egg-info/
.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
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
#   For a library or package, you might want to ignore these files since the code is
#   intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
#   install all needed dependencies.
#Pipfile.lock

# poetry
#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
#   This is especially recommended for binary packages to ensure reproducibility, and is more
#   commonly ignored for libraries.
#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
#   in version control.
#   https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
#  and can be added to the global gitignore or merged into this file.  For a more nuclear
#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea
.envrc
hatch_nodejs_version-0.3.2/LICENSE.txt0000644000000000000000000000211413615410400014453 0ustar00MIT License

Copyright (c) 2022-present Angus Hollands 

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
hatch_nodejs_version-0.3.2/README.md0000644000000000000000000001074313615410400014116 0ustar00# hatch-nodejs-version

[![PyPI - Version](https://img.shields.io/pypi/v/hatch-nodejs-version.svg)](https://pypi.org/project/hatch-nodejs-version)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/hatch-nodejs-version.svg)](https://pypi.org/project/hatch-nodejs-version)
[![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch)

-----
This package provides two Hatch plugins:

- [version source plugin](https://hatch.pypa.io/latest/plugins/version-source/) that reads/writes the package version
  from the `version` field of the Node.js `package.json` file.
- [metadata hook plugin](https://hatch.pypa.io/latest/plugins/metadata-hook/) that reads PEP 621 metadata from the
  Node.js `package.json` file.

**Table of Contents**

- [Installation](#installation)
- [Global dependency](#global-dependency)
- [Version source](#version-source)
- [Metadata hook](#metadata-hook)
- [License](#license)

## Global dependency

Ensure `hatch-nodejs-version` is defined within the `build-system.requires` field in your `pyproject.toml` file.

```toml
[build-system]
requires = ["hatchling", "hatch-nodejs-version"]
build-backend = "hatchling.build"
```

## Version source

The [version source plugin](https://hatch.pypa.io/latest/plugins/version-source/) name is `nodejs`.

- ***pyproject.toml***

    ```toml
    [tool.hatch.version]
    source = "nodejs"
    ```

- ***hatch.toml***

    ```toml
    [version]
    source = "nodejs"
    ```

### Semver

The semver specification defines the following version sections:

- `major`
- `minor`
- `patch`
- `pre-release`
- `build`

Meanwhile, [PEP 440](https://peps.python.org/pep-0440/#version-scheme) defines:

- `epoch`
- `major`
- `minor`
- `patch`
- `pre-release`
- `post-release`
- `dev-release`

In order to ensure contentful round-trip support, and ensure semantic consistency between Node.js and Python, this plugin only
accepts the common version parts:

- `major`
- `minor`
- `patch`
- `pre-release`

e.g. `1.2.3-rc0`.

Note that where normalisation occurs, the round-trip result will differ. This can be avoided by careful choice of the delimeters e.g. `-.`.


### Version source options

| Option        | Type | Default       | Description                                |
|---------------| --- |---------------|--------------------------------------------|
| `path`        | `str` | `package.json` | Relative path to the `package.json` file. |

## Metadata hook

The [metadata hook plugin](https://hatch.pypa.io/dev/plugins/metadata-hook/reference/) name is `nodejs`.

- ***pyproject.toml***

    ```toml
    [tool.hatch.metadata.hooks.nodejs]
    ```

- ***hatch.toml***

    ```toml
    [metadata.hooks.nodejs]
    ```

### Metadata hook options

| Option                        | Type            | Default          | Description                                                                                                                               |
|-------------------------------|-----------------|------------------|-------------------------------------------------------------------------------------------------------------------------------------------|
| `path`                        | `str`           | `"package.json"` | Relative path to the `package.json` file.                                                                                                 |
| `fields`                      | `list` of `str` | `None`           | Optional list of `pyproject.toml` fields to take from their counterparts in `package.json`. If missing, take all of the available fields. |
| `contributors-as-maintainers` | `bool`          | `True`           | Whether contributors in `package.json` should be considered maintainers (otherwise, treat them as authors).                               |
| `bugs-label`                  | `str`           | `"Bug Tracker"`  | The key in the URLs table of `pyproject.toml` that is populated by the `bugs` field in `package.json`                                     |
| `homepage-label`              | `str`           | `"Homepage"`     | The key in the URLs table of `pyproject.toml` that is populated by the `homepage` field in `package.json`                                 |
| `repository-label`            | `str`           | `"Repository"`   | The key in the URLs table of `pyproject.toml` that is populated by the `repository` field in `package.json`                               |

## License

`hatch-nodejs-version` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
hatch_nodejs_version-0.3.2/pyproject.toml0000644000000000000000000000233213615410400015546 0ustar00[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "hatch-nodejs-version"
description = "Hatch plugin for versioning from a package.json file"
authors = [
    {name = "Angus Hollands", email = "goosey15@gmail.com"},
]
dependencies = [
    "hatchling>=0.21.0"
]
requires-python = ">= 3.7"
readme = "README.md"
license = {text = "MIT"}
classifiers = [
  "Framework :: Hatch",
  "Programming Language :: Python :: 3.7",
  "Programming Language :: Python :: 3.8",
  "Programming Language :: Python :: 3.9",
  "Programming Language :: Python :: 3.10",
  "Programming Language :: Python :: 3.11",
]
dynamic = ["version"]

[project.optional-dependencies]

[project.entry-points.hatch]
nodejs = "hatch_nodejs_version.hooks"

[project.urls]
Homepage = "https://github.com/agoose77/hatch-nodejs-version"
"Issue Tracker" = "https://github.com/agoose77/hatch-nodejs-version/issues"
"Source Code" = "https://github.com/agoose77/hatch-nodejs-version"

[tool.hatch.version]
path = "hatch_nodejs_version/_version.py"

[tool.black]
line-length = 88
target-version = ['py310']
include = '\.pyi?$'
exclude = "extern"

[tool.isort]
profile = "black"

[tool.pdm]
[tool.pdm.dev-dependencies]
dev = [
    "pytest>=7.0.1",
]
hatch_nodejs_version-0.3.2/PKG-INFO0000644000000000000000000001243513615410400013734 0ustar00Metadata-Version: 2.1
Name: hatch-nodejs-version
Version: 0.3.2
Summary: Hatch plugin for versioning from a package.json file
Project-URL: Homepage, https://github.com/agoose77/hatch-nodejs-version
Project-URL: Issue Tracker, https://github.com/agoose77/hatch-nodejs-version/issues
Project-URL: Source Code, https://github.com/agoose77/hatch-nodejs-version
Author-email: Angus Hollands 
License: MIT
License-File: LICENSE.txt
Classifier: Framework :: Hatch
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Requires-Python: >=3.7
Requires-Dist: hatchling>=0.21.0
Description-Content-Type: text/markdown

# hatch-nodejs-version

[![PyPI - Version](https://img.shields.io/pypi/v/hatch-nodejs-version.svg)](https://pypi.org/project/hatch-nodejs-version)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/hatch-nodejs-version.svg)](https://pypi.org/project/hatch-nodejs-version)
[![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch)

-----
This package provides two Hatch plugins:

- [version source plugin](https://hatch.pypa.io/latest/plugins/version-source/) that reads/writes the package version
  from the `version` field of the Node.js `package.json` file.
- [metadata hook plugin](https://hatch.pypa.io/latest/plugins/metadata-hook/) that reads PEP 621 metadata from the
  Node.js `package.json` file.

**Table of Contents**

- [Installation](#installation)
- [Global dependency](#global-dependency)
- [Version source](#version-source)
- [Metadata hook](#metadata-hook)
- [License](#license)

## Global dependency

Ensure `hatch-nodejs-version` is defined within the `build-system.requires` field in your `pyproject.toml` file.

```toml
[build-system]
requires = ["hatchling", "hatch-nodejs-version"]
build-backend = "hatchling.build"
```

## Version source

The [version source plugin](https://hatch.pypa.io/latest/plugins/version-source/) name is `nodejs`.

- ***pyproject.toml***

    ```toml
    [tool.hatch.version]
    source = "nodejs"
    ```

- ***hatch.toml***

    ```toml
    [version]
    source = "nodejs"
    ```

### Semver

The semver specification defines the following version sections:

- `major`
- `minor`
- `patch`
- `pre-release`
- `build`

Meanwhile, [PEP 440](https://peps.python.org/pep-0440/#version-scheme) defines:

- `epoch`
- `major`
- `minor`
- `patch`
- `pre-release`
- `post-release`
- `dev-release`

In order to ensure contentful round-trip support, and ensure semantic consistency between Node.js and Python, this plugin only
accepts the common version parts:

- `major`
- `minor`
- `patch`
- `pre-release`

e.g. `1.2.3-rc0`.

Note that where normalisation occurs, the round-trip result will differ. This can be avoided by careful choice of the delimeters e.g. `-.`.


### Version source options

| Option        | Type | Default       | Description                                |
|---------------| --- |---------------|--------------------------------------------|
| `path`        | `str` | `package.json` | Relative path to the `package.json` file. |

## Metadata hook

The [metadata hook plugin](https://hatch.pypa.io/dev/plugins/metadata-hook/reference/) name is `nodejs`.

- ***pyproject.toml***

    ```toml
    [tool.hatch.metadata.hooks.nodejs]
    ```

- ***hatch.toml***

    ```toml
    [metadata.hooks.nodejs]
    ```

### Metadata hook options

| Option                        | Type            | Default          | Description                                                                                                                               |
|-------------------------------|-----------------|------------------|-------------------------------------------------------------------------------------------------------------------------------------------|
| `path`                        | `str`           | `"package.json"` | Relative path to the `package.json` file.                                                                                                 |
| `fields`                      | `list` of `str` | `None`           | Optional list of `pyproject.toml` fields to take from their counterparts in `package.json`. If missing, take all of the available fields. |
| `contributors-as-maintainers` | `bool`          | `True`           | Whether contributors in `package.json` should be considered maintainers (otherwise, treat them as authors).                               |
| `bugs-label`                  | `str`           | `"Bug Tracker"`  | The key in the URLs table of `pyproject.toml` that is populated by the `bugs` field in `package.json`                                     |
| `homepage-label`              | `str`           | `"Homepage"`     | The key in the URLs table of `pyproject.toml` that is populated by the `homepage` field in `package.json`                                 |
| `repository-label`            | `str`           | `"Repository"`   | The key in the URLs table of `pyproject.toml` that is populated by the `repository` field in `package.json`                               |

## License

`hatch-nodejs-version` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.