From 6d2469be9b9eb7f14b144b3ea15654d21a56485a Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Thu, 21 Sep 2023 15:08:40 +0200 Subject: [PATCH 01/15] ops(ci): fix submodule clone issue in ci use relative path for submodule this only works on git01 anyway --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 97c0f19f..fa3d1988 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "template/{% if docs_template == 'sphinx-fhg-iis' %}docs{% endif %}"] path = "template/{% if docs_template == 'sphinx-fhg-iis' %}docs{% endif %}" - url = https://git01.iis.fhg.de/mkj/sphinx_template + url = ../../sphinx_template From ade0374d97d9d7aea609795fd551685ecc9136f6 Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Thu, 21 Sep 2023 15:12:12 +0200 Subject: [PATCH 02/15] ops(ci): clone submodules recursively --- .gitlab-ci.yml | 1 + .gitmodules | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7af66af9..e6acb700 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,6 +2,7 @@ image: python variables: GIT_DEPTH: 0 + GIT_SUBMODULE_STRATEGY: recursive # build_example: # stage: build diff --git a/.gitmodules b/.gitmodules index fa3d1988..60eebc28 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "template/{% if docs_template == 'sphinx-fhg-iis' %}docs{% endif %}"] path = "template/{% if docs_template == 'sphinx-fhg-iis' %}docs{% endif %}" - url = ../../sphinx_template + url = ../sphinx_template From 129f7702222ca5b74aa1f8670693c9ac2dcb2ef4 Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Thu, 21 Sep 2023 16:19:19 +0200 Subject: [PATCH 03/15] fix(template): include all template files --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index 02787bcc..7f549aae 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,4 @@ prune template prune */__pycache__ exclude copier.yaml +graft src/init_python_project/template From 6755ef11b707c8097bf918648038d02e31f374c2 Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Fri, 22 Sep 2023 07:38:28 +0200 Subject: [PATCH 04/15] rename precommit and bumpversion variables without the `use`, the cli will automatically use nice flag values (--precommit, --no-precommit) instead of something clunky (--use-precommit, --no-use-precommit). --- Makefile | 4 ++-- copier.yaml | 6 +++--- template/pyproject.toml.jinja | 2 +- ...ersion %}.bumpversion.cfg{% endif %}.jinja} | 0 ...%}.pre-commit-config.yaml{% endif %}.jinja} | 0 tests/test_template.py | 18 +++++++++--------- 6 files changed, 15 insertions(+), 15 deletions(-) rename template/{{% if use_bumpversion %}.bumpversion.cfg{% endif %}.jinja => {% if bumpversion %}.bumpversion.cfg{% endif %}.jinja} (100%) rename template/{{% if use_precommit %}.pre-commit-config.yaml{% endif %}.jinja => {% if precommit %}.pre-commit-config.yaml{% endif %}.jinja} (100%) diff --git a/Makefile b/Makefile index 81055624..eb20c743 100644 --- a/Makefile +++ b/Makefile @@ -28,8 +28,8 @@ $(PUBLISHED_EXAMPLES): docs/examples/mkdocs: COPIER_DEFAULT_VALUES+=-d docs=mkdocs docs/examples/sphinx: COPIER_DEFAULT_VALUES+=-d docs=sphinx -docs/examples/minimal: COPIER_DEFAULT_VALUES+=-d docs=none -d use_precommit=False -d use_bumpversion=False -docs/examples/full: COPIER_DEFAULT_VALUES+=-d docs=mkdocs -d use_precommit=True -d use_bumpversion=True +docs/examples/minimal: COPIER_DEFAULT_VALUES+=-d docs=none -d precommit=False -d bumpversion=False +docs/examples/full: COPIER_DEFAULT_VALUES+=-d docs=mkdocs -d precommit=True -d bumpversion=True docs/examples/gitlab: COPIER_DEFAULT_VALUES+=-d remote=gitlab-iis $(DOC_EXAMPLES): diff --git a/copier.yaml b/copier.yaml index bb0ba671..3def6910 100644 --- a/copier.yaml +++ b/copier.yaml @@ -51,7 +51,7 @@ package_name: Finally, the package name is repeated across multiple configuration and documentation files. -use_precommit: +precommit: type: bool default: true help: Use pre-commit to run checks on each commit? @@ -64,7 +64,7 @@ use_precommit: Most formatters and some linters are able to fix issues automatically. So you can simply review the changes those tools made, stage them and commit again. -use_bumpversion: +bumpversion: type: bool default: false help: Use bumpversion to manage semantic version across multiple files? @@ -178,4 +178,4 @@ _tasks: - "rm -rf context" - "git init --initial-branch={{default_branch}}" - "git remote add origin {{remote_url}} || true" - - "{% if use_precommit %}pre-commit install || echo 'Error during installation of pre-commit hooks. Is pre-commit installed?'{% endif %}" + - "{% if precommit %}pre-commit install || echo 'Error during installation of pre-commit hooks. Is pre-commit installed?'{% endif %}" diff --git a/template/pyproject.toml.jinja b/template/pyproject.toml.jinja index bfa8c0c8..fa53c5d4 100644 --- a/template/pyproject.toml.jinja +++ b/template/pyproject.toml.jinja @@ -70,7 +70,7 @@ dependencies = ["click"] # Similar to `dependencies` above, these must be valid existing # projects. [project.optional-dependencies] -dev = ["black", "radon", "ruff"{% if use_bumpversion %}, "bump2version"{% endif %}] +dev = ["black", "radon", "ruff"{% if bumpversion %}, "bump2version"{% endif %}] test = ["pytest", "pytest-cov", "coverage[toml]"] # The following would provide a command line executable which executes diff --git a/template/{% if use_bumpversion %}.bumpversion.cfg{% endif %}.jinja b/template/{% if bumpversion %}.bumpversion.cfg{% endif %}.jinja similarity index 100% rename from template/{% if use_bumpversion %}.bumpversion.cfg{% endif %}.jinja rename to template/{% if bumpversion %}.bumpversion.cfg{% endif %}.jinja diff --git a/template/{% if use_precommit %}.pre-commit-config.yaml{% endif %}.jinja b/template/{% if precommit %}.pre-commit-config.yaml{% endif %}.jinja similarity index 100% rename from template/{% if use_precommit %}.pre-commit-config.yaml{% endif %}.jinja rename to template/{% if precommit %}.pre-commit-config.yaml{% endif %}.jinja diff --git a/tests/test_template.py b/tests/test_template.py index 0bbe7134..5f54bbe7 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -39,7 +39,7 @@ def venv(tmp_path): @pytest.mark.slow -@pytest.mark.parametrize("use_precommit", [True, False], ids=["pre-commit", "no pre-commit"]) +@pytest.mark.parametrize("precommit", [True, False], ids=["pre-commit", "no pre-commit"]) @pytest.mark.parametrize( "docs,docs_template", SUPPORTED_DOCS_TEMPLATES_COMBINATIONS, @@ -48,7 +48,7 @@ def venv(tmp_path): def test_template_generation( venv: VirtualEnvironment, tmp_path: Path, - use_precommit: bool, + precommit: bool, docs: str, docs_template: str, remote: str, @@ -59,7 +59,7 @@ def test_template_generation( str(tmp_path), data=dict( **required_static_data, - use_precommit=use_precommit, + precommit=precommit, docs=docs, docs_template=docs_template, remote=remote, @@ -81,7 +81,7 @@ def test_template_generation( assert fp_changelog.is_file(), "new projects should have a CHANGELOG file" fp_precommit_config = tmp_path / ".pre-commit-config.yaml" - assert fp_precommit_config.is_file() == use_precommit + assert fp_precommit_config.is_file() == precommit fp_git = tmp_path / ".git" assert fp_git.is_dir(), "new projects should be git repositories" @@ -318,21 +318,21 @@ def read_last_commit_msg(cwd: Path | str = None): return check_output(["git", "log", "-1", "--pretty=%B"], cwd=str(cwd or ".")).decode().strip() -@pytest.mark.parametrize("use_bumpversion", [True, False], ids=["bumpversion", "no bumpversion"]) -def test_bumpversion_option(venv: VirtualEnvironment, tmp_path: Path, use_bumpversion: bool): +@pytest.mark.parametrize("bumpversion", [True, False], ids=["bumpversion", "no-bumpversion"]) +def test_bumpversion_option(venv: VirtualEnvironment, tmp_path: Path, bumpversion: bool): run_copy( str(fp_template), str(tmp_path), data=dict( **required_static_data, - use_bumpversion=use_bumpversion, - use_precommit=False, # makes testing easier + bumpversion=bumpversion, + precommit=False, # makes testing easier ), unsafe=True, defaults=True, vcs_ref="HEAD", ) - if not use_bumpversion: + if not bumpversion: assert not (tmp_path / ".bumpversion.cfg").is_file() return From 65c0824590dd30ee00b752e2faa99a03fa704258 Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Fri, 22 Sep 2023 08:50:57 +0200 Subject: [PATCH 05/15] fix(temp): install doc requirements only when needed --- template/Makefile.jinja | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/template/Makefile.jinja b/template/Makefile.jinja index 64cdbf1f..051ae109 100644 --- a/template/Makefile.jinja +++ b/template/Makefile.jinja @@ -1,7 +1,7 @@ .PHONY: install-dev install-dev: ## install project including all development dependencies - pip install -e .[test,dev] - pip install -r docs/requirements.txt + pip install -e .[test,dev]{% if docs != 'none' %} + pip install -r docs/requirements.txt{% endif %} .PHONY: maintainability maintainability: ## run maintainability checks From fc5f5fa3772991eb16b159b194081628c124f086 Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Fri, 22 Sep 2023 08:56:49 +0200 Subject: [PATCH 06/15] feat(cli): extend cli to generate template in single command --- .vscode/terms.txt | 1 + src/init_python_project/cli.py | 133 ++++++++++++++++++++++++++++++++- 2 files changed, 131 insertions(+), 3 deletions(-) diff --git a/.vscode/terms.txt b/.vscode/terms.txt index ba6c990f..97b077da 100644 --- a/.vscode/terms.txt +++ b/.vscode/terms.txt @@ -30,6 +30,7 @@ pypa pyproject pytest sampleproject +secho sendline setuptools SPHINXBUILD diff --git a/src/init_python_project/cli.py b/src/init_python_project/cli.py index 689e26d1..c7a0dfb1 100644 --- a/src/init_python_project/cli.py +++ b/src/init_python_project/cli.py @@ -1,7 +1,11 @@ +import logging import sys +from enum import StrEnum from pathlib import Path +from subprocess import check_output from typing import Annotated, Optional +import typer from copier import run_copy from typer import Argument, Option, Typer, colors, confirm, style @@ -16,18 +20,122 @@ def version_callback(value: bool) -> None: sys.exit(0) +class DocumentationTool(StrEnum): + "which documentation tool to use" + mkdocs = "mkdocs" + sphinx = "sphinx" + none = "none" + + +class DocumentationTemplate(StrEnum): + "which documentation template to use" + sphinx_fhg_iis = "sphinx-fhg-iis" + builtin = "none" + + +class RemotePlatform(StrEnum): + "which remote platform to configure" + github = "github" + gitlab_fhg = "gitlab-fhg" + gitlab_iis = "gitlab-iis" + + +def CustomOptional(_type=bool, help="", custom_flag: str | list = None, **kwargs): + if issubclass(_type, StrEnum): + kwargs = {"case_sensitive": False, **kwargs} + if not help: + help = _type.__doc__ + + kwargs = {"show_default": False, "help": help, **kwargs} + + if custom_flag is None: + return Annotated[Optional[_type], Option(**kwargs)] + + if isinstance(custom_flag, str): + custom_flag = [custom_flag] + return Annotated[Optional[_type], Option(*custom_flag, **kwargs)] + + @app.command(name="init-python-project") def cli( target_path: Path = Argument("new-project"), + project_name: CustomOptional(str, "project name (title case with spaces)") = None, + package_name: CustomOptional(str, "Python package name (lowercase with underscores)") = None, + user_name: CustomOptional(str, "your user name") = None, + docs: CustomOptional(DocumentationTool) = None, + docs_template: CustomOptional(DocumentationTemplate) = None, + remote: CustomOptional(RemotePlatform) = None, + remote_url: CustomOptional(str, "ssh url where your repository will be hosted on") = None, + precommit: CustomOptional(bool, "include pre-commit hooks") = None, + bumpversion: CustomOptional(bool, "include bumpversion configuration") = None, + defaults: Annotated[ + bool, Option("--defaults", "-d", help="automatically accept all default options") + ] = False, + dry_run: Annotated[bool, Option("--dry-run", help="do not actually create project")] = False, + always_confirm: Annotated[ + bool, Option("--yes", "-y", help="answer any confirmation request with yes") + ] = False, version: Annotated[ - Optional[bool], Option("--version", callback=version_callback, is_eager=True) + Optional[bool], + Option("--version", callback=version_callback, is_eager=True, help="show version and exit"), + ] = None, + verbose: Annotated[ + Optional[bool], + typer.Option( + "--verbose", + "-v", + callback=lambda x: logging.basicConfig( + level=logging.INFO if x else logging.WARN, format="%(message)s" + ), + is_eager=True, + help="show more information", + ), + ] = False, + copier_args: Annotated[ + Optional[list[str]], + typer.Option("--copier-arg", help="anything you want to pass to copier"), ] = None, ) -> None: - """Executes the CLI command to create a new project.""" - target_path.mkdir(exist_ok=True) + """Executes the CLI command to create a new project. + + For a list of supported copier arguments, see + https://copier.readthedocs.io/en/stable/reference/main/#copier.main.Worker. + + Note that `src_path`, `dest_path`, `vcs_ref`, `data`, `defaults`, `user_defaults` and `unsafe` + are already set by this command. Further, `pretend` is set to `True` if `--dry-run` is passed + and `overwrite` is set to `True` if `--yes` is passed. + """ + + if docs_template not in [None, "none"] and ( + docs is None or (docs is not None and not docs_template.value.startswith(docs.value)) + ): + typer.secho( + f"Error: selected template ({docs_template}) not compatible " + f"with documentation tool ({docs})", + fg=colors.RED, + err=True, + ) + raise typer.Exit(1) + + # cast enums to their values + for option in "docs remote".split(): + if locals()[option] is not None: + locals()[option] = locals()[option].value + + # assemble values provided by the user + data = {} + for ( + option + ) in "project_name package_name user_name docs remote remote_url precommit bumpversion".split(): + value = locals()[option] + if value is not None: + logging.info("%s: %s", option, value) + data[option] = value + if ( target_path.is_dir() and any(target_path.iterdir()) + and not always_confirm and not confirm( style( f"Target directory '{target_path}' is not empty! Continue?", @@ -37,10 +145,29 @@ def cli( ): sys.exit(1) + # parse copier args + copier_args = { + k.replace("--", "").replace("-", "_"): v + for k, v in ( + arg.split("=") if "=" in arg else arg.split() if " " in arg else (arg, True) + for arg in (copier_args or []) + ) + } + run_copy( src_path=str(Path(__file__).parent.absolute()), dst_path=target_path, unsafe=True, + data=data, + user_defaults=dict( + user_name=check_output(["whoami"]).decode().strip() if user_name is None else user_name, + project_name=target_path.name.replace("-", " ").replace("_", " ").title(), + ), + defaults=defaults, + overwrite=always_confirm, + pretend=dry_run or copier_args.pop("pretend", False), + quiet=True, + **copier_args, ) From 5ef5288a3422715ade6866556a700a7539fdcc28 Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Fri, 22 Sep 2023 08:58:30 +0200 Subject: [PATCH 07/15] doc: update pipx and copier usage --- docs/user-guide/getting-started.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md index b8678a78..3fe9c4e7 100644 --- a/docs/user-guide/getting-started.md +++ b/docs/user-guide/getting-started.md @@ -1,7 +1,13 @@ {{ includex('README.md', start_match='Prerequisites', end_match='')}} +*Note: If you have [pipx][] installed (you should, it is good), you can simply use `pipx run init-python-project` out of the box.* + +[pipx]: https://pypa.github.io/pipx/ + ## Using [copier] directly +The underlying template is built using [copier]. This means you can also use the copier template directly like this: + ```console copier copy --trust https://git01.iis.fhg.de/mkj/project-template.git my_new_project ``` @@ -10,7 +16,4 @@ copier copy --trust https://git01.iis.fhg.de/mkj/project-template.git my_new_pro [tasks]: https://git01.iis.fhg.de/mkj/project-template/-/blob/main/copier.yaml -*Note: If you have [pipx][] installed (you should, it is good), you can simply use `pipx run copier` out of the box.* - [copier]: https://github.com/copier-org/copier -[pipx]: https://pypa.github.io/pipx/ From 7ed07eccb4455137660ebcc1bb67cc8f304e7db5 Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Fri, 22 Sep 2023 09:00:52 +0200 Subject: [PATCH 08/15] ops(doc): build doc examples using cli fix issue where examples could not be generated as copier had issues cloning the docs_template which is integrated as a submodule. the cli is using the template directly (without re- cloning it) so it exhibit this problem, as long as the template is packaged with the cli together. --- Makefile | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index eb20c743..77f95176 100644 --- a/Makefile +++ b/Makefile @@ -26,16 +26,18 @@ $(PUBLISHED_EXAMPLES): @copier copy ${COPIER_ARGS} ${COPIER_DEFAULT_VALUES} . "$@" $(MAKE) example-setup EXAMPLE_DIR="$@" -docs/examples/mkdocs: COPIER_DEFAULT_VALUES+=-d docs=mkdocs -docs/examples/sphinx: COPIER_DEFAULT_VALUES+=-d docs=sphinx -docs/examples/minimal: COPIER_DEFAULT_VALUES+=-d docs=none -d precommit=False -d bumpversion=False -docs/examples/full: COPIER_DEFAULT_VALUES+=-d docs=mkdocs -d precommit=True -d bumpversion=True -docs/examples/gitlab: COPIER_DEFAULT_VALUES+=-d remote=gitlab-iis - +INIT_PYTHON_PROJECT_ARGS=--project-name="Sample Project" +docs/examples/mkdocs: INIT_PYTHON_PROJECT_ARGS+=--docs mkdocs +docs/examples/sphinx: INIT_PYTHON_PROJECT_ARGS+=--docs sphinx +docs/examples/minimal: INIT_PYTHON_PROJECT_ARGS+=--docs none --no-precommit --no-bumpversion +docs/examples/full: INIT_PYTHON_PROJECT_ARGS+=--docs mkdocs --precommit --bumpversion +docs/examples/gitlab: INIT_PYTHON_PROJECT_ARGS+=--docs mkdocs --precommit --bumpversion --remote gitlab-iis +doc-examples: $(DOC_EXAMPLES) $(DOC_EXAMPLES): + $(MAKE) uncopy-template copy-template @echo "Recreating '$@'..." @rm -rf "$@" && mkdir -p "$@" - @copier copy ${COPIER_ARGS} --defaults -d user_name=mkj ${COPIER_DEFAULT_VALUES} . "$@" + init-python-project "$@" --user-name mkj ${INIT_PYTHON_PROJECT_ARGS} --defaults --yes --verbose @cd $@ &&\ python -m venv .venv || echo "Couldn't setup virtual environment" &&\ . .venv/bin/activate &&\ @@ -124,8 +126,10 @@ install-build: build copy-template: @cp -r ${TEMPLATE_SRC} ${TEMPLATE_DEST} @cp copier.yaml ${PKGDIR}/. -build-clean: ## remove build artifacts - @rm -rf ${BUILDDIR} ${PKGDIR}/template ${PKGDIR}/copier.yaml +uncopy-template: + @rm -rf ${TEMPLATE_DEST} ${PKGDIR}/copier.yaml +build-clean: uncopy-template ## remove build artifacts + @rm -rf ${BUILDDIR} .PHONY: help From 23a86d9251940634a86463090ceef85bf0a45ce4 Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Mon, 25 Sep 2023 07:56:34 +0200 Subject: [PATCH 09/15] ops: use absolute url for submodule again otherwise, copier fails to checkout the submodule on template creation --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 60eebc28..3d1223de 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "template/{% if docs_template == 'sphinx-fhg-iis' %}docs{% endif %}"] path = "template/{% if docs_template == 'sphinx-fhg-iis' %}docs{% endif %}" - url = ../sphinx_template + url = git@git01.iis.fhg.de:mkj/sphinx_template.git From 1be5c68dc79f747135e288a0bb5381bb2086301f Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Mon, 25 Sep 2023 08:01:57 +0200 Subject: [PATCH 10/15] doc: simplify usage section --- docs/user-guide/getting-started.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md index 3fe9c4e7..1d60c933 100644 --- a/docs/user-guide/getting-started.md +++ b/docs/user-guide/getting-started.md @@ -1,19 +1,22 @@ {{ includex('README.md', start_match='Prerequisites', end_match='')}} -*Note: If you have [pipx][] installed (you should, it is good), you can simply use `pipx run init-python-project` out of the box.* +??? note "Using [pipx]" + + ```{.sh .copy} + pipx run init-python-project + ``` [pipx]: https://pypa.github.io/pipx/ -## Using [copier] directly +??? note "Using [copier]" -The underlying template is built using [copier]. This means you can also use the copier template directly like this: + The underlying template is built using [copier]. This means you can also use the copier template directly like this: -```console -copier copy --trust https://git01.iis.fhg.de/mkj/project-template.git my_new_project -``` + ```{.sh .copy} + copier copy --trust https://git01.iis.fhg.de/mkj/project-template.git my_new_project + ``` -*Note: `--trust` is required because the template uses [tasks][] to setup your git repository for you.* + *Note: `--trust` is required because the template uses [tasks] to setup your git repository for you.* [tasks]: https://git01.iis.fhg.de/mkj/project-template/-/blob/main/copier.yaml - [copier]: https://github.com/copier-org/copier From cf6beb645f3fbd18995bcbca5daf5a73fa5525e1 Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Mon, 25 Sep 2023 08:13:11 +0200 Subject: [PATCH 11/15] doc: reword cli docstring --- src/init_python_project/cli.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/init_python_project/cli.py b/src/init_python_project/cli.py index c7a0dfb1..42acfc26 100644 --- a/src/init_python_project/cli.py +++ b/src/init_python_project/cli.py @@ -58,6 +58,7 @@ def CustomOptional(_type=bool, help="", custom_flag: str | list = None, **kwargs @app.command(name="init-python-project") def cli( + # data passed to the underlying copier template target_path: Path = Argument("new-project"), project_name: CustomOptional(str, "project name (title case with spaces)") = None, package_name: CustomOptional(str, "Python package name (lowercase with underscores)") = None, @@ -68,6 +69,7 @@ def cli( remote_url: CustomOptional(str, "ssh url where your repository will be hosted on") = None, precommit: CustomOptional(bool, "include pre-commit hooks") = None, bumpversion: CustomOptional(bool, "include bumpversion configuration") = None, + # arguments that affect project creation defaults: Annotated[ bool, Option("--defaults", "-d", help="automatically accept all default options") ] = False, @@ -102,8 +104,8 @@ def cli( https://copier.readthedocs.io/en/stable/reference/main/#copier.main.Worker. Note that `src_path`, `dest_path`, `vcs_ref`, `data`, `defaults`, `user_defaults` and `unsafe` - are already set by this command. Further, `pretend` is set to `True` if `--dry-run` is passed - and `overwrite` is set to `True` if `--yes` is passed. + are already set by this command. Further, `--dry-run` corresponds to copier's `--pretend` and + `--yes` implies copier's `--overwrite`. """ if docs_template not in [None, "none"] and ( From bd12199b60fb8c239c2c51a3a950389dc0619869 Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Mon, 25 Sep 2023 08:31:13 +0200 Subject: [PATCH 12/15] ops: use https submodule path copier clones fail on relative ssh path ci clones fail on absolute ssh paths --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 3d1223de..97c0f19f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "template/{% if docs_template == 'sphinx-fhg-iis' %}docs{% endif %}"] path = "template/{% if docs_template == 'sphinx-fhg-iis' %}docs{% endif %}" - url = git@git01.iis.fhg.de:mkj/sphinx_template.git + url = https://git01.iis.fhg.de/mkj/sphinx_template From b3931209568968b06d9bcd29937e575dd5ca5953 Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Mon, 25 Sep 2023 08:36:08 +0200 Subject: [PATCH 13/15] ops: build examples using cli (not copier) --- Makefile | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 77f95176..32e80b99 100644 --- a/Makefile +++ b/Makefile @@ -10,31 +10,27 @@ DOC_EXAMPLES = docs/examples/mkdocs docs/examples/sphinx docs/examples/default d examples: ## build all published examples examples: $(PUBLISHED_EXAMPLES) -COPIER_ARGS?=--trust --vcs-ref=HEAD -COPIER_DEFAULT_VALUES=-d "project_name=Sample Project" -d "package_name=sample_project" -build/examples/%: COPIER_DEFAULT_VALUES += --defaults +INIT_PYTHON_PROJECT_ARGS=--project-name="Sample Project" build/examples/%: EXAMPLE_DIR:=$@ -build/examples/github: COPIER_DEFAULT_VALUES+=-d user_name=jannismain -d remote=github -d remote_url=git@github.com:jannismain/python-project-template-example.git -build/examples/gitlab%: COPIER_DEFAULT_VALUES+=-d user_name=mkj -build/examples/gitlab_fhg: COPIER_DEFAULT_VALUES+= -d remote=gitlab-fhg -d remote_url=git@gitlab.cc-asp.fraunhofer.de:mkj/sample-project.git -build/examples/gitlab_iis: COPIER_DEFAULT_VALUES+= -d remote=gitlab-iis -d remote_url=git@git01.iis.fhg.de:mkj/sample-project.git -build/examples/gitlab_iis_sphinx: COPIER_DEFAULT_VALUES+= -d remote=gitlab-iis -d remote_url=git@git01.iis.fhg.de:mkj/sample-project-sphinx.git -d docs=sphinx +build/examples/github: INIT_PYTHON_PROJECT_ARGS+=--user-name=jannismain --remote=github --remote-url=git@github.com:jannismain/python-project-template-example.git +build/examples/gitlab%: INIT_PYTHON_PROJECT_ARGS+=--user-name mkj +build/examples/gitlab_fhg: INIT_PYTHON_PROJECT_ARGS+=--remote=gitlab-fhg --remote-url=git@gitlab.cc-asp.fraunhofer.de:mkj/sample-project.git +build/examples/gitlab_iis: INIT_PYTHON_PROJECT_ARGS+=--remote=gitlab-iis --remote-url=git@git01.iis.fhg.de:mkj/sample-project.git +build/examples/gitlab_iis_sphinx: INIT_PYTHON_PROJECT_ARGS+=--remote=gitlab-iis --remote-url=git@git01.iis.fhg.de:mkj/sample-project-sphinx.git --docs=sphinx -$(PUBLISHED_EXAMPLES): +$(PUBLISHED_EXAMPLES): uncopy-template copy-template @echo "Recreating '$@'..." @rm -rf "$@" && mkdir -p "$@" - @copier copy ${COPIER_ARGS} ${COPIER_DEFAULT_VALUES} . "$@" + init-python-project "$@" ${INIT_PYTHON_PROJECT_ARGS} --defaults --yes --verbose $(MAKE) example-setup EXAMPLE_DIR="$@" -INIT_PYTHON_PROJECT_ARGS=--project-name="Sample Project" docs/examples/mkdocs: INIT_PYTHON_PROJECT_ARGS+=--docs mkdocs docs/examples/sphinx: INIT_PYTHON_PROJECT_ARGS+=--docs sphinx docs/examples/minimal: INIT_PYTHON_PROJECT_ARGS+=--docs none --no-precommit --no-bumpversion docs/examples/full: INIT_PYTHON_PROJECT_ARGS+=--docs mkdocs --precommit --bumpversion docs/examples/gitlab: INIT_PYTHON_PROJECT_ARGS+=--docs mkdocs --precommit --bumpversion --remote gitlab-iis doc-examples: $(DOC_EXAMPLES) -$(DOC_EXAMPLES): - $(MAKE) uncopy-template copy-template +$(DOC_EXAMPLES): uncopy-template copy-template @echo "Recreating '$@'..." @rm -rf "$@" && mkdir -p "$@" init-python-project "$@" --user-name mkj ${INIT_PYTHON_PROJECT_ARGS} --defaults --yes --verbose @@ -68,7 +64,7 @@ examples-clean: ## remove all published examples build/example: ## build individual example for manual testing (will prompt for values!) rm -rf "$@" - copier copy ${COPIER_ARGS} ${COPIER_DEFAULT_VALUES} . "$@" + init-python-project "$@" ${INIT_PYTHON_PROJECT_ARGS} $(MAKE) example-setup EXAMPLE_DIR="$@" From 4dae55154059de3c36f79a4a3e98488f1ede1e09 Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Mon, 25 Sep 2023 09:28:51 +0200 Subject: [PATCH 14/15] ops(ci): install built package instead of src project --- .gitlab-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e6acb700..748c5c6a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -40,9 +40,11 @@ dist: docs: stage: build + needs: + - dist script: - apt-get update && apt-get install tree - - pip install .[doc] + - pip install build/dist/*.whl - make docs artifacts: paths: From 7c37f095695e3da311f074bc8c25ec20ee602e0a Mon Sep 17 00:00:00 2001 From: Jannis Mainczyk Date: Mon, 25 Sep 2023 09:37:54 +0200 Subject: [PATCH 15/15] fix(template): add missing mkdocs to doc requirements --- .../{% if docs == 'mkdocs' %}docs{% endif %}/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/template/{% if docs == 'mkdocs' %}docs{% endif %}/requirements.txt b/template/{% if docs == 'mkdocs' %}docs{% endif %}/requirements.txt index 5090e64c..4a3f3f67 100644 --- a/template/{% if docs == 'mkdocs' %}docs{% endif %}/requirements.txt +++ b/template/{% if docs == 'mkdocs' %}docs{% endif %}/requirements.txt @@ -1,3 +1,4 @@ +mkdocs mkdocs-material mkdocstrings[python] mkdocs-git-revision-date-localized-plugin