From 04dd76979e8f2ad0d395e9f55b73ed619ad58b62 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:23:28 +0200 Subject: [PATCH 01/41] Mave __version__ to __init__.py Solves lint error --- {{cookiecutter.directory_name}}/.bumpversion.cfg | 2 +- .../{{cookiecutter.package_name}}/__init__.py | 2 +- .../{{cookiecutter.package_name}}/__version__.py | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 {{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/__version__.py diff --git a/{{cookiecutter.directory_name}}/.bumpversion.cfg b/{{cookiecutter.directory_name}}/.bumpversion.cfg index bb9563d4..5cd6327c 100644 --- a/{{cookiecutter.directory_name}}/.bumpversion.cfg +++ b/{{cookiecutter.directory_name}}/.bumpversion.cfg @@ -4,7 +4,7 @@ current_version = {{ cookiecutter.version }} [comment] comment = The contents of this file cannot be merged with that of setup.cfg until https://github.com/c4urself/bump2version/issues/185 is resolved -[bumpversion:file:{{ cookiecutter.package_name }}/__version__.py] +[bumpversion:file:{{ cookiecutter.package_name }}/__init__.py] search = __version__ = "{current_version}" replace = __version__ = "{new_version}" diff --git a/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/__init__.py b/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/__init__.py index 418484ea..939ed008 100644 --- a/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/__init__.py +++ b/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/__init__.py @@ -1,9 +1,9 @@ """Documentation about {{ cookiecutter.package_name }}""" import logging -from .__version__ import __version__ logging.getLogger(__name__).addHandler(logging.NullHandler()) __author__ = "{{ cookiecutter.full_name }}" __email__ = "{{ cookiecutter.email }}" +__version__ = "{{ cookiecutter.version }}" diff --git a/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/__version__.py b/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/__version__.py deleted file mode 100644 index a955058c..00000000 --- a/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/__version__.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "{{ cookiecutter.version }}" From 501bef528bd2b39fb40c275c08d6c1e38bbe4121 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:24:09 +0200 Subject: [PATCH 02/41] Removed `.pylintrc` file, was too strict, too soon --- {{cookiecutter.directory_name}}/.pylintrc | 597 ---------------------- 1 file changed, 597 deletions(-) delete mode 100644 {{cookiecutter.directory_name}}/.pylintrc diff --git a/{{cookiecutter.directory_name}}/.pylintrc b/{{cookiecutter.directory_name}}/.pylintrc deleted file mode 100644 index 659dd6e6..00000000 --- a/{{cookiecutter.directory_name}}/.pylintrc +++ /dev/null @@ -1,597 +0,0 @@ -[MASTER] - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. -extension-pkg-whitelist= - -# Specify a score threshold to be exceeded before program exits with error. -fail-under=10 - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS - -# Add files or directories matching the regex patterns to the blacklist. The -# regex matches against base names, not paths. -ignore-patterns= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use. -jobs=1 - -# Control the amount of potential inferred values when inferring a single -# object. This can help the performance when dealing with large functions or -# complex, nested conditions. -limit-inference-results=100 - -# List of plugins (as comma separated values of python module names) to load, -# usually to register additional checkers. -load-plugins= - -# Pickle collected data for later comparisons. -persistent=yes - -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode=yes - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once). You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use "--disable=all --enable=classes -# --disable=W". -disable=apply-builtin, - backtick, - bad-inline-option, - bad-python3-import, - basestring-builtin, - buffer-builtin, - cmp-builtin, - cmp-method, - coerce-builtin, - coerce-method, - comprehension-escape, - delslice-method, - deprecated-itertools-function, - deprecated-operator-function, - deprecated-pragma, - deprecated-str-translate-call, - deprecated-string-function, - deprecated-sys-function, - deprecated-types-field, - deprecated-urllib-function, - dict-items-not-iterating, - dict-iter-method, - dict-keys-not-iterating, - dict-values-not-iterating, - dict-view-method, - div-method, - duplicate-code, - empty-docstring, - eq-without-hash, - exception-escape, - exception-message-attribute, - execfile-builtin, - file-builtin, - file-ignored, - filter-builtin-not-iterating, - getslice-method, - hex-method, - idiv-method, - import-star-module-level, - indexing-exception, - input-builtin, - intern-builtin, - invalid-str-codec, - locally-disabled, - long-builtin, - long-suffix, - map-builtin-not-iterating, - metaclass-assignment, - missing-module-docstring, - next-method-called, - next-method-defined, - no-absolute-import, - non-ascii-bytes-literal, - nonzero-method, - oct-method, - old-division, - old-ne-operator, - old-octal-literal, - old-raise-syntax, - parameter-unpacking, - print-statement, - raising-string, - range-builtin-not-iterating, - raw_input-builtin, - raw-checker-failed, - rdiv-method, - reduce-builtin, - reload-builtin, - round-builtin, - setslice-method, - standarderror-builtin, - suppressed-message, - sys-max-int, - unichr-builtin, - unicode-builtin, - unpacking-in-except, - unsubscriptable-object, - use-symbolic-message-instead, - useless-suppression, - using-cmp-argument, - xrange-builtin, - xreadlines-attribute, - zip-builtin-not-iterating - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable=c-extension-no-member - - -[REPORTS] - -# Python expression which should return a score less than or equal to 10. You -# have access to the variables 'error', 'warning', 'refactor', and 'convention' -# which contain the number of messages in each category, as well as 'statement' -# which is the total number of statements analyzed. This score is used by the -# global evaluation report (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details. -#msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio). You can also give a reporter class, e.g. -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Tells whether to display a full report or only the messages. -reports=no - -# Activate the evaluation score. -score=yes - - -[REFACTORING] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - -# Complete name of functions that never returns. When checking for -# inconsistent-return-statements if a never returning function is called then -# it will be considered as an explicit return statement and no message will be -# printed. -never-returning-functions=sys.exit - - -[BASIC] - -# Naming style matching correct argument names. -argument-naming-style=snake_case - -# Regular expression matching correct argument names. Overrides argument- -# naming-style. -#argument-rgx= - -# Naming style matching correct attribute names. -attr-naming-style=snake_case - -# Regular expression matching correct attribute names. Overrides attr-naming- -# style. -#attr-rgx= - -# Bad variable names which should always be refused, separated by a comma. -bad-names=foo, - bar, - baz, - toto, - tutu, - tata - -# Bad variable names regexes, separated by a comma. If names match any regex, -# they will always be refused -bad-names-rgxs= - -# Naming style matching correct class attribute names. -class-attribute-naming-style=any - -# Regular expression matching correct class attribute names. Overrides class- -# attribute-naming-style. -#class-attribute-rgx= - -# Naming style matching correct class names. -class-naming-style=PascalCase - -# Regular expression matching correct class names. Overrides class-naming- -# style. -#class-rgx= - -# Naming style matching correct constant names. -const-naming-style=UPPER_CASE - -# Regular expression matching correct constant names. Overrides const-naming- -# style. -#const-rgx= - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - -# Naming style matching correct function names. -function-naming-style=snake_case - -# Regular expression matching correct function names. Overrides function- -# naming-style. -#function-rgx= - -# Good variable names which should always be accepted, separated by a comma. -good-names=i, - ex, - Run, - _ - -# Good variable names regexes, separated by a comma. If names match any regex, -# they will always be accepted -good-names-rgxs= - -# Include a hint for the correct naming format with invalid-name. -include-naming-hint=no - -# Naming style matching correct inline iteration names. -inlinevar-naming-style=any - -# Regular expression matching correct inline iteration names. Overrides -# inlinevar-naming-style. -#inlinevar-rgx= - -# Naming style matching correct method names. -method-naming-style=snake_case - -# Regular expression matching correct method names. Overrides method-naming- -# style. -#method-rgx= - -# Naming style matching correct module names. -module-naming-style=snake_case - -# Regular expression matching correct module names. Overrides module-naming- -# style. -#module-rgx= - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -# These decorators are taken in consideration only for invalid-name. -property-classes=abc.abstractproperty - -# Naming style matching correct variable names. -variable-naming-style=snake_case - -# Regular expression matching correct variable names. Overrides variable- -# naming-style. -#variable-rgx= - - -[SPELLING] - -# Limits count of emitted suggestions for spelling mistakes. -max-spelling-suggestions=4 - -# Spelling dictionary name. Available dictionaries: none. To make it work, -# install the python-enchant package. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains the private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to the private dictionary (see the -# --spelling-private-dict-file option) instead of raising a message. -spelling-store-unknown-words=no - - -[STRING] - -# This flag controls whether inconsistent-quotes generates a warning when the -# character used as a quote delimiter is used inconsistently within a module. -check-quote-consistency=yes - -# This flag controls whether the implicit-str-concat should generate a warning -# on implicit string concatenation in sequences defined over several lines. -check-str-concat-over-line-jumps=yes - - -[VARIABLES] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid defining new builtins when possible. -additional-builtins= - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_, - _cb - -# A regular expression matching the name of dummy variables (i.e. expected to -# not be used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore. -ignored-argument-names=_.*|^ignored_|^unused_ - -# Tells whether we should check for unused import in __init__ files. -init-import=yes - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io - - -[SIMILARITIES] - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - -# Minimum lines number of a similarity. -min-similarity-lines=4 - - -[LOGGING] - -# The type of string formatting that logging methods do. `old` means using % -# formatting, `new` is for `{}` formatting. -logging-format-style=old - -# Logging modules to check that the string format arguments are in logging -# function parameter format. -logging-modules=logging - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME, - XXX, - TODO - -# Regular expression of note tags to take in consideration. -#notes-rgx= - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# Tells whether to warn about missing members when the owner of the attribute -# is inferred to be None. -ignore-none=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis). It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - -# List of decorators that change the signature of a decorated function. -signature-mutators= - - -[FORMAT] - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Maximum number of characters on a single line. -max-line-length=120 - -# Maximum number of lines in a module. -max-module-lines=1000 - -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma, - dict-separator - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -single-line-class-stmt=no - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - - -[IMPORTS] - -# List of modules that can be imported at any level, not just the top level -# one. -allow-any-import-level= - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=no - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Deprecated modules which should not be used, separated by a comma. -deprecated-modules=optparse,tkinter.tix - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled). -ext-import-graph= - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled). -import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled). -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - -# Couples of modules and preferred modules, separated by a comma. -preferred-modules= - - -[DESIGN] - -# Maximum number of arguments for function / method. -max-args=5 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Maximum number of boolean expressions in an if statement (see R0916). -max-bool-expr=5 - -# Maximum number of branch for function / method body. -max-branches=12 - -# Maximum number of locals for function / method body. -max-locals=15 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of return / yield for function / method body. -max-returns=6 - -# Maximum number of statements in function / method body. -max-statements=50 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__, - __new__, - setUp, - __post_init__ - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict, - _fields, - _replace, - _source, - _make - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=cls - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "BaseException, Exception". -overgeneral-exceptions=BaseException, - Exception From fc5af0158fa54504e47d19d34bd49c98d95555b3 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:24:39 +0200 Subject: [PATCH 03/41] Added docstring --- .../{{cookiecutter.package_name}}/my_module.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/my_module.py b/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/my_module.py index 4ad555d4..c6435357 100644 --- a/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/my_module.py +++ b/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/my_module.py @@ -3,4 +3,14 @@ # FIXME: put actual code here def hello(name): + """Say hello + + Example docstring using Google docstring format. + + Args: + name (str): Name to say hello to + + Returns: + str: Hello message + """ return f'Hello {name}!' From d361f0afac1ebf5b3eff2d574140c21ff41ccb01 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:25:06 +0200 Subject: [PATCH 04/41] Remove unused import --- tests/test_values.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/test_values.py b/tests/test_values.py index d4b07ff2..01d748a9 100644 --- a/tests/test_values.py +++ b/tests/test_values.py @@ -1,6 +1,3 @@ -import pytest - - def test_double_quotes_in_name_and_description(cookies): ctx = { "project_short_description": '"double quotes"', From 15278228e94e3fe8b38ad855191011c215d8b6f5 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:26:04 +0200 Subject: [PATCH 05/41] Run prospector before sonarcloud analysis --- .../.github/workflows/sonarcloud.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/{{cookiecutter.directory_name}}/.github/workflows/sonarcloud.yml b/{{cookiecutter.directory_name}}/.github/workflows/sonarcloud.yml index 1fde7d64..c24743eb 100644 --- a/{{cookiecutter.directory_name}}/.github/workflows/sonarcloud.yml +++ b/{{cookiecutter.directory_name}}/.github/workflows/sonarcloud.yml @@ -25,6 +25,8 @@ jobs: python3 --version - name: Install dependencies run: python3 -m pip install .[dev] + - name: Check style against standards using prospector + run: prospector --zero-exit --output-format grouped --output-format pylint:pylint-report.txt - name: Run unit tests with coverage run: pytest --cov --cov-report term --cov-report xml --junitxml=xunit-result.xml tests/ - name: Correct coverage paths From fbac64ffca1553bbc5f8047ac3e9d9594c92d678 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:26:31 +0200 Subject: [PATCH 06/41] Added instructions how to build docs without make --- {{cookiecutter.directory_name}}/README.dev.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/{{cookiecutter.directory_name}}/README.dev.md b/{{cookiecutter.directory_name}}/README.dev.md index 61cf613d..285c9965 100644 --- a/{{cookiecutter.directory_name}}/README.dev.md +++ b/{{cookiecutter.directory_name}}/README.dev.md @@ -65,7 +65,13 @@ cd docs make html ``` -The documentation will be in `docs/_build/` +The documentation will be in `docs/_build/html` + +If you do not have `make` use + +```shell +sphinx-build -b html docs docs/_build/html +``` ## Versioning From 598ad36898cdaa6570b7d2c67225d13dddf8e22a Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:27:16 +0200 Subject: [PATCH 07/41] Remove test examples Goto pytest docs for examples. Only test own code --- .../tests/test_my_module.py | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/{{cookiecutter.directory_name}}/tests/test_my_module.py b/{{cookiecutter.directory_name}}/tests/test_my_module.py index 76922037..e8e9f81d 100644 --- a/{{cookiecutter.directory_name}}/tests/test_my_module.py +++ b/{{cookiecutter.directory_name}}/tests/test_my_module.py @@ -1,30 +1,7 @@ -#!/usr/bin/env python - """Tests for the {{ cookiecutter.package_name }}.my_module module. """ -import pytest from {{ cookiecutter.package_name }} import my_module def test_hello(): assert my_module.hello('nlesc') == 'Hello nlesc!' - - -def test_something(): - assert True - - -def test_with_error(): - with pytest.raises(ValueError): - # Do something that raises a ValueError - raise(ValueError) - - -# Fixture example -@pytest.fixture -def an_object(): - return {} - - -def test_my_module(an_object): - assert an_object == {} From 3a98f3dc06debcdf15e8d66c2da6f49deeaa3e8e Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:28:29 +0200 Subject: [PATCH 08/41] Remove statements in project_setup.md already mentioned in README.dev.md --- {{cookiecutter.directory_name}}/project_setup.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/{{cookiecutter.directory_name}}/project_setup.md b/{{cookiecutter.directory_name}}/project_setup.md index 1977902e..fd155197 100644 --- a/{{cookiecutter.directory_name}}/project_setup.md +++ b/{{cookiecutter.directory_name}}/project_setup.md @@ -43,8 +43,7 @@ help you decide which tool to use for packaging. - Example tests that you should replace with your own meaningful tests (file: `test_my_module.py`) - The testing framework used is [PyTest](https://pytest.org) - [PyTest introduction](http://pythontesting.net/framework/pytest/pytest-introduction/) - - PyTest is listed as a development dependency, and can thus be installed with `pip3 install --editable .[dev]` -- Tests can be run with `pytest` + - PyTest is listed as a development dependency - This is configured in `setup.cfg` - The project uses [GitHub action workflows](https://docs.github.com/en/actions) to automatically run tests on GitHub infrastructure against multiple Python versions - Workflows can be found in [`.github/workflows`](.github/workflows/) @@ -62,9 +61,6 @@ help you decide which tool to use for packaging. ## Coding style conventions and code quality -- Check your code style with `prospector` -- You may need run `pip install --editable .[dev]` first, to install the required dependencies -- You can use `yapf` to fix the readability of your code style and `isort` to format and group your imports - [Relevant section in the guide](https://guide.esciencecenter.nl/#/best_practices/language_guides/python?id=coding-style-conventions) ## Continuous code quality @@ -78,8 +74,6 @@ help you decide which tool to use for packaging. - We recommend using [semantic versioning](https://guide.esciencecenter.nl/#/best_practices/releases?id=semantic-versioning). - For convenience, the package version is stored in a single place: `{{ cookiecutter.directory_name }}/.bumpversion.cfg`. - For updating the version number, make sure the dev dependencies are installed and run `bumpversion patch`, - `bumpversion minor`, or `bumpversion major` as appropriate. - Don't forget to update the version number before [making a release](https://guide.esciencecenter.nl/#/best_practices/releases)! ## Logging From 20ed7225fef0198701cff214415d31b817fe2e5f Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:29:17 +0200 Subject: [PATCH 09/41] Remove unused development dependencies --- {{cookiecutter.directory_name}}/setup.cfg | 5 ----- 1 file changed, 5 deletions(-) diff --git a/{{cookiecutter.directory_name}}/setup.cfg b/{{cookiecutter.directory_name}}/setup.cfg index d957df47..911007f0 100644 --- a/{{cookiecutter.directory_name}}/setup.cfg +++ b/{{cookiecutter.directory_name}}/setup.cfg @@ -49,16 +49,11 @@ install_requires = dev = bump2version prospector[with_pyroma] - yapf isort pytest pytest-cov - pycodestyle - docutils - pytest-runner sphinx sphinx_rtd_theme - recommonmark publishing = twine wheel From e4b962f1cb08a54f5d48c903ba19d2078bce3255 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:29:33 +0200 Subject: [PATCH 10/41] Enforce isort configuration --- {{cookiecutter.directory_name}}/setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.directory_name}}/setup.cfg b/{{cookiecutter.directory_name}}/setup.cfg index 911007f0..477b3d4e 100644 --- a/{{cookiecutter.directory_name}}/setup.cfg +++ b/{{cookiecutter.directory_name}}/setup.cfg @@ -65,7 +65,7 @@ include = {{ cookiecutter.package_name }}, {{ cookiecutter.package_name }}.* branch = True source = {{ cookiecutter.package_name }} -[tool:isort] +[isort] lines_after_imports = 2 force_single_line = 1 no_lines_before = FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER From 96d3aafb1e29bc9e95301e1f4d781b05ad8a2d36 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:31:07 +0200 Subject: [PATCH 11/41] Added tests for linting and verion bumping --- tests/test_project.py | 50 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/tests/test_project.py b/tests/test_project.py index 53f8cc8c..c2781e42 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -34,6 +34,7 @@ def run(args: Sequence[str], dirpath: os.PathLike) -> subprocess.CompletedProces @pytest.fixture def baked_with_development_dependencies(cookies): result = cookies.bake() + assert result.exit_code == 0 if IS_WINDOWS_CI: # Creating virtualenv does not work on Windows CI, # falling back to using current pip3 dir @@ -52,9 +53,9 @@ def baked_with_development_dependencies(cookies): def test_pytest(baked_with_development_dependencies): project_dir, bin_dir = baked_with_development_dependencies - pytest_output = run([f'{bin_dir}pytest'], project_dir) - assert pytest_output.returncode == 0 - assert '== 4 passed in' in pytest_output.stdout + result = run([f'{bin_dir}pytest'], project_dir) + assert result.returncode == 0 + assert '== 1 passed in' in result.stdout assert (project_dir / 'coverage.xml').exists() assert (project_dir / 'htmlcov/index.html').exists() @@ -72,8 +73,8 @@ def test_subpackage(baked_with_development_dependencies): if IS_WINDOWS_CI: # On Windows CI python and pip executable are in different paths bin_dir = '' - build_output = run([f'{bin_dir}python', 'setup.py', 'build'], project_dir) - assert build_output.returncode == 0 + result = run([f'{bin_dir}python', 'setup.py', 'build'], project_dir) + assert result.returncode == 0 assert (project_dir / 'build' / 'lib' / 'my_python_package' / 'mysub' / '__init__.py').exists() assert (project_dir / 'build' / 'lib' / 'my_python_package' / 'mysub' / 'mysub2' / '__init__.py').exists() @@ -81,7 +82,40 @@ def test_subpackage(baked_with_development_dependencies): def test_generate_api_docs(baked_with_development_dependencies): project_dir, bin_dir = baked_with_development_dependencies - build_output = run([f'{bin_dir}sphinx-build', '-b', 'html', 'docs', 'docs/_build/html'], project_dir) - assert build_output.returncode == 0 - assert 'build succeeded' in build_output.stdout + result = run([f'{bin_dir}sphinx-build', '-b', 'html', 'docs', 'docs/_build/html'], project_dir) + assert result.returncode == 0 + assert 'build succeeded' in result.stdout assert (project_dir / 'docs' / '_build' / 'html' / 'index.html').exists() + + +def test_prospector(baked_with_development_dependencies): + project_dir, bin_dir = baked_with_development_dependencies + + result = run([f'{bin_dir}prospector'], project_dir) + assert result.returncode == 0 + assert 'Messages Found: 0' in result.stdout + + +def test_isort_check(baked_with_development_dependencies): + project_dir, bin_dir = baked_with_development_dependencies + + result = run([f'{bin_dir}isort', '--recursive', '--check-only', 'my_python_package'], project_dir) + assert result.returncode == 0 + assert '' in result.stdout + + +def test_bumpversion(baked_with_development_dependencies): + project_dir, bin_dir = baked_with_development_dependencies + + original_version = '0.1.0' + assert original_version in (project_dir / 'setup.cfg').read_text('utf-8') + assert original_version in (project_dir / 'CITATION.cff').read_text('utf-8') + assert original_version in (project_dir / 'my_python_package' / '__init__.py').read_text('utf-8') + + result = run([f'{bin_dir}bumpversion', 'major'], project_dir) + assert result.returncode == 0 + assert '' in result.stdout + expected_version = '1.0.0' + assert expected_version in (project_dir / 'setup.cfg').read_text('utf-8') + assert expected_version in (project_dir / 'CITATION.cff').read_text('utf-8') + assert expected_version in (project_dir / 'my_python_package' / '__init__.py').read_text('utf-8') From f4e81eea79859ef27654724f7b32ad46d6699ac1 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:31:48 +0200 Subject: [PATCH 12/41] Consolidated test/lint/build into single matrix workflow Render workflows with escaped {{ --- cookiecutter.json | 3 +- .../.github/next_steps/05_linting.md | 2 +- .../.github/workflows/build.yml | 22 +++++++------ .../.github/workflows/lint.yml | 32 ------------------- .../.github/workflows/next_steps.yml | 20 ++++++------ .../.github/workflows/sonarcloud.yml | 4 +-- {{cookiecutter.directory_name}}/README.md | 3 +- 7 files changed, 28 insertions(+), 58 deletions(-) delete mode 100644 {{cookiecutter.directory_name}}/.github/workflows/lint.yml diff --git a/cookiecutter.json b/cookiecutter.json index ac197b6c..f45d92cb 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -1,8 +1,7 @@ { "directory_name": "my-python-project", "package_name": "my_python_package", - "_copy_without_render": [".github/workflows/*"], - "package_short_description": "", + "package_short_description": "Short description of package", "keyword1": "keyword1", "keyword2": "keyword2", "version": "0.1.0", diff --git a/{{cookiecutter.directory_name}}/.github/next_steps/05_linting.md b/{{cookiecutter.directory_name}}/.github/next_steps/05_linting.md index 385fee66..e2b32c24 100644 --- a/{{cookiecutter.directory_name}}/.github/next_steps/05_linting.md +++ b/{{cookiecutter.directory_name}}/.github/next_steps/05_linting.md @@ -2,7 +2,7 @@ title: 'Next step: Linting' --- -Your repository has a [workflow]({{ cookiecutter.repository }}/blob/main/.github/workflows/lint.yml) which [lints](https://en.wikipedia.org/wiki/Lint_(software)) your code after every push and when creating a pull request. +Your repository has a [workflow]({{ cookiecutter.repository }}/blob/main/.github/workflows/build.yml) which [lints](https://en.wikipedia.org/wiki/Lint_(software)) your code after every push and when creating a pull request. Linter workflow may fail if `description` or `keywords` field in [setup.cfg]({{ cookiecutter.repository }}/blob/main/setup.cfg) is empty. Please update these fields. To validate your changes run: diff --git a/{{cookiecutter.directory_name}}/.github/workflows/build.yml b/{{cookiecutter.directory_name}}/.github/workflows/build.yml index 3fdc9ebc..0a04be50 100644 --- a/{{cookiecutter.directory_name}}/.github/workflows/build.yml +++ b/{{cookiecutter.directory_name}}/.github/workflows/build.yml @@ -1,12 +1,12 @@ -name: build +name: Python package on: [push, pull_request] jobs: build: - name: Build for (${{ matrix.python-version }}, ${{ matrix.os }}) - runs-on: ${{ matrix.os }} + name: Build for (${{ '{{ ' -}} matrix.python-version }}, ${{ '{{ ' -}} matrix.os }}) + runs-on: ${{ '{{ ' -}} matrix.os }} strategy: fail-fast: false matrix: @@ -14,10 +14,10 @@ jobs: python-version: ['3.6', '3.7', '3.8', '3.9'] steps: - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ '{{ ' -}} matrix.python-version }} uses: actions/setup-python@v2 with: - python-version: ${{ matrix.python-version }} + python-version: ${{ '{{ ' -}} matrix.python-version }} - name: Python info shell: bash -l {0} run: | @@ -26,8 +26,12 @@ jobs: - name: Upgrade pip and install dependencies run: | python3 -m pip install --upgrade pip setuptools - python3 -m pip install .[publishing] + python3 -m pip install .[dev,publishing] + - name: Check style against standards using prospector + run: prospector + - name: Check import order + run: isort --recursive --check-only {{ cookiecutter.package_name }} + - name: Run unit tests + run: pytest -v - name: Verify that we can build the package - shell: bash -l {0} - run: | - python3 setup.py sdist bdist_wheel + run: python3 setup.py sdist bdist_wheel diff --git a/{{cookiecutter.directory_name}}/.github/workflows/lint.yml b/{{cookiecutter.directory_name}}/.github/workflows/lint.yml deleted file mode 100644 index ab502e86..00000000 --- a/{{cookiecutter.directory_name}}/.github/workflows/lint.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: lint - -on: [push, pull_request] - -jobs: - - lint: - name: Lint for (${{ matrix.python-version }}, ${{ matrix.os }}) - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] - python-version: ['3.6', '3.7', '3.8', '3.9'] - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Python info - shell: bash -l {0} - run: | - which python3 - python3 --version - - name: Install package and its dependencies - run: | - python3 -m pip install --upgrade pip setuptools - python3 -m pip install .[dev] - - name: Check style against standards using prospector - shell: bash -l {0} - run: prospector --zero-exit --output-format grouped --output-format pylint:pylint-report.txt diff --git a/{{cookiecutter.directory_name}}/.github/workflows/next_steps.yml b/{{cookiecutter.directory_name}}/.github/workflows/next_steps.yml index fbf0877b..02b9afb0 100644 --- a/{{cookiecutter.directory_name}}/.github/workflows/next_steps.yml +++ b/{{cookiecutter.directory_name}}/.github/workflows/next_steps.yml @@ -8,7 +8,7 @@ jobs: - name: Create Sonarcloud integration issue uses: JasonEtco/create-an-issue@v2 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ '{{ ' -}} secrets.GITHUB_TOKEN }} with: filename: .github/next_steps/01_sonarcloud_integration.md id: sonarcloud @@ -16,39 +16,39 @@ jobs: - name: Create citation data issue uses: JasonEtco/create-an-issue@v2 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ '{{ ' -}} secrets.GITHUB_TOKEN }} with: filename: .github/next_steps/02_citation.md id: citation - name: Create readthedocs issue uses: JasonEtco/create-an-issue@v2 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ '{{ ' -}} secrets.GITHUB_TOKEN }} with: filename: .github/next_steps/03_readthedocs.md id: readthedocs - name: Create Zenodo integration issue uses: JasonEtco/create-an-issue@v2 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ '{{ ' -}} secrets.GITHUB_TOKEN }} with: filename: .github/next_steps/04_zenodo_integration.md id: zenodo - name: Create linting issue uses: JasonEtco/create-an-issue@v2 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ '{{ ' -}} secrets.GITHUB_TOKEN }} with: filename: .github/next_steps/05_linting.md id: linting - name: List created issues run: | echo 'Created issues that must be completed to have fully working Python package: - * Sonarcloud integration ${{ steps.sonarcloud.outputs.url }} - * Zenodo integration ${{ steps.zenodo.outputs.url }} - * Read the Docs instructions ${{ steps.readthedocs.outputs.url }} - * Citation data ${{ steps.citation.outputs.url }} - * Linting fixes ${{ steps.linting.outputs.url }}' + * Sonarcloud integration ${{ '{{ ' -}} steps.sonarcloud.outputs.url }} + * Zenodo integration ${{ '{{ ' -}} steps.zenodo.outputs.url }} + * Read the Docs instructions ${{ '{{ ' -}} steps.readthedocs.outputs.url }} + * Citation data ${{ '{{ ' -}} steps.citation.outputs.url }} + * Linting fixes ${{ '{{ ' -}} steps.linting.outputs.url }}' - name: Cleanup files needed to create next steps issues run: | git config --global user.name 'NLeSC Python template' diff --git a/{{cookiecutter.directory_name}}/.github/workflows/sonarcloud.yml b/{{cookiecutter.directory_name}}/.github/workflows/sonarcloud.yml index c24743eb..61ca173d 100644 --- a/{{cookiecutter.directory_name}}/.github/workflows/sonarcloud.yml +++ b/{{cookiecutter.directory_name}}/.github/workflows/sonarcloud.yml @@ -34,5 +34,5 @@ jobs: - name: SonarCloud Scan uses: SonarSource/sonarcloud-github-action@master env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GITHUB_TOKEN: ${{ '{{' -}} secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ '{{' -}} secrets.SONAR_TOKEN }} diff --git a/{{cookiecutter.directory_name}}/README.md b/{{cookiecutter.directory_name}}/README.md index e86e4bae..c8dcc396 100644 --- a/{{cookiecutter.directory_name}}/README.md +++ b/{{cookiecutter.directory_name}}/README.md @@ -16,8 +16,7 @@ | Documentation | [![Documentation Status](https://readthedocs.org/projects/{{cookiecutter.directory_name}}/badge/?version=latest)](https://{{cookiecutter.directory_name}}.readthedocs.io/en/latest/?badge=latest) | | **GitHub Actions** |   | | Build | [![build]({{cookiecutter.repository}}/actions/workflows/build.yml/badge.svg)]({{cookiecutter.repository}}/actions/workflows/build.yml) | -| Metadata consistency | [![cffconvert]({{cookiecutter.repository}}/actions/workflows/cffconvert.yml/badge.svg)]({{cookiecutter.repository}}/actions/workflows/cffconvert.yml) | -| Lint | [![lint]({{cookiecutter.repository}}/actions/workflows/lint.yml/badge.svg)]({{cookiecutter.repository}}/actions/workflows/lint.yml) | +| Citation consistency | [![cffconvert]({{cookiecutter.repository}}/actions/workflows/cffconvert.yml/badge.svg)]({{cookiecutter.repository}}/actions/workflows/cffconvert.yml) | | SonarCloud | [![sonarcloud]({{cookiecutter.repository}}/actions/workflows/sonarcloud.yml/badge.svg)]({{cookiecutter.repository}}/actions/workflows/sonarcloud.yml) | | MarkDown link checker | [![markdown-link-check]({{cookiecutter.repository}}/actions/workflows/markdown-link-check.yml/badge.svg)]({{cookiecutter.repository}}/actions/workflows/markdown-link-check.yml) | From 047a5180f122a7aff4c132a29ca3fc29706d63ec Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:33:19 +0200 Subject: [PATCH 13/41] updated changelog --- CHANGELOG.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ed2a8cf..72ecacc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,32 @@ ## Unreleased +### Added + +* Tests for linting and version bumping +* Docstring for function + +### Changed + +* Renamed `project_name` to `directory_name` in cookiecutter questionnaire +* Initial linting is error free +* Consolidated test/lint/build into single matrix workflow +* Enforce isort configuration +* Default for `package_short_description` in cookiecutter questionnaire + +### Removed + +* `.pylintrc` file, was too strict, too soon +* Unused development dependencies +* Statements in project_setup.md already mentioned in README.dev.md +* Removed example tests for pytest + ## 0.4.0 ### Added * Instructions to add your existing code to directory generated by the NLeSC Python template [#202](https://github.com/NLeSC/python-template/issues/202) -* Keywords to questionaire [#270](https://github.com/NLeSC/python-template/issues/270) +* Keywords to questionnaire [#270](https://github.com/NLeSC/python-template/issues/270) * Next step issue generation workflow [#228](https://github.com/NLeSC/python-template/issues/228) * Next step issue for SonarCloud integration [#234](https://github.com/NLeSC/python-template/issues/234) * Next step issue for Zenodo integration [#235](https://github.com/NLeSC/python-template/issues/235) From 85e80cd7b52a8e4810f68d8369b256c8da1d0c33 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 07:55:21 +0200 Subject: [PATCH 14/41] Linkup CHANGELOG --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72ecacc1..fbc32df9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,15 +10,15 @@ ### Changed * Renamed `project_name` to `directory_name` in cookiecutter questionnaire -* Initial linting is error free -* Consolidated test/lint/build into single matrix workflow +* Initial linting is error free [#227](https://github.com/NLeSC/python-template/issues/227) +* Consolidated test/lint/build into single matrix workflow [@270](https://github.com/NLeSC/python-template/issues/276) * Enforce isort configuration * Default for `package_short_description` in cookiecutter questionnaire ### Removed * `.pylintrc` file, was too strict, too soon -* Unused development dependencies +* Unused development dependencies [#167](https://github.com/NLeSC/python-template/issues/167) * Statements in project_setup.md already mentioned in README.dev.md * Removed example tests for pytest From bab5abad5e141be553061b887d03185c4877c0ba Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 08:06:31 +0200 Subject: [PATCH 15/41] Show package_short_description default in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f5ead10..7d2d70a7 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ cookiecutter https://github.com/nlesc/python-template.git | ------------------------- | ------------- | ----------- | | directory_name | my-python-project | Name of the directory that contains the package. Avoid using spaces or uppercase letters for the best experience across operating systems. To get an impression of what will be generated, see the directory tree [below](https://github.com/NLeSC/python-template#step-33-read-about-what-was-just-generated) | | package_name | my_python_package | Name of the package. Avoid using spaces, dashes, or uppercase letters for the best experience across operating systems. | -| package_short_description |   | The information that you enter here will end up in the README, documentation, license, and setup.cfg, so it may be a good idea to prepare something in advance. | +| package_short_description | Short description of package | The information that you enter here will end up in the README, documentation, license, and setup.cfg, so it may be a good idea to prepare something in advance. | | keyword1 | keyword1 | A term that describes your package. | | keyword2 | keyword2 | Another term that describes your package. | | version | 0.1.0 |   | From 30412f7d59deac148a2e32e9f279af6e4cc97f6a Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 08:31:09 +0200 Subject: [PATCH 16/41] Typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbc32df9..766d2369 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ * Renamed `project_name` to `directory_name` in cookiecutter questionnaire * Initial linting is error free [#227](https://github.com/NLeSC/python-template/issues/227) -* Consolidated test/lint/build into single matrix workflow [@270](https://github.com/NLeSC/python-template/issues/276) +* Consolidated test/lint/build into single matrix workflow [#270](https://github.com/NLeSC/python-template/issues/276) * Enforce isort configuration * Default for `package_short_description` in cookiecutter questionnaire From 914b9a24c91bdb64aa5718f6120a7f6046ba81a3 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 08:54:41 +0200 Subject: [PATCH 17/41] Add link to CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 766d2369..7787b4f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ ### Removed -* `.pylintrc` file, was too strict, too soon +* `.pylintrc` file, was too strict, too soon [#267](https://github.com/NLeSC/python-template/issues/267) * Unused development dependencies [#167](https://github.com/NLeSC/python-template/issues/167) * Statements in project_setup.md already mentioned in README.dev.md * Removed example tests for pytest From 3614930f8acc3c473dfab1eed3ef70400b7f972c Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 09:17:44 +0200 Subject: [PATCH 18/41] Double remove --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7787b4f3..cd8bb973 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ * `.pylintrc` file, was too strict, too soon [#267](https://github.com/NLeSC/python-template/issues/267) * Unused development dependencies [#167](https://github.com/NLeSC/python-template/issues/167) * Statements in project_setup.md already mentioned in README.dev.md -* Removed example tests for pytest +* Example tests to explain pytest ## 0.4.0 From 8c0fd9dc121595840e83f666f1cb25d3281217f8 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 09:30:00 +0200 Subject: [PATCH 19/41] Ignore link checks of GH settings page and test pypi --- {{cookiecutter.directory_name}}/.mlc-config.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/{{cookiecutter.directory_name}}/.mlc-config.json b/{{cookiecutter.directory_name}}/.mlc-config.json index 54d24dcb..80d0d1aa 100644 --- a/{{cookiecutter.directory_name}}/.mlc-config.json +++ b/{{cookiecutter.directory_name}}/.mlc-config.json @@ -7,6 +7,12 @@ { "pattern": "^https://doi.org/" }, + { + "pattern": "/settings/secrets/actions$" + }, + { + "pattern": "^https://test.pypi.org" + }, { "pattern": "^https://bestpractices.coreinfrastructure.org/projects/" } From cec26fd55b218635564beeaafa49886f00c4093e Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 09:31:19 +0200 Subject: [PATCH 20/41] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd8bb973..685c7539 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * Consolidated test/lint/build into single matrix workflow [#270](https://github.com/NLeSC/python-template/issues/276) * Enforce isort configuration * Default for `package_short_description` in cookiecutter questionnaire +* Link checker ignores GH settings page and test pypi site ### Removed From 7b4e96cedd5df891a2d56c0234b16c1476d254c2 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 09:41:57 +0200 Subject: [PATCH 21/41] Link checker ignores GH private pages --- CHANGELOG.md | 2 +- {{cookiecutter.directory_name}}/.mlc-config.json | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 685c7539..a8887f37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ * Consolidated test/lint/build into single matrix workflow [#270](https://github.com/NLeSC/python-template/issues/276) * Enforce isort configuration * Default for `package_short_description` in cookiecutter questionnaire -* Link checker ignores GH settings page and test pypi site +* Link checker ignores GH private pages and test pypi site [#288](https://github.com/NLeSC/python-template/issues/288) ### Removed diff --git a/{{cookiecutter.directory_name}}/.mlc-config.json b/{{cookiecutter.directory_name}}/.mlc-config.json index 80d0d1aa..214dad70 100644 --- a/{{cookiecutter.directory_name}}/.mlc-config.json +++ b/{{cookiecutter.directory_name}}/.mlc-config.json @@ -10,6 +10,9 @@ { "pattern": "/settings/secrets/actions$" }, + { + "pattern": "^https://github.com/organizations/.*/repositories/new" + }, { "pattern": "^https://test.pypi.org" }, From 374b294f4aabb4ea5aa73a2c142e5d733e030dde Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 10:17:05 +0200 Subject: [PATCH 22/41] Another issue fixed --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8887f37..4057f6b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ * Enforce isort configuration * Default for `package_short_description` in cookiecutter questionnaire * Link checker ignores GH private pages and test pypi site [#288](https://github.com/NLeSC/python-template/issues/288) +* In CI build workflow make prospector die if there are errors [#275](https://github.com/NLeSC/python-template/issues/275) ### Removed From 2b4a31ed9fc7606e9246a58ea45d4e22c9bae00a Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 11:09:25 +0200 Subject: [PATCH 23/41] pytest.raises error --- CHANGELOG.md | 2 +- tests/test_project.py | 2 +- {{cookiecutter.directory_name}}/tests/test_my_module.py | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4057f6b1..f145c20e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,13 +16,13 @@ * Default for `package_short_description` in cookiecutter questionnaire * Link checker ignores GH private pages and test pypi site [#288](https://github.com/NLeSC/python-template/issues/288) * In CI build workflow make prospector die if there are errors [#275](https://github.com/NLeSC/python-template/issues/275) +* Explain pytest using package code ### Removed * `.pylintrc` file, was too strict, too soon [#267](https://github.com/NLeSC/python-template/issues/267) * Unused development dependencies [#167](https://github.com/NLeSC/python-template/issues/167) * Statements in project_setup.md already mentioned in README.dev.md -* Example tests to explain pytest ## 0.4.0 diff --git a/tests/test_project.py b/tests/test_project.py index c2781e42..8bab8ef9 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -55,7 +55,7 @@ def test_pytest(baked_with_development_dependencies): project_dir, bin_dir = baked_with_development_dependencies result = run([f'{bin_dir}pytest'], project_dir) assert result.returncode == 0 - assert '== 1 passed in' in result.stdout + assert '== 2 passed in' in result.stdout assert (project_dir / 'coverage.xml').exists() assert (project_dir / 'htmlcov/index.html').exists() diff --git a/{{cookiecutter.directory_name}}/tests/test_my_module.py b/{{cookiecutter.directory_name}}/tests/test_my_module.py index e8e9f81d..a6ca650b 100644 --- a/{{cookiecutter.directory_name}}/tests/test_my_module.py +++ b/{{cookiecutter.directory_name}}/tests/test_my_module.py @@ -1,7 +1,14 @@ """Tests for the {{ cookiecutter.package_name }}.my_module module. """ +import pytest + from {{ cookiecutter.package_name }} import my_module def test_hello(): assert my_module.hello('nlesc') == 'Hello nlesc!' + + +def test_hello_without_arguments(): + with pytest.raises(TypeError): + my_module.hello() From a39740321c57a7ff208532859fac9935e8e13909 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 4 May 2021 11:34:13 +0200 Subject: [PATCH 24/41] Revert "pytest.raises error" This reverts commit 2b4a31ed9fc7606e9246a58ea45d4e22c9bae00a. --- CHANGELOG.md | 2 +- tests/test_project.py | 2 +- {{cookiecutter.directory_name}}/tests/test_my_module.py | 7 ------- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f145c20e..4057f6b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,13 +16,13 @@ * Default for `package_short_description` in cookiecutter questionnaire * Link checker ignores GH private pages and test pypi site [#288](https://github.com/NLeSC/python-template/issues/288) * In CI build workflow make prospector die if there are errors [#275](https://github.com/NLeSC/python-template/issues/275) -* Explain pytest using package code ### Removed * `.pylintrc` file, was too strict, too soon [#267](https://github.com/NLeSC/python-template/issues/267) * Unused development dependencies [#167](https://github.com/NLeSC/python-template/issues/167) * Statements in project_setup.md already mentioned in README.dev.md +* Example tests to explain pytest ## 0.4.0 diff --git a/tests/test_project.py b/tests/test_project.py index 8bab8ef9..c2781e42 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -55,7 +55,7 @@ def test_pytest(baked_with_development_dependencies): project_dir, bin_dir = baked_with_development_dependencies result = run([f'{bin_dir}pytest'], project_dir) assert result.returncode == 0 - assert '== 2 passed in' in result.stdout + assert '== 1 passed in' in result.stdout assert (project_dir / 'coverage.xml').exists() assert (project_dir / 'htmlcov/index.html').exists() diff --git a/{{cookiecutter.directory_name}}/tests/test_my_module.py b/{{cookiecutter.directory_name}}/tests/test_my_module.py index a6ca650b..e8e9f81d 100644 --- a/{{cookiecutter.directory_name}}/tests/test_my_module.py +++ b/{{cookiecutter.directory_name}}/tests/test_my_module.py @@ -1,14 +1,7 @@ """Tests for the {{ cookiecutter.package_name }}.my_module module. """ -import pytest - from {{ cookiecutter.package_name }} import my_module def test_hello(): assert my_module.hello('nlesc') == 'Hello nlesc!' - - -def test_hello_without_arguments(): - with pytest.raises(TypeError): - my_module.hello() From b6452e0c2972641730e517a715d56cd3f7d2c559 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Wed, 5 May 2021 20:56:55 +0200 Subject: [PATCH 25/41] Only use example function in tests --- CHANGELOG.md | 2 +- tests/test_project.py | 2 +- .../tests/test_my_module.py | 17 +++++++++++++++++ .../{{cookiecutter.package_name}}/my_module.py | 8 +++++++- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4057f6b1..ecc097da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,13 +16,13 @@ * Default for `package_short_description` in cookiecutter questionnaire * Link checker ignores GH private pages and test pypi site [#288](https://github.com/NLeSC/python-template/issues/288) * In CI build workflow make prospector die if there are errors [#275](https://github.com/NLeSC/python-template/issues/275) +* All example tests make use of example function ### Removed * `.pylintrc` file, was too strict, too soon [#267](https://github.com/NLeSC/python-template/issues/267) * Unused development dependencies [#167](https://github.com/NLeSC/python-template/issues/167) * Statements in project_setup.md already mentioned in README.dev.md -* Example tests to explain pytest ## 0.4.0 diff --git a/tests/test_project.py b/tests/test_project.py index c2781e42..9abec498 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -55,7 +55,7 @@ def test_pytest(baked_with_development_dependencies): project_dir, bin_dir = baked_with_development_dependencies result = run([f'{bin_dir}pytest'], project_dir) assert result.returncode == 0 - assert '== 1 passed in' in result.stdout + assert '== 3 passed in' in result.stdout assert (project_dir / 'coverage.xml').exists() assert (project_dir / 'htmlcov/index.html').exists() diff --git a/{{cookiecutter.directory_name}}/tests/test_my_module.py b/{{cookiecutter.directory_name}}/tests/test_my_module.py index e8e9f81d..98ab7eff 100644 --- a/{{cookiecutter.directory_name}}/tests/test_my_module.py +++ b/{{cookiecutter.directory_name}}/tests/test_my_module.py @@ -1,7 +1,24 @@ """Tests for the {{ cookiecutter.package_name }}.my_module module. """ +import pytest + from {{ cookiecutter.package_name }} import my_module def test_hello(): assert my_module.hello('nlesc') == 'Hello nlesc!' + + +def test_hello_with_error(): + with pytest.raises(ValueError) as excinfo: + my_module.hello('nobody') + assert str(excinfo.value) == 'Can not say hello to nobody' + + +@pytest.fixture +def some_name(): + return 'Jane Smith' + + +def test_hello_with_fixture(some_name): + assert my_module.hello(some_name) == 'Hello Jane Smith!' diff --git a/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/my_module.py b/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/my_module.py index c6435357..986bdbf5 100644 --- a/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/my_module.py +++ b/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/my_module.py @@ -5,12 +5,18 @@ def hello(name): """Say hello - Example docstring using Google docstring format. + Example docstring using Google docstring style. Args: name (str): Name to say hello to Returns: str: Hello message + + Raises: + ValueError: If `name` is equal to `nobody` + """ + if name == 'nobody': + raise ValueError('Can not say hello to nobody') return f'Hello {name}!' From 29e859b92d50eee587441ded58b63129ecccc2e0 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Thu, 6 May 2021 08:25:57 +0200 Subject: [PATCH 26/41] Import function instead of module --- .../tests/test_my_module.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/{{cookiecutter.directory_name}}/tests/test_my_module.py b/{{cookiecutter.directory_name}}/tests/test_my_module.py index 98ab7eff..c78f5249 100644 --- a/{{cookiecutter.directory_name}}/tests/test_my_module.py +++ b/{{cookiecutter.directory_name}}/tests/test_my_module.py @@ -2,17 +2,17 @@ """ import pytest -from {{ cookiecutter.package_name }} import my_module +from {{ cookiecutter.package_name }}.my_module import hello def test_hello(): - assert my_module.hello('nlesc') == 'Hello nlesc!' + assert hello('nlesc') == 'Hello nlesc!' def test_hello_with_error(): with pytest.raises(ValueError) as excinfo: - my_module.hello('nobody') - assert str(excinfo.value) == 'Can not say hello to nobody' + hello('nobody') + assert 'Can not say hello to nobody' in str(excinfo.value) @pytest.fixture @@ -21,4 +21,4 @@ def some_name(): def test_hello_with_fixture(some_name): - assert my_module.hello(some_name) == 'Hello Jane Smith!' + assert hello(some_name) == 'Hello Jane Smith!' From e48587b361d83e506672268a516d088cbf6cf471 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Thu, 6 May 2021 08:46:29 +0200 Subject: [PATCH 27/41] Add example usage in docstring --- .../{{cookiecutter.package_name}}/my_module.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/my_module.py b/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/my_module.py index 986bdbf5..be0172d9 100644 --- a/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/my_module.py +++ b/{{cookiecutter.directory_name}}/{{cookiecutter.package_name}}/my_module.py @@ -5,7 +5,7 @@ def hello(name): """Say hello - Example docstring using Google docstring style. + Function docstring using Google docstring style. Args: name (str): Name to say hello to @@ -16,6 +16,13 @@ def hello(name): Raises: ValueError: If `name` is equal to `nobody` + Example: + This function can be called with `Jane Smith` as argument using + + >>> from {{ cookiecutter.package_name }}.my_module import hello + >>> hello('Jane Smith') + 'Hello Jane Smith!' + """ if name == 'nobody': raise ValueError('Can not say hello to nobody') From 46dc16078a58cbdc8ab4e587515de2a11901c3bb Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Thu, 6 May 2021 08:48:37 +0200 Subject: [PATCH 28/41] Prep for Sphinx AutoAPI usage --- {{cookiecutter.directory_name}}/.gitignore | 1 - {{cookiecutter.directory_name}}/docs/index.rst | 16 ++++------------ {{cookiecutter.directory_name}}/project_setup.md | 1 + {{cookiecutter.directory_name}}/setup.cfg | 1 + 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/{{cookiecutter.directory_name}}/.gitignore b/{{cookiecutter.directory_name}}/.gitignore index deeb37d8..22a58eb1 100644 --- a/{{cookiecutter.directory_name}}/.gitignore +++ b/{{cookiecutter.directory_name}}/.gitignore @@ -14,7 +14,6 @@ coverage.xml .pytest_cache docs/_build -docs/apidocs # ide .idea diff --git a/{{cookiecutter.directory_name}}/docs/index.rst b/{{cookiecutter.directory_name}}/docs/index.rst index d8ef571c..d4af697b 100644 --- a/{{cookiecutter.directory_name}}/docs/index.rst +++ b/{{cookiecutter.directory_name}}/docs/index.rst @@ -1,7 +1,7 @@ -.. {{ cookiecutter.package_name }} documentation main file, created by - sphinx-quickstart on Thu Jun 21 11:07:11 2018. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. +.. {{ cookiecutter.package_name }} documentation master file, created by + sphinx-quickstart on Wed May 5 22:45:36 2021. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. Welcome to {{ cookiecutter.package_name }}'s documentation! ========================================================== @@ -10,14 +10,6 @@ Welcome to {{ cookiecutter.package_name }}'s documentation! :maxdepth: 2 :caption: Contents: -API Reference -============= - -.. toctree:: - :maxdepth: 2 - - {{ cookiecutter.package_name }} - Indices and tables ================== diff --git a/{{cookiecutter.directory_name}}/project_setup.md b/{{cookiecutter.directory_name}}/project_setup.md index fd155197..19b5768a 100644 --- a/{{cookiecutter.directory_name}}/project_setup.md +++ b/{{cookiecutter.directory_name}}/project_setup.md @@ -57,6 +57,7 @@ help you decide which tool to use for packaging. - [Google style docstring examples](http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html). - The documentation is set up with the ReadTheDocs Sphinx theme. - Check out its [configuration options](https://sphinx-rtd-theme.readthedocs.io/en/latest/). +- [AutoAPI](https://sphinx-autoapi.readthedocs.io/) is used to generate documentation for the package Python objects. - [Relevant section in the guide](https://guide.esciencecenter.nl/#/best_practices/language_guides/python?id=writingdocumentation) ## Coding style conventions and code quality diff --git a/{{cookiecutter.directory_name}}/setup.cfg b/{{cookiecutter.directory_name}}/setup.cfg index 477b3d4e..ad06d7ae 100644 --- a/{{cookiecutter.directory_name}}/setup.cfg +++ b/{{cookiecutter.directory_name}}/setup.cfg @@ -54,6 +54,7 @@ dev = pytest-cov sphinx sphinx_rtd_theme + sphinx-autoapi publishing = twine wheel From ea72de2f17e9393c1d9e5ffae90c9f8258e1c99b Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Thu, 6 May 2021 08:49:40 +0200 Subject: [PATCH 29/41] Regenerated docs/conf.py Also * Use bumpversion for version in Sphinx config * Enable Sphinx built-in extensions * use Sphinx AutoAPI --- CHANGELOG.md | 9 +- tests/test_project.py | 79 +++++-- .../.bumpversion.cfg | 4 + .../.github/workflows/build.yml | 3 + {{cookiecutter.directory_name}}/README.dev.md | 27 ++- {{cookiecutter.directory_name}}/docs/conf.py | 201 ++++-------------- 6 files changed, 136 insertions(+), 187 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecc097da..592c0f72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,19 +4,24 @@ ### Added -* Tests for linting and version bumping +* Template unit tests for documentation generation, linting and version bumping * Docstring for function +* Intersphinx to documentation +* Coverage and doctest commands for documentation ### Changed * Renamed `project_name` to `directory_name` in cookiecutter questionnaire * Initial linting is error free [#227](https://github.com/NLeSC/python-template/issues/227) -* Consolidated test/lint/build into single matrix workflow [#270](https://github.com/NLeSC/python-template/issues/276) +* Consolidated test/lint/build/docs into single matrix workflow [#270](https://github.com/NLeSC/python-template/issues/276) * Enforce isort configuration * Default for `package_short_description` in cookiecutter questionnaire * Link checker ignores GH private pages and test pypi site [#288](https://github.com/NLeSC/python-template/issues/288) * In CI build workflow make prospector die if there are errors [#275](https://github.com/NLeSC/python-template/issues/275) * All example tests make use of example function +* Use bumpversion for version in Sphinx config +* Regenerated docs/conf.py with sphinx-quickstart v3.5.4 + enabled built-in extensions +* Generate api rst files with 3rd party extension instead of custom function ### Removed diff --git a/tests/test_project.py b/tests/test_project.py index 9abec498..8ccaf6df 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -7,7 +7,7 @@ import pytest -IS_WINDOWS = platform.startswith("win") +IS_WINDOWS = platform.startswith('win') IS_WINDOWS_CI = IS_WINDOWS and os.environ.get('CI', False) @@ -25,43 +25,53 @@ def run(args: Sequence[str], dirpath: os.PathLike) -> subprocess.CompletedProces stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=dirpath, - encoding="utf-8") + encoding='utf-8') print(completed_process.stdout) print(completed_process.stderr) return completed_process @pytest.fixture -def baked_with_development_dependencies(cookies): - result = cookies.bake() - assert result.exit_code == 0 +def project_env_bin_dir(tmp_path): if IS_WINDOWS_CI: # Creating virtualenv does not work on Windows CI, # falling back to using current pip3 dir pip = Path(which('pip3')) - bin_dir = str(pip.parent) + '\\' + bin_dir = pip.parent else: - env_output = run(['python3', '-m', 'venv', 'env'], result.project) + env_output = run(['python3', '-m', 'venv', 'env'], tmp_path) assert env_output.returncode == 0 - bin_dir = 'env/Scripts/' if IS_WINDOWS else 'env/bin/' + bin_dir = str(tmp_path / 'env' / 'bin') + if IS_WINDOWS: + bin_dir = str(tmp_path / 'env' / 'Scripts') + return str(bin_dir) + os.sep + + +@pytest.fixture +def baked_with_development_dependencies(cookies, project_env_bin_dir): + result = cookies.bake() + assert result.exit_code == 0 + bin_dir = project_env_bin_dir latest_pip_output = run([f'{bin_dir}pip3', 'install', '--upgrade', 'pip', 'setuptools'], result.project) assert latest_pip_output.returncode == 0 pip_output = run([f'{bin_dir}pip3', 'install', '--editable', '.[dev]'], result.project) assert pip_output.returncode == 0 - return result.project, bin_dir + return result.project -def test_pytest(baked_with_development_dependencies): - project_dir, bin_dir = baked_with_development_dependencies +def test_pytest(baked_with_development_dependencies, project_env_bin_dir): + project_dir = baked_with_development_dependencies + bin_dir = project_env_bin_dir result = run([f'{bin_dir}pytest'], project_dir) assert result.returncode == 0 assert '== 3 passed in' in result.stdout assert (project_dir / 'coverage.xml').exists() - assert (project_dir / 'htmlcov/index.html').exists() + assert (project_dir / 'htmlcov' / 'index.html').exists() -def test_subpackage(baked_with_development_dependencies): - project_dir, bin_dir = baked_with_development_dependencies +def test_subpackage(baked_with_development_dependencies, project_env_bin_dir): + project_dir = baked_with_development_dependencies + bin_dir = project_env_bin_dir subpackage = (project_dir / 'my_python_package' / 'mysub') subpackage.mkdir() (subpackage / '__init__.py').write_text('FOO = "bar"', encoding="utf-8") @@ -79,8 +89,9 @@ def test_subpackage(baked_with_development_dependencies): assert (project_dir / 'build' / 'lib' / 'my_python_package' / 'mysub' / 'mysub2' / '__init__.py').exists() -def test_generate_api_docs(baked_with_development_dependencies): - project_dir, bin_dir = baked_with_development_dependencies +def test_generate_api_docs(baked_with_development_dependencies, project_env_bin_dir): + project_dir = baked_with_development_dependencies + bin_dir = project_env_bin_dir result = run([f'{bin_dir}sphinx-build', '-b', 'html', 'docs', 'docs/_build/html'], project_dir) assert result.returncode == 0 @@ -88,15 +99,38 @@ def test_generate_api_docs(baked_with_development_dependencies): assert (project_dir / 'docs' / '_build' / 'html' / 'index.html').exists() -def test_prospector(baked_with_development_dependencies): - project_dir, bin_dir = baked_with_development_dependencies +def test_coverage_api_docs(baked_with_development_dependencies, project_env_bin_dir): + project_dir = baked_with_development_dependencies + bin_dir = project_env_bin_dir + + result = run([f'{bin_dir}sphinx-build', '-b', 'coverage', 'docs', 'docs/_build/coverage'], project_dir) + assert result.returncode == 0 + assert 'build succeeded' in result.stdout + coverage_file = project_dir / 'docs' / '_build' / 'coverage' / 'python.txt' + lines = coverage_file.readlines() + assert len(lines) == 2 + + +def test_doctest_api_docs(baked_with_development_dependencies, project_env_bin_dir): + project_dir = baked_with_development_dependencies + bin_dir = project_env_bin_dir + + result = run([f'{bin_dir}sphinx-build', '-b', 'doctest', 'docs', 'docs/_build/doctest'], project_dir) + assert result.returncode == 0 + assert 'build succeeded' in result.stdout + assert (project_dir / 'docs' / '_build' / 'doctest' / 'output.txt').exists() + + +def test_prospector(baked_with_development_dependencies, project_env_bin_dir): + project_dir = baked_with_development_dependencies + bin_dir = project_env_bin_dir result = run([f'{bin_dir}prospector'], project_dir) assert result.returncode == 0 assert 'Messages Found: 0' in result.stdout -def test_isort_check(baked_with_development_dependencies): +def test_isort_check(baked_with_development_dependencies, project_env_bin_dir): project_dir, bin_dir = baked_with_development_dependencies result = run([f'{bin_dir}isort', '--recursive', '--check-only', 'my_python_package'], project_dir) @@ -104,13 +138,15 @@ def test_isort_check(baked_with_development_dependencies): assert '' in result.stdout -def test_bumpversion(baked_with_development_dependencies): - project_dir, bin_dir = baked_with_development_dependencies +def test_bumpversion(baked_with_development_dependencies, project_env_bin_dir): + project_dir = baked_with_development_dependencies + bin_dir = project_env_bin_dir original_version = '0.1.0' assert original_version in (project_dir / 'setup.cfg').read_text('utf-8') assert original_version in (project_dir / 'CITATION.cff').read_text('utf-8') assert original_version in (project_dir / 'my_python_package' / '__init__.py').read_text('utf-8') + assert original_version in (project_dir / 'docs' / 'conf.py').read_text('utf-8') result = run([f'{bin_dir}bumpversion', 'major'], project_dir) assert result.returncode == 0 @@ -119,3 +155,4 @@ def test_bumpversion(baked_with_development_dependencies): assert expected_version in (project_dir / 'setup.cfg').read_text('utf-8') assert expected_version in (project_dir / 'CITATION.cff').read_text('utf-8') assert expected_version in (project_dir / 'my_python_package' / '__init__.py').read_text('utf-8') + assert expected_version in (project_dir / 'docs' / 'conf.py').read_text('utf-8') diff --git a/{{cookiecutter.directory_name}}/.bumpversion.cfg b/{{cookiecutter.directory_name}}/.bumpversion.cfg index 5cd6327c..16899b5e 100644 --- a/{{cookiecutter.directory_name}}/.bumpversion.cfg +++ b/{{cookiecutter.directory_name}}/.bumpversion.cfg @@ -15,3 +15,7 @@ replace = version = {new_version} [bumpversion:file:CITATION.cff] search = version: "{current_version}" replace = version: "{new_version}" + +[bumpversion:file:docs/conf.py] +search = version = "{current_version}" +replace = version = "{new_version}" diff --git a/{{cookiecutter.directory_name}}/.github/workflows/build.yml b/{{cookiecutter.directory_name}}/.github/workflows/build.yml index 0a04be50..ff8b80bf 100644 --- a/{{cookiecutter.directory_name}}/.github/workflows/build.yml +++ b/{{cookiecutter.directory_name}}/.github/workflows/build.yml @@ -35,3 +35,6 @@ jobs: run: pytest -v - name: Verify that we can build the package run: python3 setup.py sdist bdist_wheel + - name: Build documentation + run: make coverage doctest html + working-directory: docs diff --git a/{{cookiecutter.directory_name}}/README.dev.md b/{{cookiecutter.directory_name}}/README.dev.md index 285c9965..40aa89b7 100644 --- a/{{cookiecutter.directory_name}}/README.dev.md +++ b/{{cookiecutter.directory_name}}/README.dev.md @@ -73,9 +73,24 @@ If you do not have `make` use sphinx-build -b html docs docs/_build/html ``` +To find undocumented Python objects run + +```shell +cd docs +make coverage +cat _build/coverage/python.txt +``` + +To [test snippets](https://www.sphinx-doc.org/en/master/usage/extensions/doctest.html) in documentation run + +```shell +cd docs +make doctest +``` + ## Versioning -Bumping the version across all files is done with bumpversion, e.g. +Bumping the version across all files is done with [bumpversion](https://github.com/c4urself/bump2version), e.g. ```shell bumpversion major @@ -93,10 +108,10 @@ This section describes how to make a release in 3 parts: ### (1/3) Preparation -1. Update the `CHANGELOG.md` -2. Verify that the information in `CITATION.cff` is correct, and that `.zenodo.json` contains equivalent data -3. Make sure the version has been updated. -4. Run the unit tests with `pytest tests/` +1. Update the (don't forget to update links at bottom of page) +2. Verify that the information in `CITATION.cff` is correct, and that `.zenodo.json` contains equivalent data +3. Make sure the [version has been updated](#versioning). +4. Run the unit tests with `pytest -v` ### (2/3) PyPI @@ -165,4 +180,4 @@ twine upload dist/* ### (3/3) GitHub -Don't forget to also make a release on GitHub. If your repository uses the GitHub-Zenodo integration this will also trigger Zenodo into making a snapshot of your repository and sticking a DOI on it. +Don't forget to also make a [release on GitHub]({{cookiecutter.repository}}/releases/new). If your repository uses the GitHub-Zenodo integration this will also trigger Zenodo into making a snapshot of your repository and sticking a DOI on it. diff --git a/{{cookiecutter.directory_name}}/docs/conf.py b/{{cookiecutter.directory_name}}/docs/conf.py index d18ab35e..959ec776 100644 --- a/{{cookiecutter.directory_name}}/docs/conf.py +++ b/{{cookiecutter.directory_name}}/docs/conf.py @@ -1,52 +1,22 @@ -# {{ cookiecutter.package_name }} documentation build configuration file, created by -# sphinx-quickstart on {% now "local", "%a %b %d %H:%M:%S %Y" %}. +# Configuration file for the Sphinx documentation builder. # -# This file is execfile()d with the current directory set to its -# containing dir. +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html # -# 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. + +# -- Path setup -------------------------------------------------------------- # 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 sys - -here = os.path.dirname(__file__) -sys.path.insert(0, os.path.abspath(os.path.join(here, ".."))) - -import {{ cookiecutter.package_name }} +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) +# -- Project information ----------------------------------------------------- -# -- 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.napoleon"] - -# 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" - -# The main toctree document. -main_doc = "index" - -# General information about the project. project = u"{{ cookiecutter.package_name }}" copyright = u"{% now "local", "%Y" %}, {{ cookiecutter.copyright_holder }}" author = u"{{ cookiecutter.full_name.replace('\"', '\\\"') }}" @@ -56,59 +26,41 @@ # built documents. # # The short X.Y version. -version = {{ cookiecutter.package_name }}.__version__ +version = "0.1.0" # The full version, including alpha/beta/rc tags. -release = {{ cookiecutter.package_name }}.__version__ +release = version -# 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 +# -- General configuration ------------------------------------------------ + +# 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.coverage", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", + "sphinx.ext.mathjax", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "autoapi.extension", +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" - # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False -# -- Run apidoc plug-in manually, as readthedocs doesn't support it ------- -# See https://github.com/rtfd/readthedocs.org/issues/1139 -def run_apidoc(_): - here = os.path.dirname(__file__) - out = os.path.abspath(os.path.join(here, "apidocs")) - src = os.path.abspath(os.path.join(here, "..", "{{ cookiecutter.package_name }}")) - - ignore_paths = [] - - argv = [ - "-f", - "-T", - "-e", - "-M", - "-o", out, - src - ] + ignore_paths - - try: - # Sphinx 1.7+ - from sphinx.ext import apidoc - apidoc.main(argv) - except ImportError: - # Sphinx 1.6 (and earlier) - from sphinx import apidoc - argv.insert(0, apidoc.__file__) - apidoc.main(argv) - - -def setup(app): - app.connect("builder-inited", run_apidoc) +# -- Use autoapi.extension to run sphinx-apidoc ------- + +autoapi_dirs = ['../{{ cookiecutter.package_name }}'] # -- Options for HTML output ---------------------------------------------- @@ -123,80 +75,13 @@ def setup(app): # # html_theme_options = {} -# 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"] -html_context = { - "css_files": [ - "_static/theme_overrides.css" # override wide tables in RTD theme - ] -} - -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# This is required for the alabaster theme -# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars -html_sidebars = { - "**": [ - "relations.html", # needs "show_related": True theme option to display - "searchbox.html" - ] -} - - -# -- Options for HTMLHelp output ------------------------------------------ - -# Output file base name for HTML help builder. -htmlhelp_basename = "{{ cookiecutter.package_name }}_doc" - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ("letterpaper" or "a4paper"). - # - # "papersize": "letterpaper", +# -- Options for Intersphinx - # 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 = [ - (main_doc, "{{ cookiecutter.package_name }}.tex", u"{{ cookiecutter.package_name }} Documentation", - u"{{ cookiecutter.full_name }}", "manual") -] - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (main_doc, "{{ cookiecutter.package_name }}", u"{{ cookiecutter.package_name }} Documentation", [author], 1) -] - - -# -- 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 = [ - (main_doc, "{{ cookiecutter.package_name }}", u"{{ cookiecutter.package_name }} Documentation", - author, "{{ cookiecutter.package_name }}", "{{ cookiecutter.package_short_description }}", - "Miscellaneous") -] +intersphinx_mapping = {'python': ('https://docs.python.org/3', None), + # Commonly used libraries, uncomment when used in package + # 'numpy': ('http://docs.scipy.org/doc/numpy/', None), + # 'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None), + # 'scikit-learn': ('https://scikit-learn.org/stable/', None), + # 'matplotlib': ('https://matplotlib.org/stable/', None), + # 'pandas': ('http://pandas.pydata.org/docs/', None), + } From faec90f26417c10b5a06b1f9422acc477d362b89 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Thu, 6 May 2021 09:04:07 +0200 Subject: [PATCH 30/41] Fix remnant --- tests/test_project.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_project.py b/tests/test_project.py index 8ccaf6df..38fff80d 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -131,7 +131,8 @@ def test_prospector(baked_with_development_dependencies, project_env_bin_dir): def test_isort_check(baked_with_development_dependencies, project_env_bin_dir): - project_dir, bin_dir = baked_with_development_dependencies + project_dir = baked_with_development_dependencies + bin_dir = project_env_bin_dir result = run([f'{bin_dir}isort', '--recursive', '--check-only', 'my_python_package'], project_dir) assert result.returncode == 0 From 4815b82f5a3ca7e0d092ead77ff44f2358848abb Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Thu, 6 May 2021 09:04:15 +0200 Subject: [PATCH 31/41] Add issue urls to CHANGELOG --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 592c0f72..b5d2b48e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ * Template unit tests for documentation generation, linting and version bumping * Docstring for function * Intersphinx to documentation -* Coverage and doctest commands for documentation +* Coverage and doctest commands for documentation [#97](https://github.com/NLeSC/python-template/issues/97) ### Changed @@ -19,9 +19,9 @@ * Link checker ignores GH private pages and test pypi site [#288](https://github.com/NLeSC/python-template/issues/288) * In CI build workflow make prospector die if there are errors [#275](https://github.com/NLeSC/python-template/issues/275) * All example tests make use of example function -* Use bumpversion for version in Sphinx config -* Regenerated docs/conf.py with sphinx-quickstart v3.5.4 + enabled built-in extensions -* Generate api rst files with 3rd party extension instead of custom function +* Use bumpversion for version in Sphinx config [#44](https://github.com/NLeSC/python-template/issues/44) +* Regenerated docs/conf.py with sphinx-quickstart v3.5.4 + enabled built-in extensions [#44](https://github.com/NLeSC/python-template/issues/44) +* Generate api rst files with 3rd party extension instead of custom function [#95](https://github.com/NLeSC/python-template/issues/95) ### Removed From e4081dd6bc63ffec4f1daa96d7ad1fd4e9505e4b Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Thu, 6 May 2021 12:47:03 +0200 Subject: [PATCH 32/41] Need RTD config to render API docs with AutoAPI --- CHANGELOG.md | 8 ++++---- {{cookiecutter.directory_name}}/.readthedocs.yaml | 7 +++++++ {{cookiecutter.directory_name}}/project_setup.md | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 {{cookiecutter.directory_name}}/.readthedocs.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index b5d2b48e..dacde367 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ * All example tests make use of example function * Use bumpversion for version in Sphinx config [#44](https://github.com/NLeSC/python-template/issues/44) * Regenerated docs/conf.py with sphinx-quickstart v3.5.4 + enabled built-in extensions [#44](https://github.com/NLeSC/python-template/issues/44) -* Generate api rst files with 3rd party extension instead of custom function [#95](https://github.com/NLeSC/python-template/issues/95) +* Generate api rst files with extension instead of custom function [#95](https://github.com/NLeSC/python-template/issues/95) ### Removed @@ -36,7 +36,7 @@ * Instructions to add your existing code to directory generated by the NLeSC Python template [#202](https://github.com/NLeSC/python-template/issues/202) * Keywords to questionnaire [#270](https://github.com/NLeSC/python-template/issues/270) * Next step issue generation workflow [#228](https://github.com/NLeSC/python-template/issues/228) -* Next step issue for SonarCloud integration [#234](https://github.com/NLeSC/python-template/issues/234) +* Next step issue for SonarCloud integration [#234](https://github.com/NLeSC/python-template/issues/234) * Next step issue for Zenodo integration [#235](https://github.com/NLeSC/python-template/issues/235) * Next step issue for Read the Docs [#236](https://github.com/NLeSC/python-template/issues/236) * Next step issue for citation data [#237](https://github.com/NLeSC/python-template/issues/237) @@ -47,7 +47,7 @@ * CI Tests on Windows [#140](https://github.com/NLeSC/python-template/issues/140) [#223](https://github.com/NLeSC/python-template/issues/223) * `.pylintrc` file * Valid license name and first author name in `CITATION.cff` -* SonarCloud integration for code quality and coverage [#89](https://github.com/NLeSC/python-template/issues/89) +* SonarCloud integration for code quality and coverage [#89](https://github.com/NLeSC/python-template/issues/89) * Read the Docs [#78](https://github.com/NLeSC/python-template/issues/78) ### Changed @@ -94,7 +94,7 @@ * Dropped appveyor [#160](https://github.com/NLeSC/python-template/issues/160) * Dropped everything Conda related * Drop Python 3.5 support -* Removed unit tests doing the linting +* Removed unit tests doing the linting ## 0.2.0 diff --git a/{{cookiecutter.directory_name}}/.readthedocs.yaml b/{{cookiecutter.directory_name}}/.readthedocs.yaml new file mode 100644 index 00000000..544d704c --- /dev/null +++ b/{{cookiecutter.directory_name}}/.readthedocs.yaml @@ -0,0 +1,7 @@ +version: 2 +python: + install: + - method: pip + path: . + extra_requirements: + - dev diff --git a/{{cookiecutter.directory_name}}/project_setup.md b/{{cookiecutter.directory_name}}/project_setup.md index 19b5768a..872f4994 100644 --- a/{{cookiecutter.directory_name}}/project_setup.md +++ b/{{cookiecutter.directory_name}}/project_setup.md @@ -58,6 +58,7 @@ help you decide which tool to use for packaging. - The documentation is set up with the ReadTheDocs Sphinx theme. - Check out its [configuration options](https://sphinx-rtd-theme.readthedocs.io/en/latest/). - [AutoAPI](https://sphinx-autoapi.readthedocs.io/) is used to generate documentation for the package Python objects. +- `.readthedocs.yaml` is the ReadTheDocs configuration file. When ReadTheDocs is building the documentation this package and its development dependencies are installed so the API reference can be rendered. - [Relevant section in the guide](https://guide.esciencecenter.nl/#/best_practices/language_guides/python?id=writingdocumentation) ## Coding style conventions and code quality From cf3d4bf3510c5c1632829046383e046b09ddbcce Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 7 May 2021 11:19:28 +0200 Subject: [PATCH 33/41] Compare docs coverage with expected value --- tests/test_project.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_project.py b/tests/test_project.py index 38fff80d..fcb95ddf 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -107,8 +107,10 @@ def test_coverage_api_docs(baked_with_development_dependencies, project_env_bin_ assert result.returncode == 0 assert 'build succeeded' in result.stdout coverage_file = project_dir / 'docs' / '_build' / 'coverage' / 'python.txt' - lines = coverage_file.readlines() - assert len(lines) == 2 + coverage_file_lines = coverage_file.read_text('utf8').splitlines() + expected = ['Undocumented Python objects', + '==========================='] + assert coverage_file_lines == expected def test_doctest_api_docs(baked_with_development_dependencies, project_env_bin_dir): From 3318139c2fb035f1241aa0c809f7da7745a923b0 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 7 May 2021 11:24:14 +0200 Subject: [PATCH 34/41] Explain why build is used --- tests/test_project.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_project.py b/tests/test_project.py index fcb95ddf..34642647 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -70,6 +70,7 @@ def test_pytest(baked_with_development_dependencies, project_env_bin_dir): def test_subpackage(baked_with_development_dependencies, project_env_bin_dir): + """Test if subpackages end up in sdist and bdist_wheel distributions""" project_dir = baked_with_development_dependencies bin_dir = project_env_bin_dir subpackage = (project_dir / 'my_python_package' / 'mysub') @@ -83,6 +84,8 @@ def test_subpackage(baked_with_development_dependencies, project_env_bin_dir): if IS_WINDOWS_CI: # On Windows CI python and pip executable are in different paths bin_dir = '' + # sdist and bdist_wheel both call build command to create build/ dir + # So instead of looking in distribution archives we can look in build/ dir result = run([f'{bin_dir}python', 'setup.py', 'build'], project_dir) assert result.returncode == 0 assert (project_dir / 'build' / 'lib' / 'my_python_package' / 'mysub' / '__init__.py').exists() From 7b76c0f3b2c993e197c629a1e032d7b9e8a6e51b Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 7 May 2021 11:51:45 +0200 Subject: [PATCH 35/41] Update {{cookiecutter.directory_name}}/README.md Co-authored-by: Faruk D. --- {{cookiecutter.directory_name}}/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.directory_name}}/README.md b/{{cookiecutter.directory_name}}/README.md index c8dcc396..d95a2313 100644 --- a/{{cookiecutter.directory_name}}/README.md +++ b/{{cookiecutter.directory_name}}/README.md @@ -16,7 +16,7 @@ | Documentation | [![Documentation Status](https://readthedocs.org/projects/{{cookiecutter.directory_name}}/badge/?version=latest)](https://{{cookiecutter.directory_name}}.readthedocs.io/en/latest/?badge=latest) | | **GitHub Actions** |   | | Build | [![build]({{cookiecutter.repository}}/actions/workflows/build.yml/badge.svg)]({{cookiecutter.repository}}/actions/workflows/build.yml) | -| Citation consistency | [![cffconvert]({{cookiecutter.repository}}/actions/workflows/cffconvert.yml/badge.svg)]({{cookiecutter.repository}}/actions/workflows/cffconvert.yml) | +| Citation data consistency | [![cffconvert]({{cookiecutter.repository}}/actions/workflows/cffconvert.yml/badge.svg)]({{cookiecutter.repository}}/actions/workflows/cffconvert.yml) | | SonarCloud | [![sonarcloud]({{cookiecutter.repository}}/actions/workflows/sonarcloud.yml/badge.svg)]({{cookiecutter.repository}}/actions/workflows/sonarcloud.yml) | | MarkDown link checker | [![markdown-link-check]({{cookiecutter.repository}}/actions/workflows/markdown-link-check.yml/badge.svg)]({{cookiecutter.repository}}/actions/workflows/markdown-link-check.yml) | From 7ade52050809eedc7ffe633dd18be799b78e9369 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 7 May 2021 11:59:34 +0200 Subject: [PATCH 36/41] Link to README.dev.md from next_steps --- {{cookiecutter.directory_name}}/next_steps.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/{{cookiecutter.directory_name}}/next_steps.md b/{{cookiecutter.directory_name}}/next_steps.md index 66e38c6a..bfff064b 100644 --- a/{{cookiecutter.directory_name}}/next_steps.md +++ b/{{cookiecutter.directory_name}}/next_steps.md @@ -31,6 +31,10 @@ A short while after you push your commits to GitHub for the first time, a few is automatically ([here]({{cookiecutter.repository}}/issues?q=author%3Aapp%2Fgithub-actions)). Resolve them to complete the setup of your repository. +## Project development documentation + +The contains developer documentation. + ## Project layout explained For an explanation of what files are there, and what each of these do, please refer to [project_setup.md](project_setup.md). From 46824d82dcf48831c43194edbaa6c01f95cfbf0c Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 7 May 2021 12:01:52 +0200 Subject: [PATCH 37/41] Use link syntax --- {{cookiecutter.directory_name}}/next_steps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.directory_name}}/next_steps.md b/{{cookiecutter.directory_name}}/next_steps.md index bfff064b..4858fbbe 100644 --- a/{{cookiecutter.directory_name}}/next_steps.md +++ b/{{cookiecutter.directory_name}}/next_steps.md @@ -33,7 +33,7 @@ setup of your repository. ## Project development documentation -The contains developer documentation. +The [README.dev.md](README.dev.md) contains developer documentation. ## Project layout explained From 18f58f1877c6afc2d88452b276f0db321764b86f Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 7 May 2021 12:05:03 +0200 Subject: [PATCH 38/41] Add yapf --- {{cookiecutter.directory_name}}/README.dev.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/{{cookiecutter.directory_name}}/README.dev.md b/{{cookiecutter.directory_name}}/README.dev.md index 40aa89b7..5bbea3ef 100644 --- a/{{cookiecutter.directory_name}}/README.dev.md +++ b/{{cookiecutter.directory_name}}/README.dev.md @@ -52,6 +52,8 @@ isort --recursive --check-only --diff {{ cookiecutter.package_name }} isort --recursive {{ cookiecutter.package_name }} ``` +To fix readability of your code style you can use [yapf](https://github.com/google/yapf). + You can enable automatic linting with `prospector` and `isort` on commit by enabling the git hook from `.githooks/pre-commit`, like so: ```shell From 8a88d1fd12862f5b98a79c8037ce98e9e42a8a34 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 7 May 2021 12:07:27 +0200 Subject: [PATCH 39/41] Update {{cookiecutter.directory_name}}/project_setup.md Co-authored-by: Faruk D. --- {{cookiecutter.directory_name}}/project_setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.directory_name}}/project_setup.md b/{{cookiecutter.directory_name}}/project_setup.md index 872f4994..858cac23 100644 --- a/{{cookiecutter.directory_name}}/project_setup.md +++ b/{{cookiecutter.directory_name}}/project_setup.md @@ -63,7 +63,7 @@ help you decide which tool to use for packaging. ## Coding style conventions and code quality -- [Relevant section in the guide](https://guide.esciencecenter.nl/#/best_practices/language_guides/python?id=coding-style-conventions) +- [Relevant section in the NLeSC guide](https://guide.esciencecenter.nl/#/best_practices/language_guides/python?id=coding-style-conventions) and [README.dev.md](README.dev.md). ## Continuous code quality From 69c08113aab8f959c718bd80c2f122e35d3db72c Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 7 May 2021 12:17:58 +0200 Subject: [PATCH 40/41] Update {{cookiecutter.directory_name}}/.mlc-config.json Co-authored-by: Faruk D. --- {{cookiecutter.directory_name}}/.mlc-config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.directory_name}}/.mlc-config.json b/{{cookiecutter.directory_name}}/.mlc-config.json index 214dad70..414b693f 100644 --- a/{{cookiecutter.directory_name}}/.mlc-config.json +++ b/{{cookiecutter.directory_name}}/.mlc-config.json @@ -8,7 +8,7 @@ "pattern": "^https://doi.org/" }, { - "pattern": "/settings/secrets/actions$" + "pattern": "^https://github.com/.*/settings/secrets/actions$" }, { "pattern": "^https://github.com/organizations/.*/repositories/new" From bfa11c8bd1a8455e11b726e9a2c46614aceb445e Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Fri, 7 May 2021 12:35:17 +0200 Subject: [PATCH 41/41] No more theme override --- .../docs/_static/theme_overrides.css | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 {{cookiecutter.directory_name}}/docs/_static/theme_overrides.css diff --git a/{{cookiecutter.directory_name}}/docs/_static/theme_overrides.css b/{{cookiecutter.directory_name}}/docs/_static/theme_overrides.css deleted file mode 100644 index 8194805c..00000000 --- a/{{cookiecutter.directory_name}}/docs/_static/theme_overrides.css +++ /dev/null @@ -1,12 +0,0 @@ -/* override table width restrictions */ -@media screen and (min-width: 767px) { - .wy-table-responsive table td { - /* !important prevents the common CSS stylesheets from overriding - this as on RTD they are loaded after this stylesheet */ - white-space: normal !important; - } - - .wy-table-responsive { - overflow: visible !important; - } -}