@@ -18,30 +18,31 @@ The Python project structure produced by this Cookiecutter template contains
1818the following items:
1919
2020- A minimal README.rst file.
21- - A Makefile that automates many common developer tasks, such as:
21+ - A (non-essential) Makefile that taps into a Hatch project manager
22+ setup to automate many common developer tasks, such as:
2223
23- - Creating a Virtual environment
24+ - The usage of virtual environments.
2425 - Checking and formatting code style with ``black `` and ``isort ``.
2526 - Performing static analysis checks with ``pylint ``.
2627 - Performing type checking with ``mypy ``.
27- - Running unit tests with Python's ``unittest ``.
28+ - Running unit tests with `` pytest ``/ ``unittest ``.
2829 - Checking code coverage with ``coverage ``.
2930 - Generating documentation with ``Sphinx ``.
3031 - Generating, testing and uploading a project release to PyPI.
3132
3233- A ``pyproject.toml `` file used to manage nearly all project configuration.
33- - A ``CONTRIBUTING.rst `` guide. On Github this file is shown when sending
34+ - A ``CONTRIBUTING.rst `` guide. On GitHub this file is shown when sending
3435 a pull request or an issue. This file also gets included in the generated
3536 developer documentation.
3637- An empty ``CHANGELOG.rst `` file. This file gets included in the user
3738 documentation.
38- - An option ``LICENSE `` file (or ``COPYING `` for GNU licenses).
39+ - An optional ``LICENSE `` file (or ``COPYING `` for GNU licenses).
3940- An ``examples `` directory with a minimal quickstart example script. This
4041 script imports the package and prints the package version. It is also
4142 called by the unit test suite to ensure it always works.
4243- A ``tests `` directory containing a basic unit test and a shell
4344 script that can be used to test a wheel distribution of the package.
44- - A Github Actions continuous integration configuration.
45+ - A GitHub Actions continuous integration configuration.
4546- A ``docs `` directory with pre-configured Sphinx documentation containing:
4647
4748 - A minimal ``index.rst `` page
@@ -56,7 +57,7 @@ the following items:
5657
5758It is assumed that the new Python package will eventually be:
5859
59- - hosted on Github (or perhaps GitLab)
60+ - hosted on GitHub (or perhaps GitLab)
6061- published to PyPI
6162- linked to ReadTheDocs.
6263
@@ -93,8 +94,8 @@ simply navigate to a directory where you want to create the new project, then
9394run the ``cookiecutter `` command with a command line argument referencing this
9495template.
9596
96- The easiest method is to reference this template via its Github URL (where 'gh'
97- is a shortened form for Github ):
97+ The easiest method is to reference this template via its GitHub URL (where 'gh'
98+ is a shortened form for GitHub ):
9899
99100.. code-block :: console
100101
@@ -130,9 +131,10 @@ using the new project.
130131- If you do not plan to publish project artifacts at GitHub, PyPI or
131132 ReadTheDocs then remove any links to those sites. Affected files are:
132133
133- - README.rst
134- - docs/source/index.rst
135- - pyproject.toml
134+ - README.rst (references to PyPI and ReadTheDocs)
135+ - docs/source/index.rst (references to PyPI)
136+ - pyproject.toml (references to GitHub and ReadTheDocs under
137+ the `[project.urls] ` section)
136138
137139- Update any additional useful classifiers in ``pyproject.toml ``. The
138140 list of available classifiers can be found `here
@@ -151,7 +153,7 @@ Setup Steps section above which provides a virtual environment with
151153cookiecutter installed into it.
152154
153155After running the cookiecutter command and passing it a reference to this
154- template the first question it asks for is the package display name. This is
156+ template, the first question it asks for is the package display name. This is
155157the human friendly label that will be used in docs to refer to the project. It
156158is also used to create the package name so it should not contain special
157159characters that are invalid when used in a Python attribute. It can have spaces
@@ -180,47 +182,169 @@ Python package name.
180182 7 - GPL-2.0-or-later
181183 8 - GPL-3.0-only
182184 9 - GPL-3.0-or-later
183- Choose from [1/2/3/4/5/6/7/8/9] (1):
184- [10/10] year (2024 ):
185+ Choose from [1/2/3/4/5/6/7/8/9] (1): 9
186+ [10/10] year (2025 ):
185187
186188 The project has been created in the ``abc_123 `` directory.
187189
188190.. code-block :: console
189191
190192 $ cd abc_123
191193
194+ If you are planning to use git, it might be a good idea to create a
195+ new repository at this point.
196+
197+ .. code-block :: console
198+
199+ $ git init
200+ $ git add .
201+ $ git commit -m 'Initial cookiecutter-python-project setup'
202+
203+ With that out of the way, it will be easy to use git to undo any
204+ potential mistakes made while experimenting.
205+
192206We can now kick the tires of this new project by performing some initial
193207project checks.
194208
195- First, let's create a project specific virtual environment and activate it.
196- This will install all of the project's development dependencies as well as
197- the project itself. The project will be installed as an editable package (by
198- using the ``-e `` flag to ``pip ``).
209+ First, let's enter a project-specific virtual environment. Hatch
210+ will install any of the project's dependencies (if added to pyproject.toml) as well as
211+ the project itself as an editable package.
199212
200213.. code-block :: console
201214
202- $ make venv
203- ...
204- Enter virtual environment using:
205-
206- source venv/abc_123/bin/activate
207-
208- $ source venv/abc_123/bin/activate
215+ $ hatch shell
209216 (abc_123) $
210217
218+ You can exit the environment by typing `exit ` or using the Ctrl+d shortcut.
219+
211220Now that we have a virtual environment we can check the remaining convenience
212221functions provided by the Makefile.
213222
223+ There are a number of other virtual environments available to you, and
224+ most of these have their own packages and scripts to ease
225+ development. You can bring up a summary like so:
226+
214227.. code-block :: console
215228
216- (abc_123) $ make style
217- (abc_123) $ make check-style
218- (abc_123) $ make check-static-analysis
219- (abc_123) $ make test
220- (abc_123) $ make test-verbose
221- (abc_123) $ make coverage
222- (abc_123) $ make check-docs
223- (abc_123) $ make docs
224- (abc_123) $ make serve-docs # in browser navigate to http://localhost:8000/html
225- (abc_123) $ make dist
226- (abc_123) $ make dist-test
229+ $ hatch env show
230+ Standalone
231+ ┏━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
232+ ┃ Name ┃ Type ┃ Dependencies ┃ Scripts ┃
233+ ┡━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
234+ │ default │ virtual │ │ │
235+ ├──────────┼─────────┼──────────────┼──────────────────────┤
236+ │ coverage │ virtual │ coverage │ run-coverage │
237+ │ │ │ │ run-coverage-erase │
238+ │ │ │ │ run-coverage-html │
239+ │ │ │ │ run-coverage-report │
240+ │ │ │ │ run-coverage-tests │
241+ │ │ │ │ run-coverage-verbose │
242+ │ │ │ │ run-new-reports │
243+ │ │ │ │ run-reports │
244+ ├──────────┼─────────┼──────────────┼──────────────────────┤
245+ │ docs │ virtual │ sphinx │ build │
246+ │ │ │ │ build-dummy │
247+ ├──────────┼─────────┼──────────────┼──────────────────────┤
248+ │ lint │ virtual │ pylint │ check │
249+ ├──────────┼─────────┼──────────────┼──────────────────────┤
250+ │ style │ virtual │ black │ check │
251+ │ │ │ flake8 │ format │
252+ │ │ │ isort │ run-black │
253+ │ │ │ │ run-black-check │
254+ │ │ │ │ run-flake8 │
255+ │ │ │ │ run-isort │
256+ │ │ │ │ run-isort-check │
257+ ├──────────┼─────────┼──────────────┼──────────────────────┤
258+ │ types │ virtual │ mypy │ check │
259+ └──────────┴─────────┴──────────────┴──────────────────────┘
260+ $
261+
262+ You can enter use these virtual environments like so:
263+
264+ .. code-block :: console
265+
266+ $ hatch shell types
267+ (types) $ pip freeze
268+ # Editable Git install with no remote (abc_123==0.0.1)
269+ -e /home/abolte/tmp/cookiecutter-testing/abc_123
270+ mypy==1.14.1
271+ mypy-extensions==1.0.0
272+ typing_extensions==4.12.2
273+ (types) $ exit
274+ $ hatch run types:check
275+ Success: no issues found in 4 source files
276+ $
277+
278+ In other words, `hatch run ENV:SCRIPT ` (replacing *ENV * with something
279+ from the Name column in the above table, and *SCRIPT * likewise with
280+ something from the Scripts column) will allow various tools to be
281+ executed in a clean environment.
282+
283+ By splitting the tools out into separate environments, we save time by
284+ only installing packages that we actually need.
285+
286+ Take a look at the pyproject.toml configuration file to see precisely
287+ what each script does, and make any adjustments as desired.
288+
289+ If you have make installed, the included Makefile provides handy
290+ shortcuts for various Hatch commands and the configured scripts. You
291+ can print a summary of options via the `make help ` command, like so:
292+
293+ .. code-block :: console
294+
295+ $ make help
296+
297+ abc 123 Makefile help
298+
299+ help - display makefile help information
300+ venv - enter a dev virtual environment
301+ clean - clean all files using .gitignore rules
302+ scrub - clean all files, even untracked files
303+ test - run tests
304+ test-verbose - run tests [verbosely]
305+ coverage - perform test coverage checks
306+ format - perform code style format
307+ check-format - check code format compliance
308+ sort-imports - apply import sort ordering
309+ check-sort-imports - check imports are sorted
310+ style - perform code style format
311+ check-style - check code style compliance
312+ check-types - check type hint annotations
313+ check-lint - run static analysis checks
314+ check-static-analysis - check code style compliance
315+ docs - generate project documentation
316+ check-docs - quick check docs consistency
317+ serve-docs - serve project html documentation
318+ dist - create a wheel distribution package
319+ dist-test - test a wheel distribution package
320+ dist-upload - upload a wheel distribution package
321+
322+
323+ Here is an example of one in action:
324+
325+ .. code-block :: console
326+
327+ $ make coverage
328+ cmd [1] | coverage erase
329+ cmd [2] | coverage run -m unittest discover -s tests
330+ ..
331+ ----------------------------------------------------------------------
332+ Ran 2 tests in 0.021s
333+
334+ OK
335+ cmd [3] | coverage report
336+ Name Stmts Miss Branch BrPart Cover
337+ -----------------------------------------------------------
338+ src/abc_123/__init__.py 1 0 0 0 100%
339+ -----------------------------------------------------------
340+ TOTAL 1 0 0 0 100%
341+ cmd [4] | coverage html
342+ Wrote HTML report to docs/source/_static/coverage/index.html
343+ $
344+
345+
346+ Suggestions? Contributions? Problems?
347+ =====================================
348+
349+ Please open an Issue or a Pull Request! I'm open to hearing any
350+ suggestions.
0 commit comments