From 2fc2125ed6db503e12d18c83f09b43078ba4032a Mon Sep 17 00:00:00 2001 From: Hannes Feldt <feldt@astron.nl> Date: Tue, 11 Mar 2025 13:42:56 +0100 Subject: [PATCH] Add pre-commit hook and improve with better linting --- cookiecutter.json | 3 +- docker/ci-runner/Dockerfile | 4 +-- {{cookiecutter.project_slug}}/.dockerignore | 4 +++ {{cookiecutter.project_slug}}/.gitignore | 10 +++++-- {{cookiecutter.project_slug}}/.gitlab-ci.yml | 27 +++++------------ .../.pre-commit-config.yaml | 22 ++++++++++++++ .../bin/install-hooks/pre-commit.sh | 8 +++++ .../docker/ci-runner/Dockerfile | 2 +- .../{{cookiecutter.project_slug}}/Dockerfile | 18 ++++++++++++ {{cookiecutter.project_slug}}/docs/cleanup.py | 23 +++++++++++++++ {{cookiecutter.project_slug}}/docs/cleanup.sh | 14 --------- {{cookiecutter.project_slug}}/pyproject.toml | 29 +++++++++---------- .../tests/requirements.txt | 6 ---- .../tests/test_cool_module.py | 3 ++ 14 files changed, 112 insertions(+), 61 deletions(-) create mode 100644 {{cookiecutter.project_slug}}/.dockerignore create mode 100644 {{cookiecutter.project_slug}}/.pre-commit-config.yaml create mode 100755 {{cookiecutter.project_slug}}/bin/install-hooks/pre-commit.sh create mode 100644 {{cookiecutter.project_slug}}/docker/{{cookiecutter.project_slug}}/Dockerfile create mode 100644 {{cookiecutter.project_slug}}/docs/cleanup.py delete mode 100644 {{cookiecutter.project_slug}}/docs/cleanup.sh diff --git a/cookiecutter.json b/cookiecutter.json index 1f29d35..8165b97 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -1,6 +1,7 @@ { "project_name": "My Awesome App", "project_slug": "{{ cookiecutter.project_name.lower()|replace(' ', '_')|replace('-', '_')|replace('.', '_')|trim() }}", - "project_url": "https://git.astron.nl/{{cookiecutter.project_slug}}", + "project_package": "{{ cookiecutter.project_name.lower()|replace(' ', '-')|replace('_', '-')|replace('.', '-')|trim() }}", + "project_url": "https://git.astron.nl/{{ cookiecutter.project_slug }}", "description": "An example package for CI/CD working group" } diff --git a/docker/ci-runner/Dockerfile b/docker/ci-runner/Dockerfile index 8b96217..497b89a 100644 --- a/docker/ci-runner/Dockerfile +++ b/docker/ci-runner/Dockerfile @@ -1,5 +1,5 @@ -FROM python:3.11 +FROM python:3.12 RUN python -m pip install --upgrade pip -RUN pip install --upgrade cookiecutter tox twine cibuildwheel==2.13.1 cookiecutter +RUN python -m pip install --upgrade cookiecutter tox twine cibuildwheel==2.13.1 cookiecutter RUN curl -sSL https://get.docker.com/ | sh diff --git a/{{cookiecutter.project_slug}}/.dockerignore b/{{cookiecutter.project_slug}}/.dockerignore new file mode 100644 index 0000000..141f90d --- /dev/null +++ b/{{cookiecutter.project_slug}}/.dockerignore @@ -0,0 +1,4 @@ +.tox +build +*.egg-info +.venv diff --git a/{{cookiecutter.project_slug}}/.gitignore b/{{cookiecutter.project_slug}}/.gitignore index 5513c1b..885470b 100644 --- a/{{cookiecutter.project_slug}}/.gitignore +++ b/{{cookiecutter.project_slug}}/.gitignore @@ -1,13 +1,19 @@ dist/* *.egg-info *.pyc +.tox +.venv .coverage coverage.xml htmlcov/* +build +dist -# Tox -.tox +# Documentation +docs/source/source_documentation +!docs/source/source_documentation/index.rst +docs/build # setuptools-scm src/{{cookiecutter.project_slug}}/_version.py diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml index 4294826..5071e25 100644 --- a/{{cookiecutter.project_slug}}/.gitlab-ci.yml +++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml @@ -14,6 +14,7 @@ stages: - lint - test - package + - images - integration - publish # publish instead of deploy @@ -35,22 +36,10 @@ trigger_prepare: strategy: depend include: .prepare.gitlab-ci.yml -run_black: +run_lint: stage: lint script: - - tox -e black - allow_failure: true - -run_flake8: - stage: lint - script: - - tox -e pep8 - allow_failure: true - -run_pylint: - stage: lint - script: - - tox -e pylint + - tox -e lint allow_failure: true sast: @@ -74,7 +63,7 @@ secret_detection: before_script: - python --version # For debugging - python -m pip install --upgrade pip - - pip install --upgrade tox twine + - python -m pip install --upgrade tox twine # Run all unit tests for Python versions except the base image run_unit_tests: @@ -156,8 +145,7 @@ publish_on_test_pypi: - package_files when: manual rules: - - if: $CI_COMMIT_TAG - allow_failure: true + - if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"' script: - echo "run twine for test pypi" # - | @@ -175,8 +163,7 @@ publish_on_pypi: - package_files when: manual rules: - - if: $CI_COMMIT_TAG - allow_failure: true + - if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"' script: - echo "run twine for pypi" # - | @@ -195,7 +182,7 @@ publish_to_readthedocs: - package_docs when: manual rules: - - if: $CI_COMMIT_TAG + - if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"' script: - echo "scp docs/* ???" - exit 1 diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml new file mode 100644 index 0000000..ce46e64 --- /dev/null +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -0,0 +1,22 @@ +default_stages: [ pre-commit, pre-push ] +default_language_version: + python: python3 +exclude: '^docs/.*\.py$' + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: end-of-file-fixer + - id: trailing-whitespace + - id: check-yaml + - id: check-toml + - id: detect-private-key + - repo: local + hooks: + - id: tox-lint + name: tox-lint (local) + entry: tox + language: python + types: [file, python] + args: ["-e", "lint", "--"] diff --git a/{{cookiecutter.project_slug}}/bin/install-hooks/pre-commit.sh b/{{cookiecutter.project_slug}}/bin/install-hooks/pre-commit.sh new file mode 100755 index 0000000..792a3aa --- /dev/null +++ b/{{cookiecutter.project_slug}}/bin/install-hooks/pre-commit.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +if [ ! -f "setup.sh" ]; then + echo "pre-commit.sh must be executed with repository root as working directory!" + exit 1 +fi + +pre-commit install --hook-type pre-push diff --git a/{{cookiecutter.project_slug}}/docker/ci-runner/Dockerfile b/{{cookiecutter.project_slug}}/docker/ci-runner/Dockerfile index 48d4586..2deb674 100644 --- a/{{cookiecutter.project_slug}}/docker/ci-runner/Dockerfile +++ b/{{cookiecutter.project_slug}}/docker/ci-runner/Dockerfile @@ -1,5 +1,5 @@ FROM python:3.13 RUN python -m pip install --upgrade pip -RUN pip install --upgrade tox twine cibuildwheel==2.13.1 +RUN python -m pip install --upgrade tox twine cibuildwheel==2.13.1 RUN curl -sSL https://get.docker.com/ | sh diff --git a/{{cookiecutter.project_slug}}/docker/{{cookiecutter.project_slug}}/Dockerfile b/{{cookiecutter.project_slug}}/docker/{{cookiecutter.project_slug}}/Dockerfile new file mode 100644 index 0000000..1f7eb27 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker/{{cookiecutter.project_slug}}/Dockerfile @@ -0,0 +1,18 @@ +ARG BUILD_ENV=no_copy + +FROM python:3.13 AS build_no_copy +ADD ../../requirements.txt . +COPY ../.. /work +RUN rm -r /work/dist | true +RUN python -m pip install --user tox +WORKDIR /work +RUN python -m tox -e build + +FROM python:3.13 AS build_copy +COPY dist /work/dist + +FROM build_${BUILD_ENV} AS build + +FROM python:3.13-slim +COPY --from=build /work/dist /dist +RUN python -m pip install /dist/*.whl diff --git a/{{cookiecutter.project_slug}}/docs/cleanup.py b/{{cookiecutter.project_slug}}/docs/cleanup.py new file mode 100644 index 0000000..3a4508d --- /dev/null +++ b/{{cookiecutter.project_slug}}/docs/cleanup.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2023 ASTRON (Netherlands Institute for Radio Astronomy) +# SPDX-License-Identifier: Apache-2.0 + +import os + +file_dir = os.path.dirname(os.path.realpath(__file__)) + +clean_dir = os.path.join(file_dir, "source", "source_documentation") +print(f"Cleaning.. {clean_dir}/*") + +if not os.path.exists(clean_dir): + exit() + +for file_name in os.listdir(clean_dir): + file = os.path.join(clean_dir, file_name) + + if file_name == "index.rst": + continue + + print(f"Removing.. {file}") + os.remove(file) diff --git a/{{cookiecutter.project_slug}}/docs/cleanup.sh b/{{cookiecutter.project_slug}}/docs/cleanup.sh deleted file mode 100644 index aac4cef..0000000 --- a/{{cookiecutter.project_slug}}/docs/cleanup.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -FILE_DIR=$(dirname -- "$(readlink -f -- "${0}")") - -echo "Cleaning.. ${FILE_DIR}/source/source_documentation/*" - -for f in "${FILE_DIR}"/source/source_documentation/* -do - - case $f in - */index.rst) true;; - *) echo "Removing.. ${f}"; rm "${f}";; - esac -done diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index db601f1..3eefe30 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -46,20 +46,19 @@ archs = ["x86_64", "i686"] [tool.cibuildwheel.windows] archs = ["AMD64", "x86"] -[tool.pylint] -ignore = "_version.py" -# This does nothing until the issue below is resolved: -# https://github.com/PyCQA/flake8/issues/234 -[tool.flake8] -max-line-length = 88 -extend-ignore = ["E203"] -exclude = ["_version.py"] +[tool.ruff] +exclude = [ + ".venv", + ".git", + ".tox", + "dist", + "docs", + "*lib/python*", + "*egg", + "_version.py" +] + +[tool.ruff.lint] +ignore = ["E203"] -[tool.black] -line-length = 88 -extend-exclude = ''' -( - _version.py -) -''' diff --git a/{{cookiecutter.project_slug}}/tests/requirements.txt b/{{cookiecutter.project_slug}}/tests/requirements.txt index 82f1ee8..b507faf 100644 --- a/{{cookiecutter.project_slug}}/tests/requirements.txt +++ b/{{cookiecutter.project_slug}}/tests/requirements.txt @@ -1,8 +1,2 @@ -autopep8 >= 1.7.0 # MIT -black >= 22.0.0 # MIT -build >= 0.8.0 # MIT -flake8 >= 5.0.0 # MIT -pyproject-flake8 >= 5.0.4 # Unlicense -pylint >= 2.15.0 # GPLv2 pytest >= 7.0.0 # MIT pytest-cov >= 3.0.0 # MIT diff --git a/{{cookiecutter.project_slug}}/tests/test_cool_module.py b/{{cookiecutter.project_slug}}/tests/test_cool_module.py index 19e5cd2..2cacc8e 100644 --- a/{{cookiecutter.project_slug}}/tests/test_cool_module.py +++ b/{{cookiecutter.project_slug}}/tests/test_cool_module.py @@ -1,3 +1,6 @@ +# Copyright (C) 2025 ASTRON (Netherlands Institute for Radio Astronomy) +# SPDX-License-Identifier: Apache-2.0 + """Testing of the Cool Module""" from unittest import TestCase -- GitLab