diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..712bfc3 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,19 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "pip" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "daily" + - package-ecosystem: "maven" # See documentation for possible values + directory: "/data/local/test_basic/layout_maven/ms-101" # Location of package manifests + schedule: + interval: "daily" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..0467e8d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,40 @@ +name: Build PyPI +on: + workflow_call: + workflow_dispatch: + push: + pull_request: + types: + - opened + - reopened + - synchronize + +jobs: + linting: + name: Reuse linting job + uses: ./.github/workflows/lint.yml + + build: + needs: linting + runs-on: ubuntu-latest + steps: + - name: Check out source repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 #full history + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + - name: Install dependencies + run: pip install hatch + - name: Run unit and integrations tests + run: hatch run test:pytest --cov=reqstool-python-decorators --cov-report=xml --cov-report=html + - name: Build project + run: hatch build + # Upload artifacts for later use + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ diff --git a/.github/workflows/check_release.yml b/.github/workflows/check_release.yml new file mode 100644 index 0000000..6c35b4c --- /dev/null +++ b/.github/workflows/check_release.yml @@ -0,0 +1,11 @@ +name: Lint (black and flake8) +on: + workflow_call: + +jobs: + check-release: + runs-on: ubuntu-latest + steps: + - name: Check branch and tag + if: github.event_name == 'push' && !(github.ref == 'refs/heads/main' && startsWith(github.ref, 'refs/tags/v')) + run: exit 1 \ No newline at end of file diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..65d73f8 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,21 @@ +name: Lint (black and flake8) +on: + workflow_dispatch: + workflow_call: + +jobs: + linting: + runs-on: ubuntu-latest + steps: + - name: Check out source repository + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + - name: Install pip package(s) + run: pip install hatch + - name: Run black formatter check + run: hatch run lint:black --check --verbose src tests + - name: Run flake8 linter + run: hatch run lint:flake8 \ No newline at end of file diff --git a/.github/workflows/publish_gh_pages.yml b/.github/workflows/publish_gh_pages.yml new file mode 100644 index 0000000..e75c019 --- /dev/null +++ b/.github/workflows/publish_gh_pages.yml @@ -0,0 +1,47 @@ +name: Publish to GitHub Pages +on: + workflow_dispatch: + release: + types: [created] + push: + branches: + - main + +concurrency: + group: github-pages + cancel-in-progress: false +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write +jobs: + build: + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Configure Pages + uses: actions/configure-pages@v4 + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: "18" + - name: Install Antora + run: npm i antora + - name: Install Asciidoctor Kroki extension + run: npm i asciidoctor asciidoctor-kroki + - name: Generate Site + run: npx antora docs/antora-playbook.yml + - name: Create site folders + run: mkdir -p docs/build/site + - name: Upload Artifacts + uses: actions/upload-pages-artifact@v3 + with: + path: docs/build/site + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/publish_pypi_prod.yml b/.github/workflows/publish_pypi_prod.yml new file mode 100644 index 0000000..ba96ce0 --- /dev/null +++ b/.github/workflows/publish_pypi_prod.yml @@ -0,0 +1,37 @@ +name: Build and publish to PyPI + +on: + release: + types: [created] + +jobs: + check-release: + name: Reuse check release + uses: ./.github/workflows/check_release.yml + build: + name: Reuse build + uses: ./.github/workflows/build.yml + + + publish-to-pypi: + needs: + - check-release + - build + runs-on: ubuntu-latest + environment: + name: prod + url: https://pypi.org/p/reqstool-client + permissions: + id-token: write # IMPORTANT: this permission is mandatory for trusted publishing + steps: + # Download artifacts from the build job + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + name: dist + path: dist + - name: Publish distribution 📦 to PyPI + # if: startsWith(github.ref, 'refs/tags') + uses: pypa/gh-action-pypi-publish@release/v1 + with: + sign-artifacts: true diff --git a/.github/workflows/publish_pypi_test.yml b/.github/workflows/publish_pypi_test.yml new file mode 100644 index 0000000..119cac3 --- /dev/null +++ b/.github/workflows/publish_pypi_test.yml @@ -0,0 +1,32 @@ +name: Build and publish to Test PyPI + +on: + workflow_dispatch: + +jobs: + build: + name: Reuse build + uses: ./.github/workflows/build.yml + + publish-to-test-pypi: + needs: build + runs-on: ubuntu-latest + # Specifying a GitHub environment is optional, but strongly encouraged + environment: + name: test + url: https://test.pypi.org/p/reqstool-client + permissions: + id-token: write # IMPORTANT: this permission is mandatory for trusted publishing + steps: + # Download artifacts from the build job + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + name: dist + path: dist + - name: Publish distribution 📦 to Test PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + sign-artifacts: true + skip-existing: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bfa28bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,219 @@ +# Created by https://www.toptal.com/developers/gitignore/api/java,maven,python +# Edit at https://www.toptal.com/developers/gitignore?templates=java,maven,python + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +### Maven ### +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +# https://github.com/takari/maven-wrapper#usage-without-binary-jar +.mvn/wrapper/maven-wrapper.jar + +# Eclipse m2e generated files +# Eclipse Core +.project +# JDT-specific (Eclipse Java Development Tools) +.classpath + +### 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/ +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: +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ + +# 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/ + +### Python Patch ### +# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration +poetry.toml + +# ruff +.ruff_cache/ + +# LSP config files +pyrightconfig.json + +# End of https://www.toptal.com/developers/gitignore/api/java,maven,python \ No newline at end of file diff --git a/LICENSE b/LICENSE index 5ea452a..f1ff0dd 100644 --- a/LICENSE +++ b/LICENSE @@ -18,4 +18,3 @@ 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..fb74188 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +## Description + +This documentation provides information on how to use the Reqstool Hatch Plugin. The plugin is designed to be used with the Hatch build tool and facilitates the integration of the Reqstool Decorators in your project. + +## Installation + +To use the Reqstool Hatch Plugin, follow these steps: + +- Update your project dependencies in the `pyproject.toml` file and +ensure that the Reqstool Decorators' dependency is listed as follows; +``` +dependencies = ["reqstool-decorators == "] +``` + +When you declare this in the pyproject.toml file, you are specifying the required versions for the dependency of the Reqstool Decorators. This ensures that the correct version of the dependencies are used when installing and running your project. + + + +## Usage + + + +### Configuration + +The plugin can be configured through the `pyproject.toml` file. Configure plugin in `pyproject.toml`as follows; + +``` +[tool.hatch.build.targets.wheel.hooks.decorators] +dependencies = ["reqstool-hatch-plugin == "] +path = ["src","tests"] + +``` +It specifies that the reqstool-hatch-plugin is a dependency for the build process, and it should be of a specific version. + +Further it defines the paths where the plugin should be applied. In this case, it specifies that the plugin should be applied to files in the src and tests directories. \ No newline at end of file diff --git a/docs/antora-playbook.yml b/docs/antora-playbook.yml new file mode 100644 index 0000000..862868f --- /dev/null +++ b/docs/antora-playbook.yml @@ -0,0 +1,23 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/asciidoctor/asciidoctor-intellij-plugin/main/src/main/resources/jsonSchemas/antoraPlaybookSchema.json + +site: + title: Reqstool Python Hatch Plugin Documentation + url: https://github.com/luftfartsverket/reqstool-python-hatch-plugin + start_page: reqstool-python-hatch-plugin::index.adoc + +content: + sources: + - url: ~+ + branches: HEAD + start_path: docs +ui: + bundle: + url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable + snapshot: true +asciidoc: + attributes: + kroki-server-url: https://kroki.io + kroki-fetch-diagram: true + extensions: + - asciidoctor-kroki + diff --git a/docs/antora.yml b/docs/antora.yml new file mode 100644 index 0000000..2be1dfa --- /dev/null +++ b/docs/antora.yml @@ -0,0 +1,7 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/asciidoctor/asciidoctor-intellij-plugin/main/src/main/resources/jsonSchemas/antoraComponentSchema.json + +name: reqstool-python-hatch-plugin +title: Reqstool Python Hatch Plugin +version: 0.0.1 +nav: + - modules/ROOT/nav.adoc diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc new file mode 100644 index 0000000..ccbcafa --- /dev/null +++ b/docs/modules/ROOT/nav.adoc @@ -0,0 +1,2 @@ +* xref:index.adoc[Start] +* xref:usage.adoc[Usage] \ No newline at end of file diff --git a/docs/modules/ROOT/pages/description.adoc b/docs/modules/ROOT/pages/description.adoc new file mode 100644 index 0000000..fd0634d --- /dev/null +++ b/docs/modules/ROOT/pages/description.adoc @@ -0,0 +1,3 @@ +== Description + +This documentation provides information on how to use the Reqstool Python Hatch Plugin. The plugin is designed to be used with the Hatch build tool and facilitates the integration of the Reqstool Python Decorators in your project. diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc new file mode 100644 index 0000000..036ed3f --- /dev/null +++ b/docs/modules/ROOT/pages/index.adoc @@ -0,0 +1,7 @@ += Reqstool Python Hatch Plugin + +include::description.adoc[] + +include::installation.adoc[] + +include::license.adoc[] \ No newline at end of file diff --git a/docs/modules/ROOT/pages/installation.adoc b/docs/modules/ROOT/pages/installation.adoc new file mode 100644 index 0000000..aebd353 --- /dev/null +++ b/docs/modules/ROOT/pages/installation.adoc @@ -0,0 +1,20 @@ +== Installation + +To use the Reqstool Python Hatch Plugin, follow these steps: + +- Update your project dependencies in the `pyproject.toml` file and +ensure that the Reqstool Decorators' dependency is listed as follows; +``` +dependencies = ["reqstool-python-decorators == "] +``` + +When you declare this in the pyproject.toml file, you are specifying the required versions for the dependency of the Reqstool Decorators. This ensures that the correct version of the dependencies are used when installing and running your project. + + + + + + + + + diff --git a/docs/modules/ROOT/pages/license.adoc b/docs/modules/ROOT/pages/license.adoc new file mode 100644 index 0000000..51e84f1 --- /dev/null +++ b/docs/modules/ROOT/pages/license.adoc @@ -0,0 +1,3 @@ +== License + +This project is licensed under the MIT License - see the LICENSE.md file for details. diff --git a/docs/modules/ROOT/pages/usage.adoc b/docs/modules/ROOT/pages/usage.adoc new file mode 100644 index 0000000..377896e --- /dev/null +++ b/docs/modules/ROOT/pages/usage.adoc @@ -0,0 +1,16 @@ +== Usage + + +=== Configuration + +The plugin can be configured through the `pyproject.toml` file. Configure plugin in `pyproject.toml`as follows; + +``` +[tool.hatch.build.targets.wheel.hooks.decorators] +dependencies = ["reqstool-python-hatch-plugin == "] +path = ["src","tests"] + +``` +It specifies that the reqstool-hatch-plugin is a dependency for the build process, and it should be of a specific version. + +Further it defines the paths where the plugin should be applied. In this case, it specifies that the plugin should be applied to files in the src and tests directories. \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..8581511 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,67 @@ +[build-system] +requires = ["hatchling", "hatch-vcs", "build", "twine"] +build-backend = "hatchling.build" + +[tool.pytest.ini_options] +addopts = ["-s", "--import-mode=importlib"] +pythonpath = [".", "src", "tests"] +testpaths = ["tests/unit"] + +[project] +name = "reqstool-python-hatch-plugin" +dynamic = ["version"] +authors = [{ name = "LFV", email = "sysdev@lfv.se" }] +description = "Hatch plugin to process reqstool-python-decorators when building with Hatch" +readme = "README.md" + +homepage = "https://github.com/Luftfartsverket/reqstool-python-hatch-plugin.git" +repository = "https://github.com/Luftfartsverket/reqstool-python-hatch-plugin.git" +documentation = "https://github.com/Luftfartsverket/reqstool-python-hatch-plugin.git" + +urls.Source = 'https://github.com/Luftfartsverket/reqstool-python-hatch-plugin.git' + +classifiers = [ + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Operating System :: OS Independent", + "Development Status :: 4 - Beta", +] + + +requires-python = ">=3.10" + +dependencies = [ + "reqstool-python-decorators == 0.1.dev6", # This version should change when a proper relase is made. + "ruamel.yaml==0.18.5", + "hatchling>=1.20.0", +] + +packages = [{ include = "reqstool_python_hatch_plugin", from = "src" }] + +[project.scripts] + +[project.entry-points.hatch] +decorators = "reqstool_python_hatch_plugin.hooks" + +[tool.hatch.version] +source = "vcs" + +[tool.hatch.version.raw-options] +local_scheme = "no-local-version" + +[tool.hatch.envs.test] +dependencies = ["pytest==8.0.0", "pytest-sugar==1.0.0", "pytest-cov==4.1.0"] + +[tool.hatch.envs.lint] +detached = true +dependencies = ["black==24.1.1", "flake8==7.0.0", "flake8-pyproject==1.2.3"] + +[tool.black] +line-length = 120 +target-version = ['py310'] + +[tool.flake8] +ignore = ["W503"] +max-line-length = 120 + +max-complexity = 10 diff --git a/src/reqstool_python_hatch_plugin/__init__.py b/src/reqstool_python_hatch_plugin/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/reqstool_python_hatch_plugin/build_hook/hook.py b/src/reqstool_python_hatch_plugin/build_hook/hook.py new file mode 100644 index 0000000..56405ed --- /dev/null +++ b/src/reqstool_python_hatch_plugin/build_hook/hook.py @@ -0,0 +1,60 @@ +# Copyright © LFV + + +from hatchling.builders.hooks.plugin.interface import BuildHookInterface +from reqstool_python_decorators.processors.decorator_processor import ProcessDecorator + + +class Decorator(BuildHookInterface): + """ + A class that contains code that will run during the Hatch build process. + + Attributes: + - `PLUGIN_NAME` (str): The name of the plugin. + - `__config_path` (list): The path configuration for the decorator. + + Methods: + - `get_config_path` : Get the configuration path. + - `initialize` : contains the code that will be run during the Hatch build process. + """ + + PLUGIN_NAME = "decorators" + + def __init__(self, *args, **kwargs): + """ + Initialize the Decorator instance. + + Args: + - *args: Additional arguments. + - **kwargs: Additional keyword arguments. + """ + super().__init__(*args, **kwargs) + self.__config_path = None + + @property + def get_config_path(self): + """ + Get the configuration path from the pyproject.toml file of the project using this plugin. + + Returns: + - `list`: Path(s) from the configuration. + """ + if self.__config_path is None: + path = self.config.get("path", []) + + self.__config_path = path + + return self.__config_path + + def initialize(self, version, build_data): + """ + Used by the Hatch build hook, any code in this function will run during the build process. + + Args: + - version: The version (not used but required). + - build_data: The build data (not used but required). + """ + path = self.get_config_path + + process_decorator = ProcessDecorator() + process_decorator.process_decorated_data(path_to_python_files=path) diff --git a/src/reqstool_python_hatch_plugin/hooks.py b/src/reqstool_python_hatch_plugin/hooks.py new file mode 100644 index 0000000..c4a8b5f --- /dev/null +++ b/src/reqstool_python_hatch_plugin/hooks.py @@ -0,0 +1,9 @@ +# Copyright © LFV + +from hatchling.plugin import hookimpl +from reqstool_python_hatch_plugin.build_hook.hook import Decorator + + +@hookimpl +def hatch_register_build_hook(): + return Decorator diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py new file mode 100644 index 0000000..c4677b0 --- /dev/null +++ b/tests/unit/conftest.py @@ -0,0 +1,7 @@ +# Copyright © LFV + +import os + + +def get_tests_rootdir() -> str: + return os.path.dirname(__file__).removesuffix("/unit") diff --git a/tests/unit/reqstool_python_hatch_plugin/test_hooks.py b/tests/unit/reqstool_python_hatch_plugin/test_hooks.py new file mode 100644 index 0000000..808dbe3 --- /dev/null +++ b/tests/unit/reqstool_python_hatch_plugin/test_hooks.py @@ -0,0 +1,5 @@ +# Copyright © LFV + + +def test_hooks(): + pass