Skip to content

Commit

Permalink
Add devcontainer specifications to cookiecutter-poetry and child proj…
Browse files Browse the repository at this point in the history
…ects (#95)

* Added dev container specification
* Added pytest and pre-commit to devcontainer
* Made devcontainer optional
* Add documentation
* Switched to poetry pre-commit
* Additional tests, Moved vscode settings
* Removed initialization code
  • Loading branch information
kenibrewer authored Oct 19, 2023
1 parent f853ca3 commit 9c49026
Show file tree
Hide file tree
Showing 15 changed files with 126 additions and 3 deletions.
32 changes: 32 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// 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": "Cookiecutter Poetry",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye",
"features": {
"ghcr.io/devcontainers-contrib/features/cookiecutter:2": {},
"ghcr.io/devcontainers-contrib/features/poetry:2": {}
},

// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "./.devcontainer/postCreateCommand.sh",

// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"ms-python.python"
],
"settings": {
"python.testing.pytestArgs": [
"tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.defaultInterpreterPath": "/workspaces/cookiecutter-poetry/.venv/bin/python",
"python.testing.pytestPath": "/workspaces/cookiecutter-poetry/.venv/bin/pytest"
}
}
}
}
7 changes: 7 additions & 0 deletions .devcontainer/postCreateCommand.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#! /usr/bin/env bash

# Install Dependencies
poetry install --with dev

# Install pre-commit hooks
poetry run pre-commit install --install-hooks
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ cookiecutter-poetry-example

# From https://raw.githubusercontent.com/github/gitignore/main/Python.gitignore

Byte-compiled / optimized / DLL files
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
Expand Down Expand Up @@ -165,7 +165,7 @@ cython_debug/
#.idea/

# Exclude vscode config files
.vscode
.vscode/

# Exclude .DS_Store files from being added
.DS_Store
1 change: 1 addition & 0 deletions cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
"mkdocs": ["y", "n"],
"codecov" : ["y","n"],
"dockerfile" : ["y","n"],
"devcontainer" : ["y","n"],
"open_source_license": ["MIT license", "BSD license", "ISC license", "Apache Software License 2.0", "GNU General Public License v3", "Not open source"]
}
9 changes: 9 additions & 0 deletions docs/features/devcontainer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Reproducible development environments with VSCode devcontainers

If `devcontainer` is set to `"y"` project uses the VSCode [devcontainer](https://code.visualstudio.com/docs/devcontainers/containers)
specification to create a reproducible development environment. The devcontainer
is defined in the `.devcontainer` directory and pre-installs all dependencies
from poetry required to develop, test and build the project.

The devcontainer also installs the pre-commit hooks and configures the VSCode python
extension to use the appropriate python interpretor and pytest paths.
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ This is a modern Cookiecutter template that can be used to initiate a Python pro
- Documentation with [MkDocs](https://www.mkdocs.org/)
- Compatibility testing for multiple versions of Python with [Tox](https://tox.wiki/en/latest/)
- Containerization with [Docker](https://www.docker.com/)
- Development environment with [VSCode devcontainers](https://code.visualstudio.com/docs/remote/containers)

An example of a repository generated with this package can be found [here](https://github.com/fpgmaas/cookiecutter-poetry-example).

Expand Down
4 changes: 4 additions & 0 deletions docs/prompt_arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ will be deployed to the `gh-pages` branch.

`"y"` or `"n"`. Adds a simple [Dockerfile](https://docker.com).

**devcontainer**

`"y"` or `"n"`. Adds a [devcontainer](https://code.visualstudio.com/docs/devcontainers/containers) specification to the project along with pre-installed pre-commit hooks and VSCode python extension configuration.

**open_source_license**

Choose a [license](https://choosealicense.com/). Options:
Expand Down
3 changes: 3 additions & 0 deletions hooks/post_gen_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ def remove_dir(filepath: str) -> None:
remove_file("codecov.yaml")
if "{{cookiecutter.include_github_actions}}" == "y":
remove_file(".github/workflows/validate-codecov-config.yml")

if "{{cookiecutter.devcontainer}}" != "y":
remove_dir(".devcontainer")
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ nav:
- Documentation with MkDocs: features/mkdocs.md
- Compatibility testing with Tox: features/tox.md
- Containerization with Docker: features/docker.md
- Devcontainer with VSCode: features/devcontainer.md
- Tutorial: tutorial.md
- Prompt Arguments: prompt_arguments.md
plugins:
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ preview = true
[tool.poetry.scripts]
ccp = 'cookiecutter_poetry.cli:main'

[tool.pytest.ini_options]
testpaths = ["tests"]

[tool.coverage.report]
skip_empty = true

Expand Down
18 changes: 18 additions & 0 deletions tests/test_cookiecutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,24 @@ def test_using_pytest(cookies, tmp_path):
assert subprocess.check_call(shlex.split("poetry run make test")) == 0


def test_devcontainer(cookies, tmp_path):
"""Test that the devcontainer files are created when devcontainer=y"""
with run_within_dir(tmp_path):
result = cookies.bake(extra_context={"devcontainer": "y"})
assert result.exit_code == 0
assert os.path.isfile(f"{result.project_path}/.devcontainer/devcontainer.json")
assert os.path.isfile(f"{result.project_path}/.devcontainer/postCreateCommand.sh")


def test_not_devcontainer(cookies, tmp_path):
"""Test that the devcontainer files are not created when devcontainer=n"""
with run_within_dir(tmp_path):
result = cookies.bake(extra_context={"devcontainer": "n"})
assert result.exit_code == 0
assert not os.path.isfile(f"{result.project_path}/.devcontainer/devcontainer.json")
assert not os.path.isfile(f"{result.project_path}/.devcontainer/postCreateCommand.sh")


def test_cicd_contains_artifactory_secrets(cookies, tmp_path):
with run_within_dir(tmp_path):
result = cookies.bake(extra_context={"publish_to": "artifactory"})
Expand Down
31 changes: 31 additions & 0 deletions {{cookiecutter.project_name}}/.devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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": "{{cookiecutter.project_name}}",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye",
"features": {
"ghcr.io/devcontainers-contrib/features/poetry:2": {}
},

// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "./.devcontainer/postCreateCommand.sh",

// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"ms-python.python"
],
"settings": {
"python.testing.pytestArgs": [
"tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.defaultInterpreterPath": "/workspaces/{{cookiecutter.project_name}}/.venv/bin/python",
"python.testing.pytestPath": "/workspaces/{{cookiecutter.project_name}}/.venv/bin/pytest"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#! /usr/bin/env bash

# Install Dependencies
poetry install --with dev

# Install pre-commit hooks
poetry run pre-commit install --install-hooks
5 changes: 4 additions & 1 deletion {{cookiecutter.project_name}}/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ docs/source

# From https://raw.githubusercontent.com/github/gitignore/main/Python.gitignore

Byte-compiled / optimized / DLL files
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
Expand Down Expand Up @@ -156,6 +156,9 @@ dmypy.json
# Cython debug symbols
cython_debug/

# Vscode config files
.vscode/

# 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
Expand Down
3 changes: 3 additions & 0 deletions {{cookiecutter.project_name}}/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ warn_return_any = "True"
warn_unused_ignores = "True"
show_error_codes = "True"

[tool.pytest.ini_options]
testpaths = ["tests"]

[tool.ruff]
target-version = "py37"
line-length = 120
Expand Down

0 comments on commit 9c49026

Please sign in to comment.