diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..79786a1 --- /dev/null +++ b/.envrc @@ -0,0 +1,31 @@ +# Environment variables go here, and can be read in by Python using `os.getenv`: +# +# -------------------------------------------------------- +# import os +# +# # Example variable +# EXAMPLE_VARIABLE = os.getenv("EXAMPLE_VARIABLE") +# -------------------------------------------------------- +# +# To ensure the `sed` command below works correctly, make sure all file paths in environment variables are absolute, +# are relative but do not reference any other variables except `$(pwd)`. +# +# DO NOT STORE SECRETS HERE - this file is version-controlled! You should store secrets in a `.secrets` file, which is +# not version-controlled - this can then be sourced here, using `source_env ".secrets"`. + +# Extract the variables to `.env` if required. Note `.env` is NOT version-controlled, so `.secrets` will not be +# committed. Use the first line if a `.secrets` file exists, otherwise use the second line +# sed -n 's/^export \(.*\)$/\1/p' .envrc .secrets | sed -e 's?$(pwd)?'"$(pwd)"'?g' > .env +sed -n 's/^export \(.*\)$/\1/p' .envrc | sed -e 's?$(pwd)?'"$(pwd)"'?g' > .env + +# Add the working directory to PYTHONPATH +export PYTHONPATH="$PYTHONPATH:$(pwd)" + +# Import secrets from an untracked file `.secrets` +# source_env ".secrets" + +# Add environment variables for the `docs` directory +export DIR_DOCS=$(pwd)/docs + +# Add environment variables for the `tests` directory +export DIR_TESTS=$(pwd)/tests diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..fa8c8df --- /dev/null +++ b/.flake8 @@ -0,0 +1,8 @@ +[flake8] +# Rule definitions: http://flake8.pycqa.org/en/latest/user/error-codes.html +# D203: 1 blank line required before class docstring +# W503: line break before binary operator +exclude = venv*,__pycache__,node_modules,bower_components,migrations +ignore = D203,W503 +max-complexity = 9 +max-line-length = 120 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..9c64d4e --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,29 @@ +# Summary + +Add your summary here - keep it brief, to the point, and in plain English. For further information about pull requests, +check out the [GDS Way][gds-way]. + +# Checklists + + + +This pull/merge request meets the following requirements: + +- [ ] Code runs +- [ ] Developments are **secure** and [**ethical**][data-ethics-framework] +- [ ] You have made proportionate checks that the code works correctly, and the theme works as expected +- [ ] Test suite passes +- [ ] [Minimum usable documentation][agilemodeling] written in the `docs` folder + +Comments have been added below around the incomplete checks. + +[agilemodeling]: http://agilemodeling.com/essays/documentLate.htm +[data-ethics-framework]: https://www.gov.uk/government/publications/data-ethics-framework +[gds-way]: https://gds-way.cloudapps.digital/standards/pull-requests.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0cf08d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,860 @@ +# Created by https://www.toptal.com/developers/gitignore/api/vim,venv,pydev,linux,macos,flask,dotenv,django,direnv,python,windows,virtualenv,pycharm+all,visualstudio,jupyternotebooks,visualstudiocode +# Edit at https://www.toptal.com/developers/gitignore?templates=vim,venv,pydev,linux,macos,flask,dotenv,django,direnv,python,windows,virtualenv,pycharm+all,visualstudio,jupyternotebooks,visualstudiocode + +### direnv ### +.direnv +#.envrc + +### Django ### +*.log +*.pot +*.pyc +__pycache__/ +local_settings.py +db.sqlite3 +db.sqlite3-journal +media + +# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ +# in your Git repository. Update and uncomment the following line accordingly. +# /staticfiles/ + +### Django.Python Stack ### +# Byte-compiled / optimized / DLL files +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +pytestdebug.log + +# Translations +*.mo + +# Django stuff: + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ +doc/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +pythonenv* + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# profiling data +.prof + +### dotenv ### + +### Flask ### +instance/* +!instance/.gitignore + +### Flask.Python Stack ### +# Byte-compiled / optimized / DLL files + +# C extensions + +# Distribution / packaging + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. + +# Installer logs + +# Unit test / coverage reports + +# Translations + +# Django stuff: + +# Flask stuff: + +# Scrapy stuff: + +# Sphinx documentation + +# PyBuilder + +# Jupyter Notebook + +# IPython + +# pyenv + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow + +# Celery stuff + +# SageMath parsed files + +# Environments + +# Spyder project settings + +# Rope project settings + +# mkdocs documentation + +# mypy + +# Pyre type checker + +# pytype static type analyzer + +# profiling data + +### JupyterNotebooks ### +# gitignore template for Jupyter Notebooks +# website: http://jupyter.org/ + +*/.ipynb_checkpoints/* + +# IPython + +# Remove previous ipynb_checkpoints +# git rm -r .ipynb_checkpoints/ + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### PyCharm+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### PyCharm+all Patch ### +# Ignores the whole .idea folder and all .iml files +# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 + +.idea/ + +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +.idea/misc.xml +*.ipr + +# Sonarlint plugin +.idea/sonarlint + +### pydev ### +.pydevproject + +### Python ### +# Byte-compiled / optimized / DLL files + +# C extensions + +# Distribution / packaging + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. + +# Installer logs + +# Unit test / coverage reports + +# Translations + +# Django stuff: + +# Flask stuff: + +# Scrapy stuff: + +# Sphinx documentation + +# PyBuilder + +# Jupyter Notebook + +# IPython + +# pyenv + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow + +# Celery stuff + +# SageMath parsed files + +# Environments + +# Spyder project settings + +# Rope project settings + +# mkdocs documentation + +# mypy + +# Pyre type checker + +# pytype static type analyzer + +# profiling data + +### venv ### +# Virtualenv +# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ +[Bb]in +[Ii]nclude +[Ll]ib +[Ll]ib64 +[Ll]ocal +[Ss]cripts +pyvenv.cfg +pip-selfcheck.json + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +### VirtualEnv ### +# Virtualenv +# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ + +### VisualStudioCode ### +.vscode/* +#!.vscode/tasks.json +#!.vscode/launch.json +*.code-workspace + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### VisualStudio ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*[.json, .xml, .info] + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# End of https://www.toptal.com/developers/gitignore/api/vim,venv,pydev,linux,macos,flask,dotenv,django,direnv,python,windows,virtualenv,pycharm+all,visualstudio,jupyternotebooks,visualstudiocode + +### GOV.UK Tech Docs Sphinx Theme ### + +# Ignore the `.secrets` file +.secrets diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..7306cf3 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,29 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: +- repo: https://gitlab.com/pycqa/flake8 + rev: 3.8.4 + hooks: + - id: flake8 + args: ["govuk_tech_docs_sphinx_theme"] +- repo: https://github.com/Yelp/detect-secrets + rev: v0.14.3 + hooks: + - id: detect-secrets + args: ["--baseline", ".secrets.baseline"] + exclude: .*/tests/.* +- repo: https://github.com/aflc/pre-commit-jupyter + rev: v1.1.0 + hooks: + - id: jupyter-notebook-cleanup + args: + - --remove-kernel-metadata + - --pin-patterns + - "[keep_output]" +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.4.0 + hooks: + - id: check-added-large-files + args: ["--maxkb=5120"] + - id: end-of-file-fixer + - id: trailing-whitespace diff --git a/.secrets.baseline b/.secrets.baseline new file mode 100644 index 0000000..124349f --- /dev/null +++ b/.secrets.baseline @@ -0,0 +1,67 @@ +{ + "custom_plugin_paths": [], + "exclude": { + "files": null, + "lines": null + }, + "generated_at": "2021-01-11T09:41:31Z", + "plugins_used": [ + { + "name": "AWSKeyDetector" + }, + { + "name": "ArtifactoryDetector" + }, + { + "base64_limit": 4.5, + "name": "Base64HighEntropyString" + }, + { + "name": "BasicAuthDetector" + }, + { + "name": "CloudantDetector" + }, + { + "hex_limit": 3, + "name": "HexHighEntropyString" + }, + { + "name": "IbmCloudIamDetector" + }, + { + "name": "IbmCosHmacDetector" + }, + { + "name": "JwtTokenDetector" + }, + { + "keyword_exclude": null, + "name": "KeywordDetector" + }, + { + "name": "MailchimpDetector" + }, + { + "name": "PrivateKeyDetector" + }, + { + "name": "SlackDetector" + }, + { + "name": "SoftlayerDetector" + }, + { + "name": "StripeDetector" + }, + { + "name": "TwilioKeyDetector" + } + ], + "results": {}, + "version": "0.14.3", + "word_list": { + "file": null, + "hash": null + } +} diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..752a937 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,85 @@ +# Code of conduct for `govuk-tech-docs-sphinx-theme` + +Contributors to this repository hosted by `ukgovdatascience` are expected to follow the Contributor +Covenant Code of Conduct, and those working within Her Majesty's Government are also expected to follow the Civil +Service Code. + +## Civil Service Code + +The Civil Service Code can be found [here][civil-service-code]. + +## Contributor Covenant Code of Conduct + +### Definitions + +Where this Code of Conduct says: + +- "Project", we mean this `govuk-tech-docs-sphinx-theme` GitHub repository; +- "Maintainer", we mean the `ukgovdatascience` organisation owners; and +- "Leadership", we mean both `ukgovdatascience` organisation owners, line managers, and other + leadership within Government Digital Service. + +### Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make +participation in our project, and our community a harassment-free experience for everyone, regardless of age, +body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, +socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. + +### Our Standards + +Examples of behaviour that contributes to creating a positive environment include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualised language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +### Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take +appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, +issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviours that they deem inappropriate, threatening, offensive, or harmful. + +### Scope + +This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the +project or its community in public spaces. Examples of representing a project or community include using an official +project e-mail address, posting via an official social media account, or acting as an appointed representative at an +online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +### Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behaviour may be reported by contacting the project team at +[gdsdatascience@digital.cabinet-office.gov.uk][email-address]. All complaints will be reviewed and investigated and +will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated +to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement +policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent +repercussions as determined by other members of the project's leadership. + +### Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][contributor-covenant], version 1.4, available at +[https://www.contributor-covenant.org/version/1/4/code-of-conduct.html][contributor-covenant-code-of-conduct], and the +`alphagov` Code of Conduct available at +[https://github.com/alphagov/.github/blob/master/CODE_OF_CONDUCT.md][alphagov-code-of-conduct]. + +[alphagov-code-of-conduct]: https://github.com/alphagov/.github/blob/master/CODE_OF_CONDUCT.md +[civil-service-code]: https://www.gov.uk/government/publications/civil-service-code/the-civil-service-code +[contributor-covenant]: https://www.contributor-covenant.org +[contributor-covenant-code-of-conduct]: https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +[email-address]: mailto:gdsdatascience@digital.cabinet-office.gov.uk diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..b89afff --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,120 @@ +# Contributing + +We love contributions! We've compiled this documentation to help you understand our contributing guidelines. If you +still have questions, please [contact us][email] and we'd be happy to help! + +- [Code of Conduct](#code-of-conduct) +- [Getting started](#getting-started) +- [Code conventions](#code-conventions) + - [Git and GitHub](#git-and-github) + - [Python](#python) + - [Markdown](#markdown) +- [Testing](#testing) +- [Documentation](#documentation) + +## Code of Conduct + +Please read [`CODE_OF_CONDUCT.md`][code-of-conduct] before contributing. + +## Getting started + +To start contributing, first ensure your system meets the [requirements][readme-requirements]. Next, install the +required Python packages, and [pre-commit hooks][pre-commit] using: + +```shell +make requirements +``` + +It is better to use the above make command, rather than `pip install -r requirements.txt` and `pre-commit install`, as +the command will ensure your pre-commit hooks are up-to-date with any changes made. + +The pre-commit hooks are a security feature to ensure no secrets[1](#footnote-1), large data files, and +Jupyter notebook outputs are accidentally committed into the repository. For more information about the pre-commit hooks used +in this repository, see the [documentation][docs-pre-commit-hooks]. + +## Code conventions + +We mainly follow [The GDS Way][gds-way] in our code conventions. + +### Git and GitHub + +We use Git to version control the source code; please read [The GDS Way][gds-way-git] for further details, including +information about writing good commit messages, using `git rebase` for local branches, and `git merge --no-ff` for +merges, as well as the entry on `git push --force-with-lease` instead of `git push -f`. + +If you want to modify the `.gitignore` files, see the template [documentation][docs-updating-gitignore] for further +details. + +Our source code is stored on GitHub. Pull requests into `master` require at +least one approved review. + +### Python + +For Python code, we follow [The GDS Way Python style guide][gds-way-python] with a line length of 120; the flake8 +pre-commit hook should help with this! + +### Markdown + +Local links can be written as normal, but external links should be referenced at the bottom of the Markdown file for +clarity. For example: + +```md +Use a local link to reference the [`README.md`](./README.md) file, but an external link for [GOV.UK][gov-uk]. + +[gov-uk]: https://www.gov.uk/ +``` + +We also try to wrap Markdown to a line length of 120 characters, but this is not strictly enforced in all cases, for +example with long hyperlinks. + +## Testing + +Tests are written using the [pytest][pytest] framework, with its configuration in the `pytest.ini` file. Note, only +tests in the `tests` folder are executed. To run the tests, execute the +following command in your terminal: + +```shell +pytest +``` + +### Code coverage + +Code coverage of Python scripts is measured using the [`coverage`][coverage] Python package; its configuration can be +found in `.coveragerc`. Note coverage only extends to Python scripts in the `govuk_tech_docs_sphinx_theme` folder. + +To run code coverage, and view it as an HTML report, execute the following commands in your terminal: + +```shell +coverage run -m pytest +coverage html +``` + +The HTML report can be accessed at `htmlcov/index.html`. + +## Documentation + +We write our documentation in [MyST Markdown][myst] for use in Sphinx. This is mainly stored in the `docs` folder, +unless it's more appropriate to store it elsewhere, like this file. + +Further information on how to write Sphinx documentation, and how to build it into a searchable website can be found +[here][docs-write-sphinx-documentation]. + +--- + +[1]: Only secrets of specific patterns are detected by the pre-commit hooks. See +[here][docs-pre-commit-hooks-secrets-definition] for further details. + +[code-of-conduct]: ./CODE_OF_CONDUCT.md +[coverage]: https://coverage.readthedocs.io/ +[docs-pre-commit-hooks]: ./docs/contributor_guide/pre_commit_hooks.md +[docs-pre-commit-hooks-secrets-definition]: ./docs/contributor_guide/pre_commit_hooks.md#definition-of-a-secret-according-to-detect-secrets +[docs-updating-gitignore]: ./docs/contributor_guide/updating_gitignore.md +[docs-write-sphinx-documentation]: ./docs/contributor_guide/writing_sphinx_documentation.md +[email]: mailto:gdsdatascience@digital.cabinet-office.gov.uk +[gds-way]: https://gds-way.cloudapps.digital/ +[gds-way-git]: https://gds-way.cloudapps.digital/standards/source-code.html +[gds-way-python]: https://gds-way.cloudapps.digital/manuals/programming-languages/python/python.html#python-style-guide +[myst]: https://myst-parser.readthedocs.io/ +[pre-commit]: https://pre-commit.com/ +[pytest]: https://docs.pytest.org/ +[readme-requirements]: ./README.md#requirements diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e8599c7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Crown Copyright (Government Digital Service) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..81b7c3b --- /dev/null +++ b/Makefile @@ -0,0 +1,67 @@ +.PHONY: + docs + docs_check_external_links + help + prepare_docs_folder + requirements + +.DEFAULT_GOAL := help + +## Install the Python requirements for contributors, and install pre-commit hooks +requirements: + python3 -m pip install -U pip setuptools + python3 -m pip install -r requirements.txt + pre-commit install + +## Create a `docs/_build` folder, if it doesn't exist. Otherwise delete any sub-folders and their contents within it +prepare_docs_folder: + if [ ! -d "./docs/_build" ]; then mkdir ./docs/_build; fi + find ./docs/_build -mindepth 1 -maxdepth 1 -type d -exec rm -rf {} \; + +## Compile the Sphinx documentation in HTML format in the docs/_build folder from a clean build +docs: prepare_docs_folder requirements + sphinx-build -b html ./docs ./docs/_build + +## Check external links in the Sphinx documentation using linkcheck in the docs/_build folder from a clean build +docs_check_external_links: prepare_docs_folder requirements + sphinx-build -b linkcheck ./docs ./docs/_build + +## Get help on all make commands; referenced from https://github.com/drivendata/cookiecutter-data-science +help: + @echo "$$(tput bold)Available rules:$$(tput sgr0)" + @echo + @sed -n -e "/^## / { \ + h; \ + s/.*//; \ + :doc" \ + -e "H; \ + n; \ + s/^## //; \ + t doc" \ + -e "s/:.*//; \ + G; \ + s/\\n## /---/; \ + s/\\n/ /g; \ + p; \ + }" ${MAKEFILE_LIST} \ + | LC_ALL='C' sort --ignore-case \ + | awk -F '---' \ + -v ncol=$$(tput cols) \ + -v indent=25 \ + -v col_on="$$(tput setaf 6)" \ + -v col_off="$$(tput sgr0)" \ + '{ \ + printf "%s%*s%s ", col_on, -indent, $$1, col_off; \ + n = split($$2, words, " "); \ + line_length = ncol - indent; \ + for (i = 1; i <= n; i++) { \ + line_length -= length(words[i]) + 1; \ + if (line_length <= 0) { \ + line_length = ncol - indent - length(words[i]) - 1; \ + printf "\n%*s ", -indent, " "; \ + } \ + printf "%s ", words[i]; \ + } \ + printf "\n"; \ + }' \ + | more $(shell test $(shell uname) = Darwin && echo '--no-init --raw-control-chars') diff --git a/README.md b/README.md new file mode 100644 index 0000000..7c442b8 --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# GOV.UK Tech Docs Sphinx Theme + +Brief overview of your project. + +> ℹ️ Where this documentation refers to the **root folder** we mean where this README.md is located. + +- [Getting started](#getting-started) + - [Requirements](#requirements) +- [Licence](#licence) +- [Contributing](#contributing) +- [Acknowledgements](#acknowledgements) + +## Getting started + +To be added. + +### Requirements + +- [Load environment variables][docs-loading-environment-variables] from `.envrc` + +To be added. + +## Licence + +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. + +## Contributing + +If you want to help us build, and improve `govuk-tech-docs-sphinx-theme`, view our +[contributing guidelines][contributing]. + +## Acknowledgements + +This project structure is based on the [`govcookiecutter`][govcookiecutter] template project. + +[contributing]: ./CONTRIBUTING.md +[govcookiecutter]: https://github.com/ukgovdatascience/govcookiecutter +[docs-loading-environment-variables]: ./docs/user_guide/loading_environment_variables.md +[pre-commit]: https://pre-commit.com/ diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000..e69de29 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..dfa26c5 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,16 @@ +# `docs` folder + +All documentation for the project should be included in this folder in either reStructuredText or Markdown files, with +acceptable formatting for Sphinx. + +To build the documentation, run the `docs` command from the [`Makefile`][docs-makefile] using the `make` utility at the +top-level of this Git repository. + +```shell +make docs +``` + +Guidance on how to write Sphinx documentation is supplied in the [contributor guide][writing-sphinx-documentation]. + +[docs-makefile]: ../docs/structure/README.md#makefile +[writing-sphinx-documentation]: ../docs/contributor_guide/writing_sphinx_documentation.md diff --git a/docs/_static/.gitkeep b/docs/_static/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..45c962a --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,299 @@ +# GOV.UK Tech Docs Sphinx Theme 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 sys +# sys.path.insert(0, os.path.abspath(".")) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# needs_sphinx = "1.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.napoleon", + "myst_parser", +] + +# 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", ".md"] +source_suffix = { + ".rst": "restructuredtext", + ".md": "markdown", +} + +# The encoding of source files. +# +# source_encoding = "utf-8-sig" + +# The master toctree document. +master_doc = "index" + +# General information about the project. +project = "GOV.UK Tech Docs Sphinx Theme" +author = "ukgovdatascience" + +# The version info for the project you're documenting, acts as replacement for |version| and |release|, also used in +# various other places throughout the built documents. +# The short X.Y.Z version. +version = "0.0.1" +# The full version, including alpha/beta/rc tags. +release = "0.0.1" + +# The language for content autogenerated by Sphinx. Refer to documentation for a list of supported languages. +# This is also used if you do content translation via gettext catalogs. Usually you set "language" from the command +# line for these cases. +# language = None + +# There are two options for replacing |today|: either, you set today to some non-false value, then it is used: +# +# today = "" +# +# Else, today_fmt is used as the format for a strftime call. +# +# today_fmt = "%B %d, %Y" + +# 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"] + +# The reST default role (used for this markup: `text`) to use for all documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as 'system message' paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- 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 = "alabaster" + +# Theme options are theme-specific and customize the look and feel of a theme further. For a list of options available +# for each theme, see the documentation. +# html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. " v documentation" by default. +# html_title = "None" + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top of the sidebar. +# html_logo = None + +# The name of an image file (relative to this directory) to use as a favicon of the docs. This file should be a +# Windows icon file (.ico) being 16x16 or 32x32 pixels large. +# html_favicon = None + +# 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"] + +# Add any extra paths that contain custom files (such as robots.txt or .htaccess) here, relative to this directory. +# These files are copied directly to the root of the documentation. +# html_extra_path = [] + +# If not None, a 'Last updated on:' timestamp is inserted at every page bottom, using the given strftime format. +# The empty string is equivalent to '%b %d, %Y'. +# html_last_updated_fmt = None + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will contain a tag referring to it. The +# value of this option must be the base URL from which the finished HTML is served. +# html_use_opensearch = "" + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' +# html_search_language = "en" + +# A dictionary with options for the search language support, empty by default. 'ja' uses this config value. 'zh' user +# can custom change `jieba` dictionary path. +# html_search_options = {"type": "default"} + +# The name of a javascript file (relative to the configuration directory) that implements a search results scorer. If +# empty, the default will be used. +# html_search_scorer = "scorer.js" + +# Output file base name for HTML help builder. +htmlhelp_basename = "govuk-tech-docs-sphinx-themedoc" + +# -- Options for LaTeX output ------------------------------------------------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # "papersize": "letterpaper", + + # The font size ('10pt', '11pt' or '12pt'). + # + # "pointsize": "10pt", + + # Additional stuff for the LaTeX preamble. + # + # "preamble": "", + + # Latex figure (float) alignment + # + # "figure_align": "htbp", +} + +# Grouping the document tree into LaTeX files. List of tuples (source start file, target name, title, author, +# documentclass [howto, manual, or own class]). +latex_documents = [ + ("index", + "govuk-tech-docs-sphinx-theme.tex", + u"GOV.UK Tech Docs Sphinx Theme Documentation", + u"ukgovdatascience", "manual"), +] + +# The name of an image file (relative to this directory) to place at the top of the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output ------------------------------------------------------------------------------------ + +# One entry per manual page. List of tuples (source start file, name, description, authors, manual section). +man_pages = [ + ("index", "govuk-tech-docs-sphinx-theme", u"GOV.UK Tech Docs Sphinx Theme Documentation", + [u"ukgovdatascience"], 1) +] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ---------------------------------------------------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples (source start file, target name, title, author, dir +# menu entry, description, category) +texinfo_documents = [ + ("index", "govuk-tech-docs-sphinx-theme", u"GOV.UK Tech Docs Sphinx Theme Documentation", + u"ukgovdatascience", "GOV.UK Tech Docs Sphinx Theme", + "Brief overview of your project.", "Miscellaneous"), +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = "footnote" + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + +# -- 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 diff --git a/docs/contributor_guide/CODE_OF_CONDUCT.md b/docs/contributor_guide/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..cc6912b --- /dev/null +++ b/docs/contributor_guide/CODE_OF_CONDUCT.md @@ -0,0 +1,2 @@ +```{include} ../../CODE_OF_CONDUCT.md +``` diff --git a/docs/contributor_guide/CONTRIBUTING.md b/docs/contributor_guide/CONTRIBUTING.md new file mode 100644 index 0000000..528a1dd --- /dev/null +++ b/docs/contributor_guide/CONTRIBUTING.md @@ -0,0 +1,10 @@ +# Contributing + +We love contributions! To help you understand our contributing guidelines, please see the `CONTRIBUTING.md` file in the +project repository on GitHub; you might want to read out +[Code of Conduct][code-of-conduct] first! + +If you still have questions, please [contact us][email] and we'd be happy to help! + +[code-of-conduct]: ./CODE_OF_CONDUCT.md +[email]: mailto:gdsdatascience@digital.cabinet-office.gov.uk diff --git a/docs/contributor_guide/README.md b/docs/contributor_guide/README.md new file mode 100644 index 0000000..f90d7e1 --- /dev/null +++ b/docs/contributor_guide/README.md @@ -0,0 +1,12 @@ +# Contributing guide + +This is the contributor guide for the `govuk-tech-docs-sphinx-theme` project. + +```{toctree} +:maxdepth: 2 +./CODE_OF_CONDUCT.md +./CONTRIBUTING.md +./pre_commit_hooks.md +./updating_gitignore.md +./writing_sphinx_documentation.md +``` diff --git a/docs/contributor_guide/pre_commit_hooks.md b/docs/contributor_guide/pre_commit_hooks.md new file mode 100644 index 0000000..ceffa02 --- /dev/null +++ b/docs/contributor_guide/pre_commit_hooks.md @@ -0,0 +1,109 @@ +# Pre-commit hooks + +This repository uses the Python package [`pre-commit`][pre-commit] to manage pre-commit hooks. Pre-commit hooks are +actions which are run automatically, typically on each commit, to perform some common set of tasks. For example, a +pre-commit hook might be used to run any code linting automatically, providing any warnings before code is committed, +ensuring that all of our code adheres to a certain quality standard. + +```{contents} +:local: +:depth: 2 +``` + +## Purpose + +For this repository, we are using `pre-commit` for a number of purposes: + +- Checking for secrets being committed accidentally — see [here](#definition-of-a-secret-according-to-detect-secrets) + for the definition of a "secret"; +- Checking for any large files (over 5 MB) being committed; and +- Cleaning Jupyter notebooks, which means removing all outputs and execution counts. + +We have configured `pre-commit` to run automatically on _every commit_. By running on each commit, we ensure that +`pre-commit` will be able to detect all contraventions and keep our repository in a healthy state. + +## Installation + +In order for `pre-commit` to run, action is needed to configure it on your system. + +- Install the `pre-commit` package into your Python environment from `requirements.txt`; and +- Run `pre-commit install` in your terminal to set up `pre-commit` to run when code is _committed_. + +## Using the `detect-secrets` pre-commit hook + +> ⚠️ The `detect-secrets` package does its best to prevent accidental committing of secrets, but it can't catch +> everything. **It doesn't replace good software development practices!** See the definition of a secret +> [here](#definition-of-a-secret-according-to-detect-secrets) for further information. + +We use [`detect-secrets`][detect-secrets] to check that no secrets, as defined +[here](#definition-of-a-secret-according-to-detect-secrets), are accidentally committed. This hook requires you to +generate a baseline file if one is not already present within the root directory. To create the baseline file, run the +following at the root of the repository: + +```shell +detect-secrets scan > .secrets.baseline +``` + +Next, audit the baseline that has been generated by running: + +```shell +detect-secrets audit .secrets.baseline +``` + +When you run this command, you'll enter an interactive console and be presented with a list of high-entropy string +and/or anything which _could_ be a secret, and asked to verify whether this is the case. By doing this, the hook will +be in a position to know if you're later committing any _new_ secrets to the repository, and it will be able to alert +you accordingly. + +### Definition of a "secret" according to `detect-secrets` + +The [`detect-secrets` documentation][detect-secrets], as of January 2021, says it works: + +> ...by running periodic diff outputs against heuristically crafted \[regular expression\] statements, to identify +> whether any new secret has been committed. + +This means it uses regular expression patterns to scan your code changes for anything that **looks like a secret +according to one or more of these regular expression patterns**. By definition, there are only a limited number of +patterns, so the `detect-secrets` package cannot detect every conceivable type of secret. + +To understand what types of secrets will be detected, read the [caveats][detect-secrets-caveats], and the list of +[supported plugins][detect-secrets-plugins] that the package uses. Also, you should use secret variable names that +contain words that will trip the KeywordDetector plugin; see the `DENYLIST` variable +[here][detect-secrets-keyword-detector] for the full list of words. + +### If `pre-commit` detects secrets during commit + +If `pre-commit` detects any secrets when you try to create a commit, it will detail what it found and where to go to +check the secret. + +If the detected secret is a false-positive, you should update the `.secrets.baseline` through the following steps: + +- Run `detect-secrets scan --update .secrets.baseline` from the root folder in the terminal to index the + false-positive(s); +- Next, audit all indexed secrets via `detect-secrets audit .secrets.baseline` (the same as during initial set-up, if a + `.secrets.baseline` doesn't exist); and +- Finally, ensure that you commit the updated `.secrets.baseline` in the same commit as the false-positive(s) it has + been updated for. + +If the detected secret is actually a secret (or other sensitive information), remove the secret and re-commit. There is +no need to update the `.secrets.baseline` file in this case. + +If your commit contains a mixture of false-positives and actual secrets, remove the actual secrets first before +updating and auditing the `.secrets.baseline` file. + +## Keeping specific Jupyter notebook outputs + +It may be necessary or useful to keep certain output cells of a Jupyter notebook, for example charts or graphs +visualising some set of data. To do this, add the following comment at the top of the input block: + +```julia +# [keep_output] +``` + +This will tell the hook not to strip the resulting output of this cell, allowing it to be committed. + +[detect-secrets]: https://github.com/Yelp/detect-secrets +[detect-secrets-caveats]: https://github.com/Yelp/detect-secrets#caveats +[detect-secrets-keyword-detector]: https://github.com/Yelp/detect-secrets/blob/master/detect_secrets/plugins/keyword.py +[detect-secrets-plugins]: https://github.com/Yelp/detect-secrets#currently-supported-plugins +[pre-commit]: https://pre-commit.com/ diff --git a/docs/contributor_guide/updating_gitignore.md b/docs/contributor_guide/updating_gitignore.md new file mode 100644 index 0000000..1034244 --- /dev/null +++ b/docs/contributor_guide/updating_gitignore.md @@ -0,0 +1,9 @@ +# Updating the `.gitignore` file + +The `.gitignore` used in this repository was created with generic exclusions from [gitignore.io][gitignore-io], with +project-specific exclusions listed afterwards. + +If you want to add exclusions for new programming languages and/or IDEs, use the first line to recreate the generic +exclusions from [gitignore.io][gitignore-io]. Add all other project-specific exclusions afterwards. + +[gitignore-io]: https://www.toptal.com/developers/gitignore diff --git a/docs/contributor_guide/writing_sphinx_documentation.md b/docs/contributor_guide/writing_sphinx_documentation.md new file mode 100644 index 0000000..eb22465 --- /dev/null +++ b/docs/contributor_guide/writing_sphinx_documentation.md @@ -0,0 +1,143 @@ +# Writing Sphinx documentation + +This project is set up to produce documentation using [Sphinx][sphinx]; this page should give you a quick overview on +how to write documentation for it. If you're looking for information on how to write **good** documentation take a look +[here][writethedocs]; for Agile projects, consider [documenting late][agilemodeling] as well. + +```{contents} +:local: +:depth: 2 +``` + +## Why should I bother? And why Sphinx? + +Keeping as much of the documentation in a centralised location is a good thing — it means contributors, users, and +anyone else can quickly find as much information as they need to understand and/or run what you've done. + +Sphinx is a Python-based package to compile documentation into different formats, including HTML. This means you can +write your documentation and, with a single terminal command, build it into a searchable website. + +It's widely used, such as for the documentation of the [pandas][pandas], and [PyTorch][pytorch] Python packages as well +as many [others][sphinx-examples], and is highly customisable with different extensions, and themes. Included with this +project is: + +- Support for both [reStructuredText (ReST)][rest], and [ReST-enabled Markdown][myst]; +- Automatic building of documentation from Python docstrings; and +- Support for [ReStructuredText][docstring-rst], [NumPy][docstring-numpy], or [Google][docstring-google] docstring + formats. + +### Creating a searchable website + +To create a website with your documentation, run the following command in your terminal at the top-level of this +project: + +```shell +make docs +``` + +This should create an HTML version of your documentation accessible from `docs/_build/index.html`. + +## Writing in reStructuredText + +Sphinx provides [good documentation][sphinx-rst] on writing in ReST — we would highly recommend reading that for +guidance. We will cover automatically creating docstrings in the next subsection. + +### Automatically creating docstring documentation (ReST) + +Let us say that `govuk_tech_docs_sphinx_theme/__init__.py` has functions called `hello` and `world` imported into it, +and both have docstrings. To automatically generate docstring documentation, create a ReST file, and add the following +line to reference the `govuk_tech_docs_sphinx_theme` module: + +```rest +.. currentmodule:: govuk_tech_docs_sphinx_theme +``` + +Then, elsewhere in the body, call the [`autosummary`][sphinx-autosummary] directive to generate the docstrings as ReST +stub files. + +```rest +.. autosummary:: + :toctree: api/ + + hello + world + +``` + +This will create something similar to the pandas [API reference][pandas-api-reference]. + +## Writing in ReST-enabled Markdown + +We use the [`myst-parser`][myst] package (MyST) to write Markdown that can also include ReST elements; the package +[documentation][myst] is detailed, so we would recommend reviewing it. We will cover some of the more widely used +elements in the following subsections. + +### Embedding ReST directives + +Most ReST directives can be embedded into MyST Markdown — see [here][myst-rst-directives] for further details. + +### Automatically creating docstring documentation (MyST Markdown) + +Let us say that `govuk_tech_docs_sphinx_theme/__init__.py` has functions called `hello` and `world` imported into it, +and both have docstrings. To automatically generate docstring documentation, create a Markdown file, and add the +following line to reference the `govuk_tech_docs_sphinx_theme` module: + +````md +```{eval-rst} +.. currentmodule:: govuk_tech_docs_sphinx_theme +``` +```` + +Then, elsewhere in the body, call the [`autosummary`][sphinx-autosummary] directive to generate the docstrings as ReST +stub files. + +````md +```{eval-rst} +.. autosummary:: + :toctree: api/ + + hello + world + +``` +```` + +### Including Markdown files outside the `docs` folder + +MyST lets you include Markdown files outside the `docs` folder [easily][myst-include]. + +If a Markdown file (`../example.md`) only contains links that do not reference anything else in this project (including +images), create a Markdown file within the `docs` folder with the following lines: + +````md +```{include} ../example.md +``` +```` + +However, if it includes relative links referencing other files in this project (including images), we need to tell MyST +what those links actually refer. For example, if the relative link is `../hello/world.md`, we need to create a Markdown +file within the `docs` folder with the following lines: + +````md +```{include} ../example.md +:relative-docs: ../hello +:relative-images: +``` +```` + +[agilemodeling]: http://agilemodeling.com/essays/documentLate.htm +[docstring-google]: http://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings +[docstring-numpy]: https://numpydoc.readthedocs.io/en/latest/format.html +[docstring-rst]: https://www.python.org/dev/peps/pep-0287/ +[myst]: https://myst-parser.readthedocs.io/ +[myst-include]: https://myst-parser.readthedocs.io/en/latest/using/howto.html#include-a-file-from-outside-the-docs-folder-like-readme-md +[myst-rst-directives]: https://myst-parser.readthedocs.io/en/latest/using/syntax.html#directives-a-block-level-extension-point +[pandas]: https://pandas.pydata.org/docs/ +[pandas-api-reference]: https://pandas.pydata.org/docs/reference/index.html +[pytorch]: https://pytorch.org/docs/stable/index.html +[rest]: https://docutils.readthedocs.io/en/sphinx-docs/user/rst/quickstart.html +[sphinx]: https://www.sphinx-doc.org/ +[sphinx-autosummary]: https://www.sphinx-doc.org/en/master/usage/extensions/autosummary.html +[sphinx-examples]: https://www.sphinx-doc.org/en/master/examples.html +[sphinx-rst]: https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html +[writethedocs]: https://www.writethedocs.org/guide/writing/beginners-guide-to-docs/ diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..b00ae66 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,10 @@ +# GOV.UK Tech Docs Sphinx Theme documentation + +Here is the documentation for the GOV.UK Tech Docs Sphinx Theme project. + +```{toctree} +:maxdepth: 2 +./user_guide/README.md +./contributor_guide/README.md +./structure/README.md +``` diff --git a/docs/structure/README.md b/docs/structure/README.md new file mode 100644 index 0000000..d1fda92 --- /dev/null +++ b/docs/structure/README.md @@ -0,0 +1,133 @@ +# `govuk-tech-docs-sphinx-theme` structure + +This page provides information on the repository's structure. The repository's folder structure is explained here: + +```{toctree} +:maxdepth: 2 +./docs.md +./govuk_tech_docs_sphinx_theme.md +./tests.md +``` + +## Top-level files + +Each subsection here contains a brief description about the files at the top-level of this Git repository. + +### `.coveragerc` + +A file containing configuration settings for the [`coverage`][coverage] Python package. When executed with +[`pytest`][pytest] using the following command: + +```shell +coverage run -m pytest +coverage html +``` + +a code coverage report in HTML will be produced on the code in the `govuk_tech_docs_sphinx_theme` folder. This HTMl +report can be accessed at `htmlcov/index.html`. + +### `.envrc` + +A file containing environment variables for the Git repository that can be selectively loaded. This uses the +[`direnv`][direnv] shell extension; see their documentation for further information. + +This file contains a `sed` command to output a `.env` file with all the environment variables. This may be useful for +sourcing environment variables, for example in conjunction with PyCharm's EnvFile plugin. + +To ensure this `sed` command works correctly, make sure any file paths listed in this file are absolute file paths, or +relative file paths that do not use other environment variables. For example: + +```shell +export DIR_DATA=$(pwd)/data # fine +export DIR_DATA_EXTERNAL=$(pwd)/data/external # fine +export DIR_DATA_EXTERNAL=./data/external # fine +export DIR_DATA_EXTERNAL=$DIR_DATA/external # will break the `sed` command! +``` + +### `.flake8` + +A configuration file for the [`flake8`][flake8] Python package that provides linting. This file is based on the +[common configuration][gds-way-flake8] described on [The GDS Way][gds-way]. + +### `.gitignore` + +A `.gitignore` file to ignore certain files and folders from this Git repository. See the +[contributor guide][docs-updating-gitignore] for further information about modifying this file. + +### `.pre-commit-config.yaml` + +A pre-commit hook configuration file. See the [contributor guide][docs-pre-commit-hooks] for further details. + +### `.secrets.baseline` + +Baseline file for the [`detect-secrets`][detect-secrets] package; this package detects secrets, and, in conjunction +with `pre-commit`, prevents them from being committed to the repository. The baseline file flags secret-like data that +the user deliberately wishes to commit the to repository. + +### `CODE_OF_CONDUCT.md` + +The [Code of Conduct][code-of-conduct] for contributors to this project, including maintainers and `ukgovdatascience` +organisation owners. + +### `conftest.py` + +File to contain shared fixture functions for the [pytest][pytest] tests in the `tests` folder. + +### `CONTRIBUTING.md` + +The [contributing guidelines][contributing] for this project. + +### `LICENSE` + +The licence for this project. 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` + +The `Makefile` contains a set of commands for the `make` utility. Run the `help` command for further information at the +top-level of the Git repository. + +```shell +make help +``` + +### `pytest.ini` + +A file containing configuration settings for the [`pytest`][pytest] Python package. To run tests within the `tests` +folder, execute the following command: + +```shell +pytest +``` + +### `README.md` + +An overview of the Git repository, including all necessary instructions to execute the code. + +### `requirements.txt` + +A list of Python package requirements for this Git repository, which can be installed using the `pip install` command. + +```shell +pip install --requirement requirements.txt +``` + +Alternatively, to install the requirements file along with pre-commit hooks, run the following command: + +```shell +make requirements +``` + +[code-of-conduct]:../contributor_guide/CODE_OF_CONDUCT.md +[contributing]: ../contributor_guide/CONTRIBUTING.md +[coverage]: https://coverage.readthedocs.io/ +[detect-secrets]: https://github.com/Yelp/detect-secrets +[direnv]: https://direnv.net/ +[docs-pre-commit-hooks]: ../contributor_guide/pre_commit_hooks.md +[docs-tests]: ./tests.md +[docs-updating-gitignore]: ../contributor_guide/updating_gitignore.md +[flake8]: https://gitlab.com/pycqa/flake8 +[gds-way]: https://gds-way.cloudapps.digital +[gds-way-flake8]: https://gds-way.cloudapps.digital/manuals/programming-languages/python/python.html#common-configuration +[pytest]: https://docs.pytest.org/ diff --git a/docs/structure/docs.md b/docs/structure/docs.md new file mode 100644 index 0000000..b95ce84 --- /dev/null +++ b/docs/structure/docs.md @@ -0,0 +1,3 @@ +```{include} ../README.md +:relative-docs: ../docs +``` diff --git a/docs/structure/govuk_tech_docs_sphinx_theme.md b/docs/structure/govuk_tech_docs_sphinx_theme.md new file mode 100644 index 0000000..31cc208 --- /dev/null +++ b/docs/structure/govuk_tech_docs_sphinx_theme.md @@ -0,0 +1,2 @@ +```{include} ../../govuk_tech_docs_sphinx_theme/README.md +``` diff --git a/docs/structure/tests.md b/docs/structure/tests.md new file mode 100644 index 0000000..66d3ee5 --- /dev/null +++ b/docs/structure/tests.md @@ -0,0 +1,2 @@ +```{include} ../../tests/README.md +``` diff --git a/docs/user_guide/README.md b/docs/user_guide/README.md new file mode 100644 index 0000000..14e2735 --- /dev/null +++ b/docs/user_guide/README.md @@ -0,0 +1,8 @@ +# User guide + +This is the user guide for the `govuk-tech-docs-sphinx-theme` project. + +```{toctree} +:maxdepth: 2 +./loading_environment_variables.md +``` diff --git a/docs/user_guide/loading_environment_variables.md b/docs/user_guide/loading_environment_variables.md new file mode 100644 index 0000000..e69210b --- /dev/null +++ b/docs/user_guide/loading_environment_variables.md @@ -0,0 +1,78 @@ +# Loading environment variables + +We use [`direnv`][direnv] to load environment variables, as it ensures you only have project-specific variables loaded +_when you are inside the project_, otherwise these variables are not loaded. This can prevent accidental conflicts +with identically named variables. + +```{contents} +:local: +:depth: 2 +``` + +## Using `direnv` + +To load the environment variables, first [install `direnv`](#installing-direnv), and make sure you have a `.secrets` +file to [store secrets and credentials](#storing-secrets-and-credentials). Then: + +1. Open your terminal; +2. Navigate to the project folder; and + - You should see the following message: + ```shell + direnv: error .envrc is blocked. Run `direnv allow` to approve its content. + ``` +3. Allow `direnv`. + ```shell + direnv allow + ``` + +You only need to do this **once**, and again each time `.envrc` and `.secrets` are modified. + +### Installing `direnv` + +These instructions assume you are running on macOS with administrator privileges using a bash terminal. For other ways +of installing `direnv`, and its shell hooks, consult the package's [documentation][direnv]. + +1. Open your terminal; +2. Install `direnv` via [Homebrew][homebrew]; + ```shell + brew install direnv + ``` +3. Add the shell hooks to your `.bash_profile`; + ```shell + echo 'eval "$(direnv hook bash)"' >> ~/.bash_profile + ``` +4. Check that the shell hooks have been added correctly; and + ```shell + cat ~/.bash_profile + ``` + - This should display `eval "$(direnv hook bash)"` +5. Restart your terminal. + +## Storing secrets and credentials + +Secrets and credentials must be stored in the `.secrets` file. **This file is not version-controlled**, so no secrets +should be committed to GitHub. + +In your terminal navigate to the root folder, and create a `.secrets` file. + +```shell +touch .secrets +``` + +Open this new `.secrets` file using your preferred text editor, and add any secrets as environmental variables. For +example, to add a JSON credentials file for Google BigQuery, save the following changes to `.secrets`. + +```shell +export GOOGLE_APPLICATION_CREDENTIALS="path/to/credentials.json" +``` + +Once complete, make sure the `.secrets` file has the following line uncommented out: + +```shell +source_env ".secrets" +``` + +This ensures [`direnv`][direnv] loads the `.secrets` file via `.envrc` **without** version-controlling `.secrets`. + +[direnv]: https://direnv.net/ +[homebrew]: https://brew.sh/ diff --git a/govuk_tech_docs_sphinx_theme/README.md b/govuk_tech_docs_sphinx_theme/README.md new file mode 100644 index 0000000..356c12d --- /dev/null +++ b/govuk_tech_docs_sphinx_theme/README.md @@ -0,0 +1,13 @@ +# `govuk_tech_docs_sphinx_theme` package + +All functions for this project, should be stored in this folder. **All tests should be stored in the `tests` folder**, +which is one-level above this folder in the main project directory. + +Feel free to create/rename/delete these folders as required, as they will not be necessary for each and every project. + +It is strongly suggested that you import functions in the `govuk_tech_docs_sphinx_theme` `__init__.py` script. You +should also try to use absolute imports in this script whenever possible; relative imports are not discouraged, but can +be an issue for projects where the directory structure is likely to change. See [PEP 328][pep-328] for further +information. + +[pep-328]: https://www.python.org/dev/peps/pep-0328/ diff --git a/govuk_tech_docs_sphinx_theme/__init__.py b/govuk_tech_docs_sphinx_theme/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..e2be8dc --- /dev/null +++ b/pytest.ini @@ -0,0 +1,5 @@ +[pytest] +addopts = -vv --doctest-modules +doctest_optionflags = NORMALIZE_WHITESPACE +testpaths = + ./tests diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..fa38d50 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +coverage +detect-secrets +flake8 +myst-parser +pre-commit +pytest +Sphinx diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..9e1e405 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,3 @@ +# `tests` folder + +All tests for the functions defined in the `govuk_tech_docs_sphinx_theme` folder should be stored here.