diff --git a/.github/workflows/build-documentation.yml b/.github/workflows/build-documentation.yml new file mode 100644 index 0000000..237f222 --- /dev/null +++ b/.github/workflows/build-documentation.yml @@ -0,0 +1,34 @@ +name: "Build and Deploy documentation to GH Pages" + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Check out repository + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Build the MkDocs site + run: mkdocs build + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./site diff --git a/.github/workflows/govcookiecutter-build.yml b/.github/workflows/govcookiecutter-build.yml index abf14e3..1092c25 100644 --- a/.github/workflows/govcookiecutter-build.yml +++ b/.github/workflows/govcookiecutter-build.yml @@ -32,10 +32,10 @@ jobs: - name: Create documentation run: | if [[ "$RUNNER_OS" == "Linux" || "$RUNNER_OS" == "macOS" ]]; then - sphinx-build -b html ./docs ./docs/_build + mkdocs build -c -s elif [ "$RUNNER_OS" == "Windows" ]; then # TODO: Investigate why Sphinx build raises a warning on Windows but not Unix - sphinx-build -b html ./docs ./docs/_build -Q + mkdocs build -c -s else echo "$RUNNER_OS not supported" exit 1 diff --git a/.github/workflows/govcookiecutter-deploy-documentation.yml b/.github/workflows/govcookiecutter-deploy-documentation.yml deleted file mode 100644 index 8ed4d6c..0000000 --- a/.github/workflows/govcookiecutter-deploy-documentation.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: govcookiecutter deploy documentation - -on: - release: - types: [ released ] - -jobs: - deploy-documentation: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up Python 3.9 - uses: actions/setup-python@v4 - with: - python-version: 3.9 - - name: Install requirements, and build documentation - run: make docs - - name: Publish to GitHub Pages - if: startsWith(github.ref, 'refs/tags') - uses: JamesIves/github-pages-deploy-action@4.1.4 - with: - branch: gh-pages - folder: docs/_build diff --git a/CHANGELOG.md b/CHANGELOG.md index c3fb71d..037a31e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,12 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ### Added +- Use of Mkdocs and material for mkdocs to create HTML documentation ### Fixed ### Changed +- Structure of Docs folder, combined and removed files to simplify folder structure +- Reviewed accessibility statement ### Removed +- Sphinx documentation ## [1.0.0] - 18th July 2025 diff --git a/docs/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md deleted file mode 100644 index 1c46998..0000000 --- a/docs/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,2 +0,0 @@ -```{include} ../CODE_OF_CONDUCT.md -``` diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md deleted file mode 100644 index 7e3e5eb..0000000 --- a/docs/CONTRIBUTING.md +++ /dev/null @@ -1,3 +0,0 @@ -```{include} ../CONTRIBUTING.md -:relative-docs: ../ -``` diff --git a/docs/_static/mkdocs_custom.css b/docs/_static/mkdocs_custom.css new file mode 100644 index 0000000..9ec8de0 --- /dev/null +++ b/docs/_static/mkdocs_custom.css @@ -0,0 +1,46 @@ +[data-md-color-scheme="default"] { + --md-primary-fg-color: #003C57; + --md-primary-fg-color--light: #003C57; + --md-primary-fg-color--dark: #003C57; + --md-accent-fg-color: #F46A25; + --md-accent-fg-color--light: #F46A25; + --md-accent-fg-color--dark: #F46A25; + /* Set hyperlink color */ + --md-typeset-a-color: #28A197; + --md-typeset-a-color--hover: #003C57; + + --title-font-color: #003C57; + --md-footer-bg-color: #095b81; + --md-footer-bg-color--dark: #003C57; + +} + +[data-md-color-scheme="slate"] { + --md-primary-fg-color: #003C57; + --md-primary-fg-color--light: #003C57; + --md-primary-fg-color--dark: #003C57; + --md-accent-fg-color: #F46A25; + --md-accent-fg-color--light: #f57c3f; + --md-accent-fg-color--dark: #8e3f18; + /* Set hyperlink color */ + --md-typeset-a-color: #28A197; + --md-typeset-a-color--hover: #003C57; + --md-code-bg-color: #3D3D3D; + --md-footer-bg-color: #003C57; + --title-font-color: #F46A25; + --md-footer-bg-color: #0b2b3a; + --md-footer-bg-color--dark: #003C57; + + /* --md-default-bg-color: #3D3D3D; */ + /* --md-typeset-color: #ffffff; */ + /* --md-default-bg-color: #3D3D3D; */ +} + +.md-typeset h1, +.md-typeset h2, +.md-typeset h3, +.md-typeset h4, +.md-typeset h5, +.md-typeset h6 { + color: var(--title-font-color); +} diff --git a/docs/accessibility.md b/docs/accessibility.md index 934fb2f..182ca62 100644 --- a/docs/accessibility.md +++ b/docs/accessibility.md @@ -77,8 +77,7 @@ The content listed below is non-accessible for the following reasons. #### Disproportionate burden [The use of layout tables are due to the use of the -`sphinx.ext.autosummary`][sphinx-autosummary], and [`sphinx.ext.autodoc` -extensions][sphinx-autodoc]. This is a third-party, open source code base, and so is +`mkdocstrings`][mkdocstrings]. This is a third-party, open source code base, and so is beyond the scope of this project to fix, although we will apply updates as this codebase develops. @@ -98,11 +97,11 @@ They tested all pages on this site. ## What we're doing to improve accessibility -We plan to fix the accessibility issues in the content by the end of December 2021. +We plan to fix the accessibility issues in the content by the end of December 2025. ## Preparation of this accessibility statement -This statement was prepared on 30 June 2021. It was last reviewed on 20 July 2021. +This statement was prepared on 30 June 2021. It was last reviewed on 30 July 2025. [abilitynet]: https://abilitynet.org.uk/ [accessibility-legislation]: https://www.legislation.gov.uk/uksi/2018/952/regulation/4/made @@ -110,8 +109,7 @@ This statement was prepared on 30 June 2021. It was last reviewed on 20 July 202 [email]: mailto:gsshelp@statistics.gov.uk [github-issues]: https://github.com/best-practice-and-impact/govcookiecutter-lite/issues/new [github-pages]: https://best-practice-and-impact.github.io/govcookiecutter-lite -[sphinx-autodoc]: https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html -[sphinx-autosummary]: https://www.sphinx-doc.org/en/master/usage/extensions/autosummary.html +[mkdocstrings]: https://mkdocstrings.github.io/ [wave]: https://wave.webaim.org/ [wcag]: https://www.w3.org/TR/WCAG21/ [wcag-2.1-1.3.1]: https://www.w3.org/WAI/WCAG21/Understanding/info-and-relationships.html diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index a9977d3..0000000 --- a/docs/conf.py +++ /dev/null @@ -1,145 +0,0 @@ -# `govcookiecutter-lite` documentation build configuration file -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this autogenerated -# file. -# -# All configuration values have a default; values that are commented out serve to show -# the default. - -# If extensions (or modules to document with autodoc) are in another directory, add -# these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. - -import os -import subprocess -import sys - -sys.path.insert(0, os.path.abspath("..")) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = "4.0" - -# Add any Sphinx extension module names here, as strings. They can be extensions coming -# with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [ - "sphinx.ext.autodoc", - "sphinx.ext.autosectionlabel", - "sphinx.ext.autosummary", - "sphinx.ext.githubpages", - "sphinx.ext.napoleon", - "myst_parser", - "sphinx_rtd_theme", -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# The suffix(es) of source filenames. You can specify multiple suffix as a list of -# string: -source_suffix = { - ".rst": "restructuredtext", - ".md": "markdown", -} - -# The master toctree document. -master_doc = "index" - -# General information about the project. -project = "govcookiecutter-lite" -author = "Office for National Statistics" - -# List of patterns, relative to source directory, that match files and directories to -# ignore when looking for source files. These patterns also affect html_static_path and -# html_extra_path -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "README.md"] - -# -- Options for HTML output ----------------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for a list of -# builtin themes. -html_theme = "sphinx_rtd_theme" - -# Variables to pass to each HTML page to help populate page-specific options -html_context = { - "github_url": "https://www.github.com/best-practice-and-impact/govcookiecutter", - "gitlab_url": None, - "conf_py_path": "docs/", - "version": "main", - "accessibility": "accessibility.md", -} - -# Adds logo to top of page -html_logo = "_static/af-logo.png" - -# Add any paths that contain custom static files (such as style sheets) here, relative -# to this directory. They are copied after the builtin static files, so a file named -# "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - -# Output file base name for HTML help builder. -htmlhelp_basename = "govcookiecutterdoc" - -# -- Options for govuk-tech-docs-sphinx-theme ------------------------------------------ - -# Get the latest Git commit hash — this is used to redirect the 'View Source' link -# correctly. If this fails, default to `main`. Based on code snippet from: -# https://github.com/sphinx-doc/sphinx/blob/1ebc9c26c7a4c484733beb9f8e39e93846d86494/sphinx/__init__.py#L53 # noqa: E501 -try: - p = subprocess.run( - ["git", "show", "-s", "--pretty=format:%H"], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - encoding="ascii", - ) - git_version = p.stdout if p.stdout else "main" -except Exception: - git_version = "main" - -# -- Options for autosection output ---------------------------------------------------- - -# Prefix document path to section labels, otherwise autogenerated labels would look -# like 'heading' rather than 'path/to/file:heading' -autosectionlabel_prefix_document = True - -# -- Options for autosummary output ---------------------------------------------------- - -# Set the autosummary to generate stub files -autosummary_generate = True - -# -- Options for Napoleon extension ---------------------------------------------------- - -# Napoleon settings to enable parsing of Google- and NumPy-style docstrings. -# napoleon_google_docstring = True -# napoleon_numpy_docstring = True -# napoleon_include_init_with_doc = False -# napoleon_include_private_with_doc = False -# napoleon_include_special_with_doc = True -# napoleon_use_admonition_for_examples = False -# napoleon_use_admonition_for_notes = False -# napoleon_use_admonition_for_references = False -# napoleon_use_ivar = False -# napoleon_use_param = True -# napoleon_use_rtype = True - -# -- Options for MyST ------------------------------------------------------------------ - -# Enforce heading anchors for h1 to h6 headings -myst_heading_anchors = 6 - -# Enable MyST extensions -myst_enable_extensions = [ - "amsmath", - "colon_fence", - "deflist", - "dollarmath", - "html_admonition", - "html_image", - # "linkify", - "replacements", - "smartquotes", - "substitution", -] diff --git a/CODE_OF_CONDUCT.md b/docs/contributing/CODE_OF_CONDUCT.md similarity index 100% rename from CODE_OF_CONDUCT.md rename to docs/contributing/CODE_OF_CONDUCT.md diff --git a/CONTRIBUTING.md b/docs/contributing/CONTRIBUTING.md similarity index 83% rename from CONTRIBUTING.md rename to docs/contributing/CONTRIBUTING.md index 0a33257..f3a414b 100644 --- a/CONTRIBUTING.md +++ b/docs/contributing/CONTRIBUTING.md @@ -1,9 +1,9 @@ # Contributing We love contributions! We've compiled this documentation to help you understand our -contributing guidelines. Please also read our [`CODE_OF_CONDUCT.md`][code-of-conduct]. +contributing guidelines. Please also read our [code of conduct](./CODE_OF_CONDUCT.md). -If you still have questions, please contact us at ASAP@ons.gov.uk and we'd be happy to help! +If you still have questions, please contact us at [ASAP@ons.gov.uk][asap-email] and we'd be happy to help! ## Getting started @@ -50,7 +50,7 @@ Raise an issue using the bug report template - please check the [issues][issues] ### Want to see a new feature? -We'd be delighted to consider it! Please raise an issue using the feature request template after checking the [issues][issues] in case you can add to an ongoing discussion. +We'd be delighted to consider it! Please [raise an issue][new-issue] using the feature request template after checking the [issues][issues] in case you can add to an ongoing discussion. ### Markdown @@ -100,21 +100,24 @@ The HTML report can be accessed at `htmlcov/index.html`. Documentation is stored in the `docs` folder unless it's more appropriate to store it elsewhere, like this contributing guidance. We -write our documentation in [MyST Markdown][myst] for use in [Sphinx][sphinx], to make -a searchable wesite. Public sector websites must be accessible by law, and GOV.UK has +write our documentation in [MyST Markdown][myst] for use in [mkdocs][mkdocs], to make +a searchable website. Public sector websites must be accessible by law, and GOV.UK has further information on these [requirements][gov-uk-accessibility]. To create the website locally, run the following command in your terminal at the top-level of this project: ```shell -make docs +mkdocs build ``` -This should create an HTML version of your documentation accessible from -`docs/_build/index.html`. +or make an interactive version to view live changes run: -[code-of-conduct]: https://github.com/best-practice-and-impact/govcookiecutter/blob/main/CODE_OF_CONDUCT.md +```shell +mkdocs serve +``` + +[asap-email]: mailto:ASAP@ons.gov.uk [coverage]: https://coverage.readthedocs.io/ [detect-secrets-repo]: https://github.com/Yelp/detect-secrets/tree/master [duck-book-version-control]: https://best-practice-and-impact.github.io/qa-of-code-guidance/version_control.html @@ -123,9 +126,10 @@ This should create an HTML version of your documentation accessible from [gitignore-io]: https://www.toptal.com/developers/gitignore [gov-uk-accessibility]: https://www.gov.uk/guidance/accessibility-requirements-for-public-sector-websites-and-apps [gov-uk]: https://www.gov.uk/ -[issues]: https://github.com/best-practice-and-impact/govcookiecutter/issues/new +[issues]: https://github.com/best-practice-and-impact/govcookiecutter-lite/issues +[new-issue]: https://github.com/best-practice-and-impact/govcookiecutter-lite/issues/new [myst]: https://myst-parser.readthedocs.io/ [nbstripout-repo]: https://github.com/kynan/nbstripout [pre-commit]: https://pre-commit.com [pytest]: https://docs.pytest.org/ -[sphinx]: https://www.sphinx-doc.org/en/master/index.html +[mkdocs]: https://www.mkdocs.org/ diff --git a/docs/contributing/create_example.md b/docs/contributing/create_example.md new file mode 100644 index 0000000..42bc686 --- /dev/null +++ b/docs/contributing/create_example.md @@ -0,0 +1,21 @@ +# `example` folder overview + +Test builds of the cookiecutter template using all default options can be made in this +repository. + +In Windows, delete any pre-existing sub-folders in the `example` folder, and run: + +```shell +python -m cookiecutter . -o ./example --no-input +``` + +Unix and Linux users can alternatively use a `make` command: + +!!! warning + + Any existing folders will be automatically deleted by executing the make command. + + +```shell +make example +``` diff --git a/docs/govcookiecutter_structure/docs_structure_README.md b/docs/contributing/docs_structure_README.md similarity index 87% rename from docs/govcookiecutter_structure/docs_structure_README.md rename to docs/contributing/docs_structure_README.md index 9cc54e7..a182898 100644 --- a/docs/govcookiecutter_structure/docs_structure_README.md +++ b/docs/contributing/docs_structure_README.md @@ -1,63 +1,49 @@ # `govcookiecutter-lite` structure -This page provides information on the `govcookiecutter-lite` repository structure. -Further detail on folder contents is available: - -```{toctree} -:maxdepth: 1 -./docs.md -./example.md -./hooks.md -./tests.md -../{{ cookiecutter.repo_name }}/docs_repo_README.md -``` - -## Top-level files - Each subsection here contains a brief description about the files at the top-level of this Git repository. -### `.flake8` +## `.flake8` A configuration file for the `flake8` Python package that provides linting. This file is based on the common configuration described in the [GDS Way][gds-way-flake8]. -### `.gitignore` +## `.gitignore` A `.gitignore` file to specify that git should not track certain files and folders in this repository. -### `.pre-commit-config.yaml` +## `.pre-commit-config.yaml` A [pre-commit hook][docs-pre-commit-hooks] file covering linting, secret detection, and styling among other things. -### `.secrets.baseline` +## `.secrets.baseline` A file for configuration of the `detect-secrets`[detect-secrets] pre-commit hook. `detect-secrets` prevents secrets from being committed to the repository. The baseline file flags secret-like data that the user deliberately wishes to commit the to repository. -### `CHANGELOG.md` +## `CHANGELOG.md` A file describing the changes made to `govcookiecutter-lite` over time, including unreleased and upcoming changes. -### `CODE_OF_CONDUCT.md` +## `CODE_OF_CONDUCT.md` The [Code of Conduct][code-of-conduct] describes how contributors should interact with each other on the project. It also contains information about the responsibilities of contributors both within and outside of the `best-practice-and-impact` organisation. -### `conftest.py` +## `conftest.py` A file to store shared fixture functions for the `pytest` tests in the `tests` folder. -### `CONTRIBUTING.md` +## `CONTRIBUTING.md` The contributing guidelines for this project, explaining how contributors can engage with `govcookiecutter-lite`. -### `cookiecutter.json` +## `cookiecutter.json` A file containing the prompts for template generation alongside default values. Any keys beginning with an underscore are not shown to users. @@ -70,14 +56,14 @@ information. For further information in the `cookiecutter.json` file, see the `cookiecutter` package [documentation][cookiecutter]. -### `LICENSE` +## `LICENSE` The licence describes how the project can be used or re-used by others. Unless stated otherwise, the codebase is released under the MIT License. This covers both the codebase and any sample code in the documentation. The documentation is © Crown copyright and available under the terms of the Open Government 3.0 licence. -### `Makefile` +## `Makefile` The `Makefile` contains a set of commands for the `make` utility, more often used on Unix-like and Linux systems. This allows a user to, for example, @@ -87,7 +73,7 @@ run the `help` command for further information at the top-level of the Git repos make help ``` -### `pyproject.toml` +## `pyproject.toml` A file containing Python project settings. This includes configuration settings for: @@ -95,11 +81,11 @@ A file containing Python project settings. This includes configuration settings - [`pytest`](#pytest) - [code coverage](#code-coverage) -#### `isort` +### `isort` Python imports are arranged according to the [specification defined by `black`][black]. -#### `pytest` +### `pytest` To run the tests within the `tests`, and `{{ cookiecutter.project_slug }}/tests` folders using the `pytest` Python package, enter the following command: @@ -108,7 +94,7 @@ using the `pytest` Python package, enter the following command: pytest ``` -#### Code coverage +### Code coverage To run code coverage using the `coverage` Python package with `pytest`, enter the following command: @@ -128,11 +114,11 @@ A code coverage report in HTML will be produced on the code in the `hooks` and `{{ cookiecutter.project_slug }}/{{ cookiecutter.project_slug }}` folders. This HTML report can be accessed at `htmlcov/index.html`. -### `README.md` +## `README.md` An overview of the Git repository and aims of `govcookiecutter-lite`, including all necessary instructions to run the code. -### `requirements.txt` +## `requirements.txt` A list of Python package dependencies for the `govcookiecutter` repository, which can be installed using the `pip install` command: diff --git a/docs/reference/docs_ref_README.md b/docs/contributing/hooks_api_reference.md similarity index 56% rename from docs/reference/docs_ref_README.md rename to docs/contributing/hooks_api_reference.md index 1c22c7e..63d17d8 100644 --- a/docs/reference/docs_ref_README.md +++ b/docs/contributing/hooks_api_reference.md @@ -1,17 +1,24 @@ -# `hooks` API reference +## hooks folder overview + +This folder contains any pre- and post-generation hooks used by the `cookiecutter` +Python package. These are used to customise the created repository based on the +user's requirements, and perform automated tasks such as removing folders. + +Full documentation on pre- and post-generation hooks is available in +the [`cookiecutter` documentation][cookiecutter-hooks]. + +## `hooks` API reference This page gives an overview of all public `hooks` objects, functions and methods. All classes and functions exposed in `hooks.*` namespace are public. -```{eval-rst} -.. currentmodule:: hooks -``` - ## Cookiecutter pre-generation hooks These are functions run after user input, but before project generation. If any pre-generation hooks fail, the project will not be generated. +::: hooks.pre_gen_project + ## Cookiecutter post-generation hooks These are functions run after initial project generation by the `cookiecutter` @@ -19,21 +26,9 @@ package. These include moving the selected organisational frameworks to the corr location, as well as deleting unnecessary files and folders. If any post-generation hooks fail, the generated project will be rolled-back, and deleted. -### Public sector organisational framework functions - -```{eval-rst} -.. autosummary:: - :toctree: api/ - -``` ### Post-generation clean up -```{eval-rst} -.. autosummary:: - :toctree: api/ - - delete_files_and_folders - parse_features_json +::: hooks.post_gen_project -``` +[cookiecutter-hooks]: https://cookiecutter.readthedocs.io/en/latest/advanced/hooks.html diff --git a/docs/contributing_guide/modify_govcookiecutter-lite.md b/docs/contributing/modify_govcookiecutter-lite.md similarity index 56% rename from docs/contributing_guide/modify_govcookiecutter-lite.md rename to docs/contributing/modify_govcookiecutter-lite.md index 588ef74..5f67162 100644 --- a/docs/contributing_guide/modify_govcookiecutter-lite.md +++ b/docs/contributing/modify_govcookiecutter-lite.md @@ -1,10 +1,11 @@ -# Modifying `govcookiecutter-lite` +# Modifying govcookiecutter-lite + +!!! warning + + It's strongly recommended you build an example project to test that your changes work! -```{warning} -It's strongly recommended you build an example project to test that your changes work! -``` -[`govcookiecutter-lite` uses the `cookiecutter` Python package][cookiecutter] to build +Govcookiecutter-lite uses the [`cookiecutter` Python package][cookiecutter] to build template project structures. In turn, [`cookiecutter` uses Jinja templating to inject user-defined variables][jinja] into files, file names, and folder names. Most of these variables are based on answers to prompts when you run the `cookiecutter` command. @@ -52,86 +53,8 @@ User entries are validated with pre-generation hooks, which are defined in `hooks/pre_gen_project.py`. These hooks run before a project is created and, if they fail, will not create the project. -The only supported validation currently is for a [valid email address, based on the -HTML5 standard for email address format][html5-email-format]. - -## Conditional files and/or folders - -Conditional folders and/or files are items than only exist if actively selected for the -user. For example, if users select `No` for the `using_R` prompt, any R files and -content is removed from their outputted project. - -```{note} Folder and file names with Jinja templating - -Do not use Jinja templating for conditional folders and/or files, as certain characters -may not be supported on all operating systems. - -``` - -This functionality is provided by post-generation hooks in `govcookiecutter-lite`, which are -defined in `hooks/post_gen_project.py`. These hooks only run after a project has been -generated and, if they fail, will rollback the entire project. - -Conditional files and folders are defined as `features` in the -`{{ cookiecutter.project_slug }}/manifest.json` file, which looks like: - -``` -{ - "features": [ - { - "name": "A name", - "description": "A description.", - "remove": {% if cookiecutter.{KEY} == {VALUE} %}true{% else %}false{% endif %}, - "resources": ["A", "list", "of", "files", "and/or", "folders"] - } - ] -} -``` - -where `{KEY}` and `{VALUE}` are `cookiecutter.json` keys and values. - -This works by using Jinja conditional templating to either set the `remove` value to -true or false. The post-generation hook then scans through this JSON file deleting all -files and folders listed in the `resources` value where `remove == true`. - -### Changing conditional folders and files - -If an existing feature has a `remove` condition that meets your needs, amend its -`resources` list to change the folders/files that will be removed. - -To add a new feature, add a dictionary within the `features` list, which has at least -the `remove` and `resources` keys. Add your Jinja conditional for the `remove` value, -and a list of files/folders for the `resources` key. For documentation purposes, it's -good practice to add `name` and `description` keys as well! - -To remove a feature, delete the appropriate dictionary from the `features` list. - -## Conditional file content - -Jinja conditional statements can be used display content based on the user responses. -For example, for the following Markdown: - -```markdown -### `CONTRIBUTING.md` - -The contributing guidelines for this project. - -### `LICENSE` - -The licence for this project... -``` - -the `DESCRIPTION` section is conditional on the user response to the `using_R` prompt. - -Notice the hyphen before the trailing `%` in each Jinja statement; this hyphen controls -blank space after the statement. A hyphen after the leading `%` in a Jinja statement -controls blank space before the element. - -## Replacing folders and files - -[Replacing folders and files a more involved change, and is currently supported for -AQA frameworks and pull/merge request templates only][docs-organisational-frameworks]. -These are performed in the `hooks/post_gen_project.py`file. +Currently we only raise a warning if the user includes underscores in the project name. +It is recommend to only include underscores in package names if they improve readability. ## Tests, coverage, and continuous integration @@ -180,15 +103,9 @@ When a pull request is raised, GitHub Actions will also: - navigate into the example project - initialise Git - install requirements -- build the example project documentation, checking for errors but not warnings -- check for broken external links in the documentation -- run pre-commit hooks on all files These "on pull request" CI checks are run on Ubuntu, and macOS operating systems, as -well as Python 3.6+, and for example projects with or without R 4.0.4+. - -[To understand why only certain operating systems are supported for GitHub Actions, -see GitHub issues 29 and 30][github-issues]. +well as Python 3.9+. ## Releases diff --git a/docs/contributing_guide/docs_contributor_README.md b/docs/contributing_guide/docs_contributor_README.md deleted file mode 100644 index 51c7aaf..0000000 --- a/docs/contributing_guide/docs_contributor_README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Contributing guide - -This is the contributor guide for the `govcookiecutter-lite` project. - -## Table of Contents - -- [Code of Conduct](../CODE_OF_CONDUCT.md) -- [Contributing Guidelines](../CONTRIBUTING.md) -- [How to Modify govcookiecutter-lite](./modify_govcookiecutter-lite.md) -- [top level files](../govcookiecutter_structure/docs_structure_README.md) diff --git a/docs/{{ cookiecutter.repo_name }}/docs_repo_README.md b/docs/created_project_structure/created_folder_structure.md similarity index 100% rename from docs/{{ cookiecutter.repo_name }}/docs_repo_README.md rename to docs/created_project_structure/created_folder_structure.md diff --git a/docs/created_project_structure/prompts.md b/docs/created_project_structure/prompts.md new file mode 100644 index 0000000..7e91b23 --- /dev/null +++ b/docs/created_project_structure/prompts.md @@ -0,0 +1,43 @@ +# Govcookiecutter-lite Prompts + +We have opted to create a slimmed down install which comes with the bare minimum. +Hence we have reduced the number of questions prompted to the user. +Although these may be self explanatory by name, this table has been created to outline what each prompt represents and how it should be used. + + + + + + + + + + + + + + + + + + + + + + + +
Prompt NameDescriptionExample Value
project_nameThe name to assign to your new project.
Underscores are advised against unless they increase readability.
This name is also used as the Python package name; it can be changed in pyproject.toml.
your_new_project_name
organisation_handleThe short identifier for your organisation or team.
Used in project TOML to identify authors of the package.
ONS
diff --git a/docs/docs_README.md b/docs/docs_README.md deleted file mode 100644 index 5b31d5c..0000000 --- a/docs/docs_README.md +++ /dev/null @@ -1,29 +0,0 @@ -# `docs` folder overview - -This folder contains documentation for `govcookiecutter-lite`. These are written in MyST Markdown files with Sphinx compatibility. - -```{warning} -Further details to consider when modifying these files are supplied in the [contributing guidance][contributing-guidance]. -``` - -To include documentation from the `{{ cookiecutter.project_slug }}` -folder without duplicating it, refer to it in a file within the `docs/{{ cookiecutter.project_slug }}` folder. - -To build the documentation, run: - -```shell -sphinx-build -b html ./docs ./docs/_build -``` - -Unix and Linux users can alternatively run the `docs` command from [`Makefile`][docs-makefile] using -the `make` utility at the top-level of this repository. - -```shell -make docs -``` - -The HTML-version of this documentation can then be viewed at `docs/_build/index.html`, -relative to the top-level of this repository. - -[docs-makefile]: https://github.com/best-practice-and-impact/govcookiecutter/blob/main/docs/govcookiecutter_structure/docs_structure_README.md#makefile -[contributing-guidance]: https://github.com/best-practice-and-impact/govcookiecutter/blob/main/%7B%7B%20cookiecutter.repo_name%20%7D%7D/docs/contributor_guide/CONTRIBUTING.md#documentation diff --git a/docs/govcookiecutter_structure/docs.md b/docs/govcookiecutter_structure/docs.md deleted file mode 100644 index 20cc980..0000000 --- a/docs/govcookiecutter_structure/docs.md +++ /dev/null @@ -1,3 +0,0 @@ -```{include} ../docs_README.md -:relative-docs: ../ -``` diff --git a/docs/govcookiecutter_structure/example.md b/docs/govcookiecutter_structure/example.md deleted file mode 100644 index e66113f..0000000 --- a/docs/govcookiecutter_structure/example.md +++ /dev/null @@ -1,2 +0,0 @@ -```{include} ../../example/example_folder_README.md -``` diff --git a/docs/govcookiecutter_structure/hooks.md b/docs/govcookiecutter_structure/hooks.md deleted file mode 100644 index bf7af89..0000000 --- a/docs/govcookiecutter_structure/hooks.md +++ /dev/null @@ -1,2 +0,0 @@ -```{include} ../../hooks/hooks_README.md -``` diff --git a/docs/govcookiecutter_structure/tests.md b/docs/govcookiecutter_structure/tests.md deleted file mode 100644 index de16b2c..0000000 --- a/docs/govcookiecutter_structure/tests.md +++ /dev/null @@ -1,2 +0,0 @@ -```{include} ../../tests/tests_README.md -``` diff --git a/docs/index.md b/docs/index.md index b5e0140..a9cad79 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,11 +1,75 @@ -```{include} ../README.md -:relative-docs: ../ ./contributing_guide +## What is govcookiecutter-lite? + +A lightweight cookiecutter template for analytical Python-based projects within +His Majesty's Government, and wider public sector. + +## Project structure layout + +The cookiecutter template generated for each project will follow this folder structure: + +```shell +your_project/ +├── docs/ +│ └── ... +├── your_project/ +│ ├── example_module/ +│ │ └── ... +│ └── ... +├── tests/ +│ └── ... +├── .gitignore +├── CHANGELOG.md +├── LICENSE +├── pyproject.toml +└── README.md ``` -```{toctree} -:hidden: -:maxdepth: 2 -self -./{{ cookiecutter.repo_name }}/docs_repo_README.md -./contributing_guide/docs_contributor_README.md +More information on these top level files can be found in [created folder structure section][created-folder-structure] + +## Quickstart Guide + +Govcookiecutter-lite only has one package requirement; `cookiecutter`. The following two lines can be pasted and run in a python virtual environment and will install cookiecutter, then use the govcookiecutter-lite template to create your new project. + + +``` shell +pip install cookiecutter +python -m cookiecutter https://github.com/best-practice-and-impact/govcookiecutter-lite.git ``` +Further details on the prompts asked and what they mean can be found in [creation prompts][prompts]. + +## Picking between Govcookiecutter and Govcookiecutter-lite + +We have tabulated the differences between the versions to help selecting which version best suites your use case. +Note it is possible to add items such as pre-commit hooks and buildable documentation post creation, this table simply denotes what is included at project creation. + +| Feature | [Govcookiecutter][govcookiecutter] | [Govcookiecutter-lite][govcookiecutter-lite] | +|-----------------------------------|:-----------------:|:---------------------:| +| Python Project Template | ✓ | ✓ | +| Documentation Folder with Analytical QA | ✓ | ✓ | +| Unit test folder | ✓ | ✓ | +| Simplified setup prompts | ✗ | ✓ | +| Example code and unit tests | ✓ | ✗ | +| HTML Buildable Documentation | ✓ | ✗ | +| Pre-commit hooks | ✓ | ✗ | +| Options to include R | ✓ | ✗ | +| Options to specify if development is in locked down environment | ✓ | N/A *| +|Platform specific issue and pull request templates| ✓ | ✗| + +\* This option is not included in govcookiecutter-lite as it relates to pre-commit hooks + + + +[prompts]: created_project_structure/prompts.md +[created-folder-structure]: created_project_structure/created_folder_structure.md +[aqua-book]: https://www.gov.uk/government/publications/the-aqua-book-guidance-on-producing-quality-analysis-for-government +[blog-post]: https://dataingovernment.blog.gov.uk/2021/07/20/govcookiecutter-a-template-for-data-science-projects/ +[cruft]: https://github.com/cruft/cruft +[docs-pre-commit]: contributing/CONTRIBUTING.md#getting-started +[drivendata]: http://drivendata.github.io/cookiecutter-data-science/ +[govcookiecutter]: https://github.com/best-practice-and-impact/govcookiecutter.git +[homebrew]: https://brew.sh/ +[issue-windows-os]: https://github.com/best-practice-and-impact/govcookiecutter/issues/20 +[pluralsight]: https://www.pluralsight.com/tech-blog/managing-python-environments/ +[youtube]: https://www.youtube.com/watch?v=N7_d3k3uQ_M +[govcookiecutter]: https://github.com/best-practice-and-impact/govcookiecutter/tree/main +[govcookiecutter-lite]: https://github.com/best-practice-and-impact/govcookiecutter-lite/tree/main diff --git a/README.md b/docs/readme.md similarity index 90% rename from README.md rename to docs/readme.md index 0d3459a..8ca0dff 100644 --- a/README.md +++ b/docs/readme.md @@ -1,4 +1,4 @@ -# `govcookiecutter-lite` +# govcookiecutter-lite ## What is govcookiecutter-lite? @@ -43,7 +43,7 @@ First, make sure your system meets the requirements. ### Requirements to create a cookiecutter template > **Note** -> Contributors have some additional [requirements!](./CONTRIBUTING.md) +> Contributors have some additional [requirements!](contributing/CONTRIBUTING.md) To get started your system should meet the following requirements: @@ -105,16 +105,10 @@ Once you've answered all the prompts, your project will be created. Then: git init ``` -3. Install the necessary packages using `pip` and the pre-commit hooks: +3. Install the necessary packages using `pip`: ```shell python -m pip install -U pip setuptools python -m pip install -e .[dev] - pre-commit install - ``` - - or use the `make` command: - ```shell - make install_dev ``` 4. Stage all your project files, and make your first commit @@ -139,10 +133,6 @@ Here are some suggested changes to make before your first commit: - make sure the `README.md` reflects what you want to do with your project - have a look inside the `docs/aqa` folder, as you may want to modify some of this analytical quality assurance documentation (AQA), for example the AQA plan -- (if present) confirm that the pull or merge request template checklists meet your - requirements - - These can be found at `.github/pull_request_template.md` (GitHub), or in - `.gitlab/merge_request_templates` folder (GitLab) ## Licence @@ -153,7 +143,7 @@ Crown copyright and available under the terms of the Open Government 3.0 licence ## Contributing If you want to help us build, and improve `govcookiecutter-lite`, view our [contributing -guidelines](./CONTRIBUTING.md). +guidelines](contributing/CONTRIBUTING.md). ## Acknowledgements @@ -163,7 +153,7 @@ project][drivendata]. Specifically, it uses a modified version of the `help` com [aqua-book]: https://www.gov.uk/government/publications/the-aqua-book-guidance-on-producing-quality-analysis-for-government [blog-post]: https://dataingovernment.blog.gov.uk/2021/07/20/govcookiecutter-a-template-for-data-science-projects/ [cruft]: https://github.com/cruft/cruft -[docs-pre-commit]: ./CONTRIBUTING.md#getting-started +[docs-pre-commit]: contributing/CONTRIBUTING.md#getting-started [drivendata]: http://drivendata.github.io/cookiecutter-data-science/ [govcookiecutter]: https://github.com/best-practice-and-impact/govcookiecutter.git [homebrew]: https://brew.sh/ diff --git a/docs/{{ cookiecutter.repo_name }}/docs.md b/docs/{{ cookiecutter.repo_name }}/docs.md deleted file mode 100644 index 010cd88..0000000 --- a/docs/{{ cookiecutter.repo_name }}/docs.md +++ /dev/null @@ -1,2 +0,0 @@ -```{include} ../../{{ cookiecutter.project_name }}/docs/repo_docs_README.md -``` diff --git a/docs/{{ cookiecutter.repo_name }}/dot_govcookiecutter.md b/docs/{{ cookiecutter.repo_name }}/dot_govcookiecutter.md deleted file mode 100644 index 72fe5b6..0000000 --- a/docs/{{ cookiecutter.repo_name }}/dot_govcookiecutter.md +++ /dev/null @@ -1,6 +0,0 @@ -# `.govcookiecutter` folder overview - -## manifest.json - -Used in cookiecutter configuation for removing files in the created repository that are not required -for users not using R. diff --git a/docs/{{ cookiecutter.repo_name }}/source_code.md b/docs/{{ cookiecutter.repo_name }}/source_code.md deleted file mode 100644 index dbb9c7a..0000000 --- a/docs/{{ cookiecutter.repo_name }}/source_code.md +++ /dev/null @@ -1,5 +0,0 @@ -# `{{ cookiecutter.project_slug }}` folder overview - -This is where source code for the created project is stored. We recommend following a standard Python project structure, -with functions grouped into modules inside a descriptively named folder. The created repository contains an `example_module.py` -inside the `example_modules` folder. These can then be imported into a main script, such as `run_pipeline.py`. diff --git a/docs/{{ cookiecutter.repo_name }}/tests.md b/docs/{{ cookiecutter.repo_name }}/tests.md deleted file mode 100644 index 9889907..0000000 --- a/docs/{{ cookiecutter.repo_name }}/tests.md +++ /dev/null @@ -1,2 +0,0 @@ -```{include} ../../{{ cookiecutter.project_name }}/tests/repo_tests_README.md -``` diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 3bbfd9f..b2cffe8 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -5,16 +5,19 @@ def delete_files_and_folders(paths: Union[Path, str, List[Path], List[str]]) -> None: - """Delete files and folders for given file and/or folder paths. + """ + Delete files and folders for given file and/or folder paths. - Args: - paths: A ``pathlib.Path`` object or string, or list of ``pathlib.Path`` or - strings. + Parameters + ---------- + paths : pathlib.Path or str or list of pathlib.Path or list of str + File and/or folder paths to delete. - Returns: - None - deletes the files and/or folders defined in ``paths`` if they exist. If + Returns + ------- + None + Deletes the files and/or folders defined in `paths` if they exist. If this function raises an error, the files and/or folders have not been removed. - """ # Coerce `paths` into a list of `pathlib.Path` objects. Then remove each folder and diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..14ad627 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,92 @@ +site_name: Govcookiecutter Lite +repo_url: https://github.com/best-practice-and-impact/govcookiecutter-lite +repo_name: govcookiecutter-lite +nav: + - Quick Start Guide: index.md + - Detailed Summary: readme.md + - Creation Prompts: created_project_structure/prompts.md + - Created Folder Structure: created_project_structure/created_folder_structure.md + - Contributing: + - Contributing Guide: contributing/CONTRIBUTING.md + - Code of Conduct: contributing/CODE_OF_CONDUCT.md + - Modifying Govcookiecutter-lite: contributing/modify_govcookiecutter-lite.md + - Development Folder Structure: contributing/docs_structure_README.md + - Creating an Example Project: contributing/create_example.md + - Hooks: contributing/hooks_api_reference.md + - Accessibility: accessibility.md + + + + +theme: + logo: "_static/af-logo.png" + name: material + palette: + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + primary: custom + accent: custom + toggle: + icon: material/brightness-7 + name: Switch to dark mode + + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: custom + accent: red + toggle: + icon: material/brightness-4 + name: Switch to light mode + icon: + repo: fontawesome/brands/github + admonition: + note: octicons/tag-16 + abstract: octicons/checklist-16 + info: octicons/info-16 + tip: octicons/squirrel-16 + success: octicons/check-16 + question: octicons/question-16 + warning: octicons/alert-16 + failure: octicons/x-circle-16 + danger: octicons/zap-16 + bug: octicons/bug-16 + example: octicons/beaker-16 + quote: octicons/quote-16 + features: + - content.code.copy + - content.code.annotate + - navigation.path + - navigation.sections + - toc.integrate + - navigation.tabs + - search.suggest + - navigation.top + - navigation.expand + - navigation.tabs.sticky + - navigation.footer + +markdown_extensions: + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences + - toc: + toc_depth: 2 + - admonition + - pymdownx.details + - pymdownx.superfences + +plugins: + - mkdocstrings + - search + +extra_css: + - _static/mkdocs_custom.css + +copyright: Copyright © Office for National Statistics 2025 diff --git a/requirements.txt b/requirements.txt index 582ede9..bea9676 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,3 +13,8 @@ pytest-xdist python-dotenv Sphinx toml +# ons-mkdocs-theme +mkdocstrings[python] +mkdocs-git-revision-date-localized-plugin +mkdocs-jupyter +mkdocs-mermaid2-plugin diff --git a/tests/test_documentation_build.py b/tests/test_documentation_build.py index f71b4fb..8e15896 100644 --- a/tests/test_documentation_build.py +++ b/tests/test_documentation_build.py @@ -1,9 +1,14 @@ +import subprocess from pathlib import Path -from sphinx.cmd.build import main - class TestDocumentation: def test_build(self, tmp_path: Path) -> None: - """Test the build of the main `govcookiecutter-lite` repository.""" - assert main(["-b", "html", "docs", str(tmp_path.joinpath("_build"))]) == 0 + """Test the build of the main `govcookiecutter-lite` repository using mkdocs.""" + result = subprocess.run( + ["mkdocs", "build", "--site-dir", str(tmp_path.joinpath("_site"))], + cwd=Path(__file__).parent.parent, + capture_output=True, + text=True, + ) + assert result.returncode == 0, f"mkdocs build failed: {result.stderr}"