From 7a06a8c278ac57ffff2300e5f0ee60fb189f1333 Mon Sep 17 00:00:00 2001 From: Giles Knap Date: Mon, 16 Dec 2024 12:32:21 +0000 Subject: [PATCH] update to template 2.6.0 --- .copier-answers.yml | 3 +- .devcontainer/devcontainer.json | 10 +++--- .github/CONTRIBUTING.md | 2 +- .github/ISSUE_TEMPLATE/bug_report.md | 21 ++++++++++++ .github/ISSUE_TEMPLATE/issue.md | 13 ++++++++ .../pull_request_template.md | 8 +++++ .github/pages/index.html | 2 +- .github/pages/make_switcher.py | 25 ++++++++------- .github/workflows/_pypi.yml | 2 ++ .github/workflows/_release.yml | 2 +- .github/workflows/ci.yml | 2 +- .gitignore | 1 + .pre-commit-config.yaml | 1 + .vscode/extensions.json | 2 +- .vscode/settings.json | 3 +- .vscode/tasks.json | 2 +- Dockerfile | 2 +- README.md | 2 +- catalog-info.yaml | 10 ------ pyproject.toml | 32 +++++++++++-------- src/vdct2template/__init__.py | 8 +++++ src/vdct2template/__main__.py | 5 ++- src/vdct2template/expansion.py | 7 ++-- tests/conftest.py | 12 +++++-- 24 files changed, 116 insertions(+), 61 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/issue.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md delete mode 100644 catalog-info.yaml diff --git a/.copier-answers.yml b/.copier-answers.yml index 6bdb63b..7710058 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,9 +1,8 @@ # Changes here will be overwritten by Copier -_commit: 2.1.0 +_commit: 2.6.0 _src_path: gh:DiamondLightSource/python-copier-template author_email: giles.knap@diamond.ac.uk author_name: Giles Knap -component_owner: group:default/sscc description: Converts EPICS vdct templates to pure msi compatible EPICS db templates distribution_name: vdct2template docker: false diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 79b85ff..979a89c 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -28,11 +28,11 @@ } }, "features": { - // Some default things like git config - "ghcr.io/devcontainers/features/common-utils:2": { - "upgradePackages": false - } + // add in eternal history and other bash features + "ghcr.io/diamondlightsource/devcontainer-features/bash-config:1.0.0": {} }, + // Create the config folder for the bash-config feature + "initializeCommand": "mkdir -p ${localEnv:HOME}/.config/bash-config", "runArgs": [ // Allow the container to access the host X11 display and EPICS CA "--net=host", @@ -43,4 +43,4 @@ "workspaceMount": "source=${localWorkspaceFolder}/..,target=/workspaces,type=bind", // After the container is created, install the python project in editable form "postCreateCommand": "pip install $([ -f dev-requirements.txt ] && echo '-c dev-requirements.txt') -e '.[dev]' && pre-commit install" -} \ No newline at end of file +} diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 2a890fa..074a361 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -24,4 +24,4 @@ It is recommended that developers use a [vscode devcontainer](https://code.visua This project was created using the [Diamond Light Source Copier Template](https://github.com/DiamondLightSource/python-copier-template) for Python projects. -For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.1.0/how-to.html). +For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.6.0/how-to.html). diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..aa65892 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,21 @@ +--- +name: Bug Report +about: The template to use for reporting bugs and usability issues +title: " " +labels: 'bug' +assignees: '' + +--- + +Describe the bug, including a clear and concise description of the expected behavior, the actual behavior and the context in which you encountered it (ideally include details of your environment). + +## Steps To Reproduce +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + + +## Acceptance Criteria +- Specific criteria that will be used to judge if the issue is fixed diff --git a/.github/ISSUE_TEMPLATE/issue.md b/.github/ISSUE_TEMPLATE/issue.md new file mode 100644 index 0000000..52c84dd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue.md @@ -0,0 +1,13 @@ +--- +name: Issue +about: The standard template to use for feature requests, design discussions and tasks +title: " " +labels: '' +assignees: '' + +--- + +A brief description of the issue, including specific stakeholders and the business case where appropriate + +## Acceptance Criteria +- Specific criteria that will be used to judge if the issue is fixed diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 0000000..8200afe --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,8 @@ +Fixes #ISSUE + +### Instructions to reviewer on how to test: +1. Do thing x +2. Confirm thing y happens + +### Checks for reviewer +- [ ] Would the PR title make sense to a user on a set of release notes diff --git a/.github/pages/index.html b/.github/pages/index.html index 80f0a00..c495f39 100644 --- a/.github/pages/index.html +++ b/.github/pages/index.html @@ -8,4 +8,4 @@ - \ No newline at end of file + diff --git a/.github/pages/make_switcher.py b/.github/pages/make_switcher.py index 0babd3c..c06813a 100755 --- a/.github/pages/make_switcher.py +++ b/.github/pages/make_switcher.py @@ -1,30 +1,32 @@ +"""Make switcher.json to allow docs to switch between different versions.""" + import json import logging from argparse import ArgumentParser from pathlib import Path from subprocess import CalledProcessError, check_output -from typing import List, Optional -def report_output(stdout: bytes, label: str) -> List[str]: +def report_output(stdout: bytes, label: str) -> list[str]: + """Print and return something received frm stdout.""" ret = stdout.decode().strip().split("\n") print(f"{label}: {ret}") return ret -def get_branch_contents(ref: str) -> List[str]: +def get_branch_contents(ref: str) -> list[str]: """Get the list of directories in a branch.""" stdout = check_output(["git", "ls-tree", "-d", "--name-only", ref]) return report_output(stdout, "Branch contents") -def get_sorted_tags_list() -> List[str]: +def get_sorted_tags_list() -> list[str]: """Get a list of sorted tags in descending order from the repository.""" stdout = check_output(["git", "tag", "-l", "--sort=-v:refname"]) return report_output(stdout, "Tags list") -def get_versions(ref: str, add: Optional[str]) -> List[str]: +def get_versions(ref: str, add: str | None) -> list[str]: """Generate the file containing the list of all GitHub Pages builds.""" # Get the directories (i.e. builds) from the GitHub Pages branch try: @@ -41,7 +43,7 @@ def get_versions(ref: str, add: Optional[str]) -> List[str]: tags = get_sorted_tags_list() # Make the sorted versions list from main branches and tags - versions: List[str] = [] + versions: list[str] = [] for version in ["master", "main"] + tags: if version in builds: versions.append(version) @@ -53,14 +55,12 @@ def get_versions(ref: str, add: Optional[str]) -> List[str]: return versions -def write_json(path: Path, repository: str, versions: str): +def write_json(path: Path, repository: str, versions: list[str]): + """Write the JSON switcher to path.""" org, repo_name = repository.split("/") - pages_url = f"https://{org}.github.io" - if repo_name != f"{org}.github.io": - # Only add the repo name if it isn't the source for the org pages site - pages_url += f"/{repo_name}" struct = [ - {"version": version, "url": f"{pages_url}/{version}/"} for version in versions + {"version": version, "url": f"https://{org}.github.io/{repo_name}/{version}/"} + for version in versions ] text = json.dumps(struct, indent=2) print(f"JSON switcher:\n{text}") @@ -68,6 +68,7 @@ def write_json(path: Path, repository: str, versions: str): def main(args=None): + """Parse args and write switcher.""" parser = ArgumentParser( description="Make a versions.json file from gh-pages directories" ) diff --git a/.github/workflows/_pypi.yml b/.github/workflows/_pypi.yml index 0c5258d..8032bba 100644 --- a/.github/workflows/_pypi.yml +++ b/.github/workflows/_pypi.yml @@ -15,3 +15,5 @@ jobs: - name: Publish to PyPI using trusted publishing uses: pypa/gh-action-pypi-publish@release/v1 + with: + attestations: false diff --git a/.github/workflows/_release.yml b/.github/workflows/_release.yml index e55efdb..81b6264 100644 --- a/.github/workflows/_release.yml +++ b/.github/workflows/_release.yml @@ -23,7 +23,7 @@ jobs: - name: Create GitHub Release # We pin to the SHA, not the tag, for security reasons. # https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions - uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 # v2.0.4 + uses: softprops/action-gh-release@e7a8f85e1c67a31e6ed99a94b41bd0b71bbee6b8 # v2.0.9 with: prerelease: ${{ contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc') }} files: "*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 93de608..bc606ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: strategy: matrix: runs-on: ["ubuntu-latest"] # can add windows-latest, macos-latest - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.10", "3.11", "3.12"] include: # Include one that runs in the dev environment - runs-on: "ubuntu-latest" diff --git a/.gitignore b/.gitignore index 7394d5e..537913a 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ cov.xml # Sphinx documentation docs/_build/ +docs/_api # PyBuilder target/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5a4cbf7..60fc23f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,6 +5,7 @@ repos: - id: check-added-large-files - id: check-yaml - id: check-merge-conflict + - id: end-of-file-fixer - repo: local hooks: diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 66ad632..933c580 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,4 +2,4 @@ "recommendations": [ "ms-vscode-remote.remote-containers", ] -} \ No newline at end of file +} diff --git a/.vscode/settings.json b/.vscode/settings.json index c129d99..101c75f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,7 +5,8 @@ "editor.codeActionsOnSave": { "source.organizeImports": "explicit" }, + "files.insertFinalNewline": true, "[python]": { "editor.defaultFormatter": "charliermarsh.ruff", }, -} \ No newline at end of file +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 946e69d..c999e86 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -13,4 +13,4 @@ "problemMatcher": [], } ] -} \ No newline at end of file +} diff --git a/Dockerfile b/Dockerfile index c4404ec..35d2abf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # The devcontainer should use the developer target and run as root with podman # or docker with user namespaces. ARG PYTHON_VERSION=3.11 -FROM python:${PYTHON_VERSION} as developer +FROM python:${PYTHON_VERSION} AS developer # Add any system dependencies for the developer/build environment here RUN apt-get update && apt-get install -y --no-install-recommends \ diff --git a/README.md b/README.md index f1ee176..1c35f6c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![CI](https://github.com/epics-containers/vdct2template/actions/workflows/ci.yml/badge.svg)](https://github.com/epics-containers/vdct2template/actions/workflows/ci.yml) [![Coverage](https://codecov.io/gh/epics-containers/vdct2template/branch/main/graph/badge.svg)](https://codecov.io/gh/epics-containers/vdct2template) [![PyPI](https://img.shields.io/pypi/v/vdct2template.svg)](https://pypi.org/project/vdct2template) -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) # vdct2template diff --git a/catalog-info.yaml b/catalog-info.yaml deleted file mode 100644 index e191914..0000000 --- a/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: vdct2template - title: vdct2template - description: Converts EPICS vdct templates to pure msi compatible EPICS db templates -spec: - type: documentation - lifecycle: experimental - owner: group:default/sscc \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index e9bb15d..22ed684 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=64", "setuptools_scm[toml]>=6.2"] +requires = ["setuptools>=64", "setuptools_scm[toml]>=8"] build-backend = "setuptools.build_meta" [project] @@ -7,18 +7,16 @@ name = "vdct2template" classifiers = [ "Development Status :: 3 - Alpha", "License :: OSI Approved :: Apache Software License", - "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", + "Programming Language :: Python :: 3.12", ] description = "Converts EPICS vdct templates to pure msi compatible EPICS db templates" dependencies = ["typer", "ruamel.yaml", "jinja2"] dynamic = ["version"] license.file = "LICENSE" readme = "README.md" -requires-python = ">=3.7" +requires-python = ">=3.10" [project.optional-dependencies] dev = [ @@ -45,9 +43,10 @@ name = "Giles Knap" [tool.setuptools_scm] -write_to = "src/vdct2template/_version.py" +version_file = "src/vdct2template/_version.py" [tool.pyright] +typeCheckingMode = "standard" reportMissingImports = false # Ignore missing stubs in imported modules [tool.pytest.ini_options] @@ -93,11 +92,18 @@ src = ["src", "tests"] ignore = ["B008"] line-length = 88 lint.select = [ - "B", # flake8-bugbear - https://docs.astral.sh/ruff/rules/#flake8-bugbear-b - "C4", # flake8-comprehensions - https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 - "E", # pycodestyle errors - https://docs.astral.sh/ruff/rules/#error-e - "F", # pyflakes rules - https://docs.astral.sh/ruff/rules/#pyflakes-f - "W", # pycodestyle warnings - https://docs.astral.sh/ruff/rules/#warning-w - "I", # isort - https://docs.astral.sh/ruff/rules/#isort-i - "UP", # pyupgrade - https://docs.astral.sh/ruff/rules/#pyupgrade-up + "B", # flake8-bugbear - https://docs.astral.sh/ruff/rules/#flake8-bugbear-b + "C4", # flake8-comprehensions - https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 + "E", # pycodestyle errors - https://docs.astral.sh/ruff/rules/#error-e + "F", # pyflakes rules - https://docs.astral.sh/ruff/rules/#pyflakes-f + "W", # pycodestyle warnings - https://docs.astral.sh/ruff/rules/#warning-w + "I", # isort - https://docs.astral.sh/ruff/rules/#isort-i + "UP", # pyupgrade - https://docs.astral.sh/ruff/rules/#pyupgrade-up + "SLF", # self - https://docs.astral.sh/ruff/settings/#lintflake8-self ] + +[tool.ruff.lint.per-file-ignores] +# By default, private member access is allowed in tests +# See https://github.com/DiamondLightSource/python-copier-template/issues/154 +# Remove this line to forbid private member access in tests +"tests/**/*" = ["SLF001"] diff --git a/src/vdct2template/__init__.py b/src/vdct2template/__init__.py index 26d23ba..a2ffbf3 100644 --- a/src/vdct2template/__init__.py +++ b/src/vdct2template/__init__.py @@ -1,3 +1,11 @@ +"""Top level API. + +.. data:: __version__ + :type: str + + Version number as calculated by https://github.com/pypa/setuptools_scm +""" + from ._version import __version__ __all__ = ["__version__"] diff --git a/src/vdct2template/__main__.py b/src/vdct2template/__main__.py index 6e1314b..f961a90 100644 --- a/src/vdct2template/__main__.py +++ b/src/vdct2template/__main__.py @@ -1,5 +1,4 @@ from pathlib import Path -from typing import Optional import typer @@ -20,7 +19,7 @@ def version_callback(value: bool): @cli.command() def main( - version: Optional[bool] = typer.Option( + version: bool | None = typer.Option( None, "--version", callback=version_callback, @@ -38,7 +37,7 @@ def main( True, help="Use the builder.py file to look for direct references to template files.", ), - builder: Optional[Path] = typer.Option( + builder: Path | None = typer.Option( None, help="Path to the builder file.", exists=True, diff --git a/src/vdct2template/expansion.py b/src/vdct2template/expansion.py index b046276..e936208 100644 --- a/src/vdct2template/expansion.py +++ b/src/vdct2template/expansion.py @@ -1,5 +1,4 @@ from pathlib import Path -from typing import Dict, List from vdct2template.macros import Macros @@ -14,9 +13,9 @@ class Expansion: """ # class level list of all Expansion instances created - expansions: List["Expansion"] = [] + expansions: list["Expansion"] = [] # class level list of all vdb files processed so far - processed: List[str] = [] + processed: list[str] = [] def __init__(self, filename: Path, folder: Path) -> None: """ @@ -106,7 +105,7 @@ def validate_includes(cls) -> bool: necessary but it is left in for now as a backup check. """ warning = False - index: Dict[str, Macros] = {} + index: dict[str, Macros] = {} print() for expansion in cls.expansions: diff --git a/tests/conftest.py b/tests/conftest.py index d5cdd5f..ebe9c10 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,5 @@ import os +from typing import Any import pytest @@ -7,9 +8,14 @@ if os.getenv("PYTEST_RAISE", "0") == "1": @pytest.hookimpl(tryfirst=True) - def pytest_exception_interact(call): - raise call.excinfo.value + def pytest_exception_interact(call: pytest.CallInfo[Any]): + if call.excinfo is not None: + raise call.excinfo.value + else: + raise RuntimeError( + f"{call} has no exception data, an unknown error has occurred" + ) @pytest.hookimpl(tryfirst=True) - def pytest_internalerror(excinfo): + def pytest_internalerror(excinfo: pytest.ExceptionInfo[Any]): raise excinfo.value