From 342ee9af4c2a3f86e7ddc15960903062290ce09f Mon Sep 17 00:00:00 2001 From: John Aziz Date: Sun, 8 Dec 2024 18:51:24 +0000 Subject: [PATCH 01/11] add devcontainer --- .devcontainer/Dockerfile | 5 ++++ .devcontainer/devcontainer.json | 39 +++++++++++++++++++++++++++ .devcontainer/setup.sh | 6 +++++ .github/workflows/devcontainer-ci.yml | 28 +++++++++++++++++++ pyproject.toml | 38 ++++++++++++++++++++++++++ 5 files changed, 116 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/setup.sh create mode 100644 .github/workflows/devcontainer-ci.yml create mode 100644 pyproject.toml diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..2c8aaaf --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,5 @@ +ARG IMAGE="python:3.12" +FROM --platform=amd64 mcr.microsoft.com/vscode/devcontainers/${IMAGE} +RUN apt-get update \ + && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y install --no-install-recommends build-essential libssl-dev gdb cmake diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..e574197 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,39 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/python +{ + "name": "Cookie Cutter - Render Engine", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "build": { + "dockerfile": "Dockerfile", + "context": "..", + "args": { + "IMAGE": "python:3.12" + } + }, + "postCreateCommand": ". .devcontainer/setup.sh", + "customizations": { + "vscode": { + "settings": { + "python.formatting.provider": "charliermarsh.ruff", + "python.testing.pytestEnabled": true, + "python.testing.pytestPath": "pytest", + "python.testing.unittestEnabled": false, + "python.editor.formatOnSave": true, + "python.editor.codeActionsOnSave": {"source.fixAll": true}, + "python.testing.pytestArgs": [ + "tests" + ], + ".markdownlint-cli2.ignores": [".gitignore"] + + }, + "extensions": [ + "ms-python.python", + "charliermarsh.ruff", + "github.github-actions", + "github.github", + "yzhang.markdown-all-in-one", + "DavidAnson.vscode-markdownlint" + ] + } + } +} diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh new file mode 100644 index 0000000..c01c0eb --- /dev/null +++ b/.devcontainer/setup.sh @@ -0,0 +1,6 @@ +python -m pip install --user --upgrade pip +python -m pip install --user pip-tools +python -m piptools compile --upgrade -o requirements.txt pyproject.toml +python -m pip install --user -r requirements.txt +python -m pip install -e . +pre-commit install diff --git a/.github/workflows/devcontainer-ci.yml b/.github/workflows/devcontainer-ci.yml new file mode 100644 index 0000000..05f4c7b --- /dev/null +++ b/.github/workflows/devcontainer-ci.yml @@ -0,0 +1,28 @@ +name: Check Dev Container + +on: + push: + branches: [ main ] + paths: + - ".devcontainer/**" + - ".github/workflows/devcontainer-ci.yaml" + pull_request: + branches: [ main ] + paths: + - ".devcontainer/**" + - ".github/workflows/devcontainer-ci.yaml" + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js 20.x + uses: actions/setup-node@v4 + with: + node-version: 20.x + - run: npm install -g @devcontainers/cli + - run: devcontainer build --config ./.devcontainer/devcontainer.json --workspace-folder "$(pwd)" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..d8bbb29 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,38 @@ +[build-system] +requires = ["setuptools", "setuptools_scm", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "render_engine_cookie_cutter" +dynamic = ["version"] +description = "Cookie Cutter template for Render Engine" +readme = "README.md" +requires-python = ">=3.10" +dependencies = [ + "cookiecutter", +] + +[project.optional-dependencies] +dev = [ + "ruff", + "pip-tools" +] + + +[tool.setuptools_scm] +local_scheme = "no-local-version" +# version_scheme = "python-simplified-semver" + +[project.urls] +homepage = "https://github.com/render-engine/render_engine/" +repository = "https://github.com/render-engine/cookiecutter-render-engine-site/" +documentation = "https://render-engine.readthedocs.io/en/latest/" + +[tool.semantic_release] +version_toml = "pyproject.toml:project.version" +branch = "main" + +[tool.ruff] +lint.select = ["E", "F", "I", "UP"] +target-version = "py312" +line-length = 120 From 98c7557eac3b2e8a475f8f205f9f8f74fae0aa1c Mon Sep 17 00:00:00 2001 From: John Aziz Date: Sun, 8 Dec 2024 19:03:20 +0000 Subject: [PATCH 02/11] use requirements txt instead of pyproject --- .devcontainer/setup.sh | 4 +--- pyproject.toml | 38 -------------------------------- requirements-dev.txt | 1 + requirements.in | 1 + requirements.txt | 50 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 53 insertions(+), 41 deletions(-) delete mode 100644 pyproject.toml create mode 100644 requirements-dev.txt create mode 100644 requirements.in create mode 100644 requirements.txt diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh index c01c0eb..132bba0 100644 --- a/.devcontainer/setup.sh +++ b/.devcontainer/setup.sh @@ -1,6 +1,4 @@ python -m pip install --user --upgrade pip python -m pip install --user pip-tools -python -m piptools compile --upgrade -o requirements.txt pyproject.toml +python -m piptools compile --upgrade -o requirements.txt requirements.in python -m pip install --user -r requirements.txt -python -m pip install -e . -pre-commit install diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index d8bbb29..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,38 +0,0 @@ -[build-system] -requires = ["setuptools", "setuptools_scm", "wheel"] -build-backend = "setuptools.build_meta" - -[project] -name = "render_engine_cookie_cutter" -dynamic = ["version"] -description = "Cookie Cutter template for Render Engine" -readme = "README.md" -requires-python = ">=3.10" -dependencies = [ - "cookiecutter", -] - -[project.optional-dependencies] -dev = [ - "ruff", - "pip-tools" -] - - -[tool.setuptools_scm] -local_scheme = "no-local-version" -# version_scheme = "python-simplified-semver" - -[project.urls] -homepage = "https://github.com/render-engine/render_engine/" -repository = "https://github.com/render-engine/cookiecutter-render-engine-site/" -documentation = "https://render-engine.readthedocs.io/en/latest/" - -[tool.semantic_release] -version_toml = "pyproject.toml:project.version" -branch = "main" - -[tool.ruff] -lint.select = ["E", "F", "I", "UP"] -target-version = "py312" -line-length = 120 diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..2c2a9f3 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1 @@ +pip-tools diff --git a/requirements.in b/requirements.in new file mode 100644 index 0000000..6090908 --- /dev/null +++ b/requirements.in @@ -0,0 +1 @@ +cookiecutter \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5ad0c53 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,50 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile --output-file=requirements.txt requirements.in +# +arrow==1.3.0 + # via cookiecutter +binaryornot==0.4.4 + # via cookiecutter +certifi==2024.8.30 + # via requests +chardet==5.2.0 + # via binaryornot +charset-normalizer==3.4.0 + # via requests +click==8.1.7 + # via cookiecutter +cookiecutter==2.6.0 + # via -r requirements.in +idna==3.10 + # via requests +jinja2==3.1.4 + # via cookiecutter +markdown-it-py==3.0.0 + # via rich +markupsafe==3.0.2 + # via jinja2 +mdurl==0.1.2 + # via markdown-it-py +pygments==2.18.0 + # via rich +python-dateutil==2.9.0.post0 + # via arrow +python-slugify==8.0.4 + # via cookiecutter +pyyaml==6.0.2 + # via cookiecutter +requests==2.32.3 + # via cookiecutter +rich==13.9.4 + # via cookiecutter +six==1.17.0 + # via python-dateutil +text-unidecode==1.3 + # via python-slugify +types-python-dateutil==2.9.0.20241206 + # via arrow +urllib3==2.2.3 + # via requests From a57be5cd08c226f093d00fa488643899426994f6 Mon Sep 17 00:00:00 2001 From: John Aziz Date: Sun, 8 Dec 2024 19:10:54 +0000 Subject: [PATCH 03/11] fix github extension name --- .devcontainer/devcontainer.json | 3 +-- requirements.in | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e574197..3864416 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -29,8 +29,7 @@ "extensions": [ "ms-python.python", "charliermarsh.ruff", - "github.github-actions", - "github.github", + "GitHub.vscode-github-actions", "yzhang.markdown-all-in-one", "DavidAnson.vscode-markdownlint" ] diff --git a/requirements.in b/requirements.in index 6090908..c8e988b 100644 --- a/requirements.in +++ b/requirements.in @@ -1 +1 @@ -cookiecutter \ No newline at end of file +cookiecutter From c393f4c4ef714563c3b56d253271e5e262d696e7 Mon Sep 17 00:00:00 2001 From: John Aziz Date: Sun, 8 Dec 2024 20:04:18 +0000 Subject: [PATCH 04/11] automate site generation and testing --- .devcontainer/devcontainer.json | 3 +- .devcontainer/setup.sh | 6 ++- .github/workflows/tests.yml | 28 ++++++++++ requirements-dev.txt | 3 ++ tests/pytest.ini | 4 ++ tests/test_template.py | 92 +++++++++++++++++++++++++++++++++ 6 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/tests.yml create mode 100644 tests/pytest.ini create mode 100644 tests/test_template.py diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3864416..4563925 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -31,7 +31,8 @@ "charliermarsh.ruff", "GitHub.vscode-github-actions", "yzhang.markdown-all-in-one", - "DavidAnson.vscode-markdownlint" + "DavidAnson.vscode-markdownlint", + "ms-vscode.makefile-tools" ] } } diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh index 132bba0..159409f 100644 --- a/.devcontainer/setup.sh +++ b/.devcontainer/setup.sh @@ -1,4 +1,6 @@ python -m pip install --user --upgrade pip -python -m pip install --user pip-tools +python -m venv .venv +source .venv/bin/activate +python -m pip install pip-tools python -m piptools compile --upgrade -o requirements.txt requirements.in -python -m pip install --user -r requirements.txt +python -m pip install -r requirements-dev.txt diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..0e1c9f0 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,28 @@ +name: PyTest +on: + workflow_call: + workflow_dispatch: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + fail-fast: true + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: python -m pip install --upgrade pip -r requirements-dev.txt + - name: Run tests + run: python tests/test_template.py diff --git a/requirements-dev.txt b/requirements-dev.txt index 2c2a9f3..2593c30 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1 +1,4 @@ pip-tools +pytest + +-r requirements.txt diff --git a/tests/pytest.ini b/tests/pytest.ini new file mode 100644 index 0000000..ceb893c --- /dev/null +++ b/tests/pytest.ini @@ -0,0 +1,4 @@ +[pytest] +python_files = test_*.py +python_classes = [A-Z]*Test +python_functions = test_* diff --git a/tests/test_template.py b/tests/test_template.py new file mode 100644 index 0000000..4361a2c --- /dev/null +++ b/tests/test_template.py @@ -0,0 +1,92 @@ +""" Test the Cookiecutter template. + +A template project is created in a temporary directory, the application is +installed into a self-contained venv environment, and the application test +suite is run. + +""" +from cookiecutter.generate import generate_context +from cookiecutter.main import cookiecutter +from pathlib import Path +from shlex import split +from subprocess import run +from venv import create + +import pytest + + +@pytest.fixture(scope="session") +def template() -> Path: + """ The template under test. + + """ + return Path(__file__).resolve().parents[1] + + +@pytest.fixture(scope="module") +def tmpdir(tmp_path_factory) -> Path: + """ Test directory. + + """ + return tmp_path_factory.mktemp("test_template") + + +@pytest.fixture(scope="module") +def context(template) -> dict: + """ Template context for testing. + + """ + context = generate_context(template.joinpath("cookiecutter.json")) + context["cookiecutter"].update({ + "project_slug": "slugify" + }) + return context["cookiecutter"] + + +@pytest.fixture(scope="module") +def project(tmpdir, template, context) -> Path: + """ Create a test project from the Cookiecutter template. + + """ + cookiecutter(str(template), no_input=True, output_dir=tmpdir, extra_context=context) + return tmpdir / context["project_slug"] + + +@pytest.fixture +def python(tmp_path): + """ Create a Python virtual environment for testing. + + """ + venv = tmp_path / ".venv" + create(venv, with_pip=True) + return venv / "bin" / "python" + + +def test_project(project): + """ Verify that the project was created correctly. + + """ + # Just a basic sanity test. + assert len(list(project.iterdir())) == 4 + return + + +@pytest.fixture +def install_render_engine_cli(python): + install_cli = "pip install render_engine[cli]" + install_args = split(f"{python} -m {install_cli}") + install_process = run(install_args) + assert install_process.returncode == 0 + + +def test_site_generation(context, project, python, install_render_engine_cli): + generate_site = "render-engine build app:app" + generate_args = split(generate_site) + generate_process = run(generate_args, cwd=project) + assert generate_process.returncode == 0 + + +# Make the script executable. + +if __name__ == "__main__": + raise SystemExit(pytest.main([__file__])) \ No newline at end of file From b6240e903b9b20cfb2f077ed6edecded91c82cd0 Mon Sep 17 00:00:00 2001 From: John Aziz Date: Sun, 8 Dec 2024 20:13:28 +0000 Subject: [PATCH 05/11] fix ci --- tests/test_template.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/test_template.py b/tests/test_template.py index 4361a2c..33ea7ac 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -1,9 +1,5 @@ -""" Test the Cookiecutter template. - -A template project is created in a temporary directory, the application is -installed into a self-contained venv environment, and the application test -suite is run. - +""" +Test the Cookiecutter template. """ from cookiecutter.generate import generate_context from cookiecutter.main import cookiecutter @@ -80,8 +76,8 @@ def install_render_engine_cli(python): def test_site_generation(context, project, python, install_render_engine_cli): - generate_site = "render-engine build app:app" - generate_args = split(generate_site) + generate_site = "render_engine build app:app" + generate_args = split(f"{python} -m {generate_site}") generate_process = run(generate_args, cwd=project) assert generate_process.returncode == 0 @@ -89,4 +85,4 @@ def test_site_generation(context, project, python, install_render_engine_cli): # Make the script executable. if __name__ == "__main__": - raise SystemExit(pytest.main([__file__])) \ No newline at end of file + raise SystemExit(pytest.main([__file__])) From 817b525b117a5d85250d64e091cb28979bca9293 Mon Sep 17 00:00:00 2001 From: John Aziz Date: Sun, 8 Dec 2024 20:18:15 +0000 Subject: [PATCH 06/11] remove python3.9 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0e1c9f0..92c1913 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.10", "3.11", "3.12"] fail-fast: true steps: - uses: actions/checkout@v4 From 000b0c8e8f2b09a11a8d261479fed3fb1e570064 Mon Sep 17 00:00:00 2001 From: John Aziz Date: Mon, 9 Dec 2024 19:12:30 +0000 Subject: [PATCH 07/11] test python3.13 --- .devcontainer/Dockerfile | 2 +- .devcontainer/devcontainer.json | 2 +- .github/workflows/tests.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 2c8aaaf..c228663 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE="python:3.12" +ARG IMAGE="python:3.13" FROM --platform=amd64 mcr.microsoft.com/vscode/devcontainers/${IMAGE} RUN apt-get update \ && export DEBIAN_FRONTEND=noninteractive \ diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4563925..177c61a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,7 +7,7 @@ "dockerfile": "Dockerfile", "context": "..", "args": { - "IMAGE": "python:3.12" + "IMAGE": "python:3.13" } }, "postCreateCommand": ". .devcontainer/setup.sh", diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 92c1913..b49aba2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12"] + python-version: ["3.10", "3.11", "3.12", "3.13"] fail-fast: true steps: - uses: actions/checkout@v4 From f29d70186f280fadb8b509db44386b6d981782af Mon Sep 17 00:00:00 2001 From: John Aziz Date: Mon, 9 Dec 2024 19:16:16 +0000 Subject: [PATCH 08/11] add correct image for codespaces --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index c228663..da6aa78 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ ARG IMAGE="python:3.13" -FROM --platform=amd64 mcr.microsoft.com/vscode/devcontainers/${IMAGE} +FROM --platform=amd64 mcr.microsoft.com/devcontainers/${IMAGE} RUN apt-get update \ && export DEBIAN_FRONTEND=noninteractive \ && apt-get -y install --no-install-recommends build-essential libssl-dev gdb cmake From 25a0299a4c01a7555622dc5e09d0488e646362c6 Mon Sep 17 00:00:00 2001 From: John Aziz Date: Mon, 9 Dec 2024 19:17:46 +0000 Subject: [PATCH 09/11] add correct image for codespaces --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index da6aa78..c228663 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ ARG IMAGE="python:3.13" -FROM --platform=amd64 mcr.microsoft.com/devcontainers/${IMAGE} +FROM --platform=amd64 mcr.microsoft.com/vscode/devcontainers/${IMAGE} RUN apt-get update \ && export DEBIAN_FRONTEND=noninteractive \ && apt-get -y install --no-install-recommends build-essential libssl-dev gdb cmake From 09afa2b06e89d123827778b450a3e25ecd49e71c Mon Sep 17 00:00:00 2001 From: John Aziz Date: Mon, 9 Dec 2024 19:21:28 +0000 Subject: [PATCH 10/11] add correct image for codespaces --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index c228663..da6aa78 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ ARG IMAGE="python:3.13" -FROM --platform=amd64 mcr.microsoft.com/vscode/devcontainers/${IMAGE} +FROM --platform=amd64 mcr.microsoft.com/devcontainers/${IMAGE} RUN apt-get update \ && export DEBIAN_FRONTEND=noninteractive \ && apt-get -y install --no-install-recommends build-essential libssl-dev gdb cmake From 1055f1e9d94d7131ae3a593558d38c8554d34e98 Mon Sep 17 00:00:00 2001 From: John Aziz Date: Mon, 9 Dec 2024 19:25:07 +0000 Subject: [PATCH 11/11] revert back to 3.12 --- .devcontainer/Dockerfile | 2 +- .devcontainer/devcontainer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index da6aa78..9a34a3e 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE="python:3.13" +ARG IMAGE="python:3.12" FROM --platform=amd64 mcr.microsoft.com/devcontainers/${IMAGE} RUN apt-get update \ && export DEBIAN_FRONTEND=noninteractive \ diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 177c61a..4563925 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,7 +7,7 @@ "dockerfile": "Dockerfile", "context": "..", "args": { - "IMAGE": "python:3.13" + "IMAGE": "python:3.12" } }, "postCreateCommand": ". .devcontainer/setup.sh",