diff --git a/.github/workflows/ci-pip-tools.yml b/.github/workflows/ci-pip-tools.yml new file mode 100644 index 0000000..606556f --- /dev/null +++ b/.github/workflows/ci-pip-tools.yml @@ -0,0 +1,45 @@ +name: Tests (pip-tools) + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + python-version: ["3.12"] + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install cookiecutter + run: pip install cookiecutter + + - name: Create project from template + # Choose default options + run: cookiecutter . --no-input packaging=pip-tools + + - name: Install project dependencies + working-directory: my_project + run: pip install -r dev-requirements.txt + + - name: Run tests + working-directory: my_project + run: pytest + + - name: Run pre-commit hooks for project + working-directory: my_project + run: | + git init + git add . + pre-commit run -a diff --git a/.github/workflows/ci.yml b/.github/workflows/ci-poetry.yml similarity index 93% rename from .github/workflows/ci.yml rename to .github/workflows/ci-poetry.yml index 9107b6c..d7fbff1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci-poetry.yml @@ -1,4 +1,4 @@ -name: Test and build +name: Tests (poetry) on: push: @@ -32,7 +32,7 @@ jobs: - name: Create project from template # Choose default options - run: cookiecutter --no-input . + run: cookiecutter . --no-input packaging=poetry - name: Install project dependencies working-directory: my_project diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4eda0d..b92a083 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,6 +16,7 @@ repos: # Prettier supports many other file formats (e.g., JavaScript, HTML; see # https://prettier.io for list). Add other types here. types_or: [yaml, json] + exclude: "{{ cookiecutter.project_slug }}/.+" - repo: https://github.com/igorshubovych/markdownlint-cli rev: v0.40.0 hooks: diff --git a/cookiecutter.json b/cookiecutter.json index 19b6609..b099fd6 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -4,15 +4,16 @@ "project_description": "[Description for project.]", "author": "Jane Doe", "author_email": "jane_doe@imperial.ac.uk", + "packaging": ["poetry", "pip-tools"], "use_bsd3_licence": false, "add_precommit_workflows": true, - "_copy_without_render": [".github"], "__prompts__": { "project_name": "Enter a human-readable name for the project", "project_slug": "Enter a name for the Python package", "project_description": "Enter a brief description of the project", "author": "Enter your full name", "author_email": "Enter your email address", + "packaging": "Select the Python packaging tool you wish to use", "use_bsd3_licence": "Whether to use Imperial's default open-source licence (BSD 3-clause)", "add_precommit_workflows": "Add Github Actions to run pre-commit hooks (only needed for private repositories)" } diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index c42c741..4ee7107 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -4,6 +4,7 @@ REMOVE_PATHS = [ "{% if not cookiecutter.use_bsd3_licence %}LICENSE{% endif %}", "{% if not cookiecutter.add_precommit_workflows %}.github/workflows/pre-commit*.yml{% endif %}", + "{% if cookiecutter.packaging != 'pip-tools' %}*requirements.txt{% endif %}" ] for path in REMOVE_PATHS: diff --git a/{{ cookiecutter.project_slug }}/.github/workflows/ci.yml b/{{ cookiecutter.project_slug }}/.github/workflows/ci.yml index 41bb432..7e92846 100644 --- a/{{ cookiecutter.project_slug }}/.github/workflows/ci.yml +++ b/{{ cookiecutter.project_slug }}/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: jobs: test: - runs-on: ${{ matrix.os }} + runs-on: ${{ "{{" }}matrix.os{{ "}} "}} strategy: fail-fast: false matrix: @@ -20,8 +20,9 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} + python-version: ${{ "{{" }}matrix.python-version{{ "}} "}} +{% if cookiecutter.packaging == "poetry" %} - name: Install Poetry uses: abatilo/actions-poetry@v3.0.0 with: @@ -32,3 +33,10 @@ jobs: - name: Run tests run: poetry run pytest +{%- elif cookiecutter.packaging == "pip-tools" %} + - name: Install dependencies + run: pip install -r dev-requirements.txt + + - name: Run tests + run: pytest +{%- endif %} diff --git a/{{ cookiecutter.project_slug }}/.github/workflows/pre-commit_autoupdate.yml b/{{ cookiecutter.project_slug }}/.github/workflows/pre-commit_autoupdate.yml index 1b05599..0dd7634 100644 --- a/{{ cookiecutter.project_slug }}/.github/workflows/pre-commit_autoupdate.yml +++ b/{{ cookiecutter.project_slug }}/.github/workflows/pre-commit_autoupdate.yml @@ -13,7 +13,7 @@ jobs: - uses: browniebroke/pre-commit-autoupdate-action@main - uses: peter-evans/create-pull-request@v6 with: - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ "{{" }} secrets.GITHUB_TOKEN {{ "}}" }} branch: update/pre-commit-hooks title: Update pre-commit hooks commit-message: "chore: update pre-commit hooks" diff --git a/{{ cookiecutter.project_slug }}/dev-requirements.txt b/{{ cookiecutter.project_slug }}/dev-requirements.txt new file mode 100644 index 0000000..f85b6be --- /dev/null +++ b/{{ cookiecutter.project_slug }}/dev-requirements.txt @@ -0,0 +1,76 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile --extra=dev --output-file=dev-requirements.txt pyproject.toml +# +attrs==23.2.0 + # via pytest-mypy +build==1.2.1 + # via pip-tools +cfgv==3.4.0 + # via pre-commit +click==8.1.7 + # via pip-tools +coverage[toml]==7.5.0 + # via pytest-cov +distlib==0.3.8 + # via virtualenv +filelock==3.13.1 + # via + # pytest-mypy + # virtualenv +identify==2.5.33 + # via pre-commit +iniconfig==2.0.0 + # via pytest +mypy==1.9.0 + # via + # datahub (pyproject.toml) + # pytest-mypy +mypy-extensions==1.0.0 + # via mypy +nodeenv==1.8.0 + # via pre-commit +packaging==24.0 + # via + # build + # pytest +pip-tools==7.4.0 + # via datahub (pyproject.toml) +platformdirs==4.2.1 + # via virtualenv +pluggy==1.5.0 + # via pytest +pre-commit==3.7.0 + # via datahub (pyproject.toml) +pyproject-hooks==1.0.0 + # via + # build + # pip-tools +pytest==8.1.1 + # via + # datahub (pyproject.toml) + # pytest-cov + # pytest-mock + # pytest-mypy +pytest-cov==4.1.0 + # via datahub (pyproject.toml) +pytest-mock==3.12.0 + # via datahub (pyproject.toml) +pytest-mypy==0.10.3 + # via datahub (pyproject.toml) +pyyaml==6.0.1 + # via pre-commit +ruff==0.3.0 + # via datahub (pyproject.toml) +typing-extensions==4.9.0 + # via mypy +virtualenv==20.26.1 + # via pre-commit +wheel==0.43.0 + # via pip-tools + +# The following packages are considered to be unsafe in a requirements file: +# pip +# setuptools diff --git a/{{ cookiecutter.project_slug }}/pyproject.toml b/{{ cookiecutter.project_slug }}/pyproject.toml index f5128b3..427f01f 100644 --- a/{{ cookiecutter.project_slug }}/pyproject.toml +++ b/{{ cookiecutter.project_slug }}/pyproject.toml @@ -1,3 +1,4 @@ +{%- if cookiecutter.packaging == "poetry" -%} [tool.poetry] name = "{{ cookiecutter.project_slug }}" version = "0.1.0" @@ -17,6 +18,41 @@ pytest-mypy = "^0.10.0" pytest-mock = "^3.7.0" pre-commit = "^3.0.4" +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" +{%- elif cookiecutter.packaging == "pip-tools" -%} +[project] +name = "{{ cookiecutter.project_slug }}" +version = "0.1.0" +description = "{{ cookiecutter.project_description }}" +authors = [ + { name = "{{ cookiecutter.author }}", email = "{{ cookiecutter.author_email }}" }, + { name = "Imperial College London RSE Team", email = "ict-rse-team@imperial.ac.uk" } +] +requires-python = ">=3.12" +dependencies = [] + +[project.optional-dependencies] +dev = [ + "ruff", + "mypy", + "pip-tools", + "pre-commit", + "pytest", + "pytest-cov", + "pytest-mypy", + "pytest-mock" +] + +[build-system] +requires = ["setuptools", "setuptools-scm"] +build-backend = "setuptools.build_meta" + +[tool.setuptools.packages.find] +exclude = ["htmlcov"] # Exclude the coverage report file from setuptools package finder +{%- endif %} + [tool.mypy] disallow_any_explicit = true disallow_any_generics = true @@ -32,10 +68,6 @@ disallow_untyped_defs = false [tool.pytest.ini_options] addopts = "-v --mypy -p no:warnings --cov={{ cookiecutter.project_slug }} --cov-report=html --doctest-modules --ignore={{ cookiecutter.project_slug }}/__main__.py" -[build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" - [tool.ruff] target-version = "py312" diff --git a/{{ cookiecutter.project_slug }}/requirements.txt b/{{ cookiecutter.project_slug }}/requirements.txt new file mode 100644 index 0000000..f8538a1 --- /dev/null +++ b/{{ cookiecutter.project_slug }}/requirements.txt @@ -0,0 +1,6 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile +#