Skip to content

Commit

Permalink
Use new interface of pytask (#139)
Browse files Browse the repository at this point in the history
* Python test runs through.
* Use pytask.task instead of pytask.mark.task.
* [pre-commit.ci] pre-commit autoupdate
* Update hooks.
* Codespell complaints.
* More additions to dialogue, citation.
* Adjust docs for v0.7.0.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
hmgaudecker and pre-commit-ci[bot] committed Oct 9, 2023
1 parent 5569b1f commit ea6febf
Show file tree
Hide file tree
Showing 25 changed files with 185 additions and 126 deletions.
9 changes: 6 additions & 3 deletions .pre-commit-config.yaml
Expand Up @@ -59,8 +59,8 @@ repos:
- --wrap-descriptions
- '88'
- --blank
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.289
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.292
hooks:
- id: ruff
# args:
Expand All @@ -76,7 +76,10 @@ repos:
rev: 1.7.0
hooks:
- id: nbqa-black
additional_dependencies: [black==23.9.1]
- id: nbqa-ruff
additional_dependencies: [ruff==v0.0.292]
args: ['--ignore=B018,T201']
- repo: https://github.com/executablebooks/mdformat
rev: 0.7.17
hooks:
Expand All @@ -92,7 +95,7 @@ repos:
args: [--wrap, '88']
files: (docs/.)
- repo: https://github.com/codespell-project/codespell
rev: v2.2.5
rev: v2.2.6
hooks:
- id: codespell
args: [--skip="**.ipynb"]
Expand Down
10 changes: 8 additions & 2 deletions CHANGES.md
@@ -1,6 +1,12 @@
# Release Notes

## v0.6.4 -- March 2023
## v0.7.0 -- October 2023

- Update required pytask to version 0.4 and adjust code accordingly (only Python
example).
- Pre-commit autoupdate / fix ruff complaints.

## v0.6.5 -- March 2023

Incorporate more feedback from EPP students, @janosg:

Expand Down Expand Up @@ -48,7 +54,7 @@ Incorporate feedback from EPP students, @janosg, @tobiasraabe.

- Much improved documentation (@raholler)
- Extensive instructions for use on Windows (@raholler)
- Re-use previously-entered data when cookiecutter fails
- Reuse previously-entered data when cookiecutter fails
(@tobiasraabe, @raholler)
- Fix Stata template by setting <span
class="title-ref">--shell-escape=1</span> (#63, @raholler)
Expand Down
12 changes: 6 additions & 6 deletions cookiecutter.json
Expand Up @@ -24,16 +24,16 @@
"no"
],
"add_r_example": [
"yes",
"no"
"no",
"yes"
],
"add_julia_example": [
"yes",
"no"
"no",
"yes"
],
"add_stata_example": [
"yes",
"no"
"no",
"yes"
],
"add_linters": [
"no",
Expand Down
2 changes: 1 addition & 1 deletion docs/source/background/design_rationale.md
Expand Up @@ -3,7 +3,7 @@ The design of the project templates is guided by the following main thoughts:
1. **Separation of logical chunks:** A minimal requirement for a project to scale.
1. **Only execute required tasks, automatically:** Again required for scalability. It
means that the machine needs to know what is meant by a "required task".
1. **Re-use of code and data instead of copying and pasting:** Else you will forget the
1. **Reuse of code and data instead of copying and pasting:** Else you will forget the
copy & paste step at some point down the road. At best, this leads to errors; at
worst, to misinterpreting the results.
1. **Be as language-agnostic as possible:** Make it easy to use the best tool for a
Expand Down
4 changes: 2 additions & 2 deletions docs/source/conf.py
Expand Up @@ -107,8 +107,8 @@
# |version| and |release|, also used in various other places throughout the
# built documents.
#
release = "0.6.5"
version = "0.6.5"
release = "0.7.0"
version = "0.7.0"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
3 changes: 0 additions & 3 deletions docs/source/development/changes.md

This file was deleted.

3 changes: 0 additions & 3 deletions docs/source/development/index.md
Expand Up @@ -7,6 +7,3 @@
parser: myst_parser.sphinx_
---
```

```{include} changes.md
```
4 changes: 2 additions & 2 deletions docs/source/faq.md
Expand Up @@ -118,7 +118,7 @@ but it is precise...).
Then type:

```bash
$ code ~/.cookiecutter_replay/econ-project-templates-0.6.5.json
$ code ~/.cookiecutter_replay/econ-project-templates-0.7.0.json
```

If you are not using VS Code as your editor of choice, adjust the line accordingly.
Expand All @@ -130,7 +130,7 @@ you have spaces or special characters in your path, you need to adjust your path
When done, launch a new shell if necessary and type:

```bash
$ cookiecutter --replay https://github.com/OpenSourceEconomics/econ-project-templates/archive/v0.6.5.zip
$ cookiecutter --replay https://github.com/OpenSourceEconomics/econ-project-templates/archive/v0.7.0.zip
```

(stata_failure_check_erase_log_file)=
Expand Down
24 changes: 15 additions & 9 deletions docs/source/getting_started/cookiecutter_dialogue.md
@@ -1,11 +1,17 @@
1. If you are on Windows, please open the Windows Powershell. On Mac or Linux, open a
terminal.

Navigate to the parent folder of your future project and type (i.e., copy & paste):
1. Navigate to the parent folder of your future project.

```console
$ cookiecutter https://github.com/OpenSourceEconomics/econ-project-templates/archive/v0.6.5.zip
```
1. If you are using conda environments, make sure that you are in the base
environment before proceeding. If in doubt, type `conda deactivate`, possibly
multiple times.

1. Type (i.e., copy & paste):

```console
cookiecutter https://github.com/OpenSourceEconomics/econ-project-templates/archive/v0.7.0.zip
```

1. The dialogue will move you through the installation. **Make sure to keep this page
side-by-side during the process because if something is invalid, the whole process
Expand Down Expand Up @@ -42,14 +48,14 @@

**version** -- The version of your project.

**python_version** -- The python version, tested with 3.9 - 3.11.
**python_version** -- The python version, min 3.10, tested with 3.10 - 3.11.

**conda_environment_name** -- Name of your conda environment. This should not be too
long, since you need to type it often.
long, since you need to type it often. Typically just the same as *project_slug*.

**create_conda_environment_at_finish** -- Just accept the default. If you don't, the
same caveat applies as for the *project_slug*. If you really do not want a conda
environment, type "x".
**create_conda_environment_at_finish** -- You can do so for convenience, but often it
is useful to add packages to the environment file first so that it will serve your
needs.

**add_python_example** -- Whether to set up the example project in the Python
programming language.
Expand Down
5 changes: 5 additions & 0 deletions docs/source/getting_started/preparing_your_system.md
Expand Up @@ -126,6 +126,11 @@
enable personalized installations. Before you start, install cookiecutter on your
system.

```{warning} If you are using conda environments, make sure that you are in the base
environment before installing cookiecutter (`conda deactivate`, possibly multiple
times). Else you may get a nested environment later on, this can be annoying.
```

```console
$ pip install cookiecutter
```
Expand Down
1 change: 1 addition & 0 deletions docs/source/index.md
Expand Up @@ -58,5 +58,6 @@ guides_explanations/index
programming_languages/index
faq
development/index
release_notes
zreferences
```
7 changes: 7 additions & 0 deletions docs/source/release_notes.md
@@ -0,0 +1,7 @@
# Release Notes

```{include} ../../CHANGES.md
---
start-line: 1
---
```
6 changes: 2 additions & 4 deletions environment.yml
Expand Up @@ -13,16 +13,14 @@ dependencies:
- myst-parser
- nbsphinx
- pandas
- pdbpp
- pip
- plotly>=5.13.0
- pre-commit
- pydata-sphinx-theme>=0.3.0
- pytask>=0.2
- pytest
- pytest-cookies
- pytest-cov
- python
- python=3.11
- setuptools_scm
- sphinx
- sphinx-autoapi
Expand All @@ -31,4 +29,4 @@ dependencies:
- sphinx-panels
- sphinxcontrib-bibtex
- toml
- pip: [kaleido]
- pip: [kaleido, pdbp]
4 changes: 4 additions & 0 deletions hooks/post_gen_project.py
Expand Up @@ -92,6 +92,9 @@ def main() -> None:
conda_exe = shutil.which("conda")

if conda_exe:
print(
"\nStarting to create conda environment, might take a while.",
)
subprocess.run(
(
conda_exe,
Expand All @@ -104,6 +107,7 @@ def main() -> None:
check=True,
capture_output=True,
)
print("Finished creating conda environment.")
else:
warnings.warn(
"conda environment could not be created since no conda or mamba "
Expand Down
53 changes: 36 additions & 17 deletions hooks/pre_gen_project.py
Expand Up @@ -3,46 +3,65 @@

MODULE_REGEX = r"^[_a-zA-Z][_a-zA-Z0-9]*$"
ENVIRON_REGEX = r"^[-_a-zA-Z0-9]*$"
PYTHONVERSION_REGEX = r"^(3)\.(9|10|11)"
PYTHONVERSION_MIN = "3.9"
PYTHON_VERSION_REGEX = r"^(3)\.(11)"
# If bumping this, also bump the version in "test_invalid_python_version"
PYTHON_VERSION_MIN = "3.11"

EXCEPTION_MSG_MODULE_NAME = """
ERROR: The project slug ({module_name}) is not a valid Python module name.

class InvalidModuleNameError(Exception):
"""Raised when the module name is invalid."""

def __init__(self: Exception, module_name: str) -> None:
"""Initialize the exception."""
self.message = f"""
The project slug ({module_name}) is not a valid Python module name.
Please do not use anything other than letters, numbers, and underscores '_'.
The first character must not be a number.
"""
super().__init__(self.message)


class InvalidEnvironmentNameError(Exception):
"""Raised when the environment name is invalid."""

EXCEPTION_MSG_ENVIRON_NAME = """
ERROR: The project slug ({environment_name}) is not a valid conda environment name.
def __init__(self: Exception, environment_name: str) -> None:
"""Initialize the exception."""
self.message = f"""
ERROR: The environment name ({environment_name}) is not a valid conda environment name.
Please do not use anything other than letters, numbers, underscores '_',
and minus signs '-'.
"""
super().__init__(self.message)

EXCEPTION_MSG_PYTHONVERSION = """
ERROR: The python version must be >= {PYTHONVERSION_MIN}, got {pythonversion}.

class InvalidPythonVersionError(Exception):
"""Raised when the Python version not supported."""

def __init__(self: Exception, python_version: str) -> None:
"""Initialize the exception."""
self.message = f"""
ERROR: The python version must be >= {PYTHON_VERSION_MIN}, got {python_version}.
"""
super().__init__(self.message)


def main() -> None:
"""Apply pre-generation hooks."""
module_name = "{{ cookiecutter.project_slug }}"

if not re.match(MODULE_REGEX, module_name):
raise ValueError(EXCEPTION_MSG_MODULE_NAME.format(module_name))
raise InvalidModuleNameError(module_name)

environment_name = "{{ cookiecutter.conda_environment_name }}"

if not re.match(ENVIRON_REGEX, environment_name):
raise ValueError(EXCEPTION_MSG_ENVIRON_NAME.format(environment_name))
raise InvalidEnvironmentNameError(environment_name)

python_version = "{{ cookiecutter.python_version }}"

if not re.match(PYTHONVERSION_REGEX, python_version):
raise ValueError(
EXCEPTION_MSG_PYTHONVERSION.format(PYTHONVERSION_MIN, python_version),
)
if not re.match(PYTHON_VERSION_REGEX, python_version):
raise InvalidPythonVersionError(python_version)


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Expand Up @@ -13,7 +13,7 @@ exclude = [

[tool.ruff.per-file-ignores]
"tests/*" = ["S101", "ANN", "D100", "D103"]
"hooks/post_gen_project.py" = ["C901", "PLR0912"]
"hooks/post_gen_project.py" = ["C901", "PLR0912", "T201"]
"docs/source/conf.py" = ["DTZ005", "D100"]
"docs/source/__init__.py" = ["D104"]
"hooks/__init__.py" = ["D104"]
Expand Down
37 changes: 24 additions & 13 deletions tests/test_cookie.py
Expand Up @@ -8,6 +8,22 @@
conda_exe = _mamba if (_mamba := shutil.which("mamba")) else shutil.which("conda")


def test_invalid_module_name(cookies):
result = cookies.bake(extra_context={"project_slug": "hello-world"})
assert str(result.exception).startswith("Hook script failed")


def test_invalid_environment_name(cookies):
result = cookies.bake(extra_context={"project_slug": "hello-world"})
assert str(result.exception).startswith("Hook script failed")


def test_invalid_python_version(cookies):
result = cookies.bake(extra_context={"python_version": "3.10"})
assert result.exception is not None
assert str(result.exception).startswith("Hook script failed")


@pytest.mark.end_to_end()
def test_bake_project(cookies):
major, minor = sys.version_info[:2]
Expand Down Expand Up @@ -119,19 +135,14 @@ def test_check_conda_environment_creation_for_all_examples_and_run_all_checks(
check=True,
)

# Check linting, but not on the first try since formatters fix stuff.
subprocess.run(
(conda_exe, "run", "-n", env_name, "pre-commit", "run", "--all-files"),
cwd=result.project_path,
check=False,
env={},
)
subprocess.run(
(conda_exe, "run", "-n", env_name, "pre-commit", "run", "--all-files"),
cwd=result.project_path,
check=True,
env={},
)
# Check linting, but not on the first two tries since formatters fix stuff.
for check in False, False, True:
subprocess.run(
(conda_exe, "run", "-n", env_name, "pre-commit", "run", "--all-files"),
cwd=result.project_path,
check=check,
env={},
)

subprocess.run(
(conda_exe, "run", "-n", env_name, "pytask", "-x"),
Expand Down

0 comments on commit ea6febf

Please sign in to comment.