Skip to content

Commit d10e4c1

Browse files
authored
Updated CONTRIBUTING.md significantly. (#1431)
Our Contributor's Guide had a lot of outdated information in it. This updates it to solidly use the modern development workflow based around uv, make, and pre-commit. Also: - Update pre-commit to also check TOML files - Updated "make install" command to use the latest stable version of Python for the virtual environment, downloading that for uv if necessary, and also to install pre-commit hooks as well as prettier from npm.
1 parent 7549c93 commit d10e4c1

File tree

3 files changed

+169
-67
lines changed

3 files changed

+169
-67
lines changed

.github/CONTRIBUTING.md

Lines changed: 162 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# Contributor's guide
22

3-
We welcome pull requests from cmd2 users and seasoned Python developers alike! Follow these steps to contribute:
3+
We welcome pull requests from `cmd2` users and seasoned Python developers alike! Follow these steps to contribute:
44

55
1. Find an issue that needs assistance by searching for
66
the [Help Wanted](https://github.com/python-cmd2/cmd2/labels/help%20wanted) tag
77

88
2. Let us know you're working on it by posting a comment on the issue
99

10-
3. Follow the [Contribution guidelines](#contribution-guidelines) to start working on the issue
10+
3. Follow the [Contribution guidelines](#contribution-guidelines) below to start working on the issue
1111

1212
Remember to feel free to ask for help by leaving a comment within the Issue.
1313

@@ -25,7 +25,7 @@ Working on your first pull request? You can learn how from the
2525
- [Creating a branch](#creating-a-branch)
2626
- [Setting up for cmd2 development](#setting-up-for-cmd2-development)
2727
- [Making changes](#making-changes)
28-
- [Static code analysis](#static-code-analysis)
28+
- [Code Quality Checks](#code-quality-checks)
2929
- [Running the test suite](#running-the-test-suite)
3030
- [Squashing your commits](#squashing-your-commits)
3131
- [Creating a pull request](#creating-a-pull-request)
@@ -40,29 +40,45 @@ Working on your first pull request? You can learn how from the
4040

4141
### Prerequisites
4242

43-
The tables below list all prerequisites along with the minimum required version for each.
43+
`cmd2` development is heavily based around using [uv](https://github.com/astral-sh/uv) for Python package and project
44+
management as well as creating and updating a local Python virtual environment. We also rely on [npm](https://www.npmjs.com/)
45+
for installing a few dependencies like [prettier](https://prettier.io/) for formatting non-Python files.
4446

45-
> _Updating to the latest releases for all prerequisites via `uv` is recommended_.
47+
We have a [Makefile](../Makefile) with commands that make it quick and easy for developers to get everything setup and
48+
perform common development tasks.
49+
50+
Nearly all project configuration, including for dependencies and quality tools is in the [pyproject.toml](../pyproject.toml) file.
51+
52+
> _Updating to the latest releases for all prerequisites via `uv` is recommended_. This can be done with `uv lock --upgrade` followed by `uv sync`.
4653
4754
#### Prerequisites to run cmd2 applications
4855

49-
| Prerequisite | Minimum Version |
50-
| --------------------------------------------------- | --------------- |
51-
| [python](https://www.python.org/downloads/) | `3.9` |
52-
| [pyperclip](https://github.com/asweigart/pyperclip) | `1.8.2` |
53-
| [wcwidth](https://pypi.python.org/pypi/wcwidth) | `0.2.12` |
56+
See the `dependencies` list under the `[project]` heading in [pyproject.toml](../pyproject.toml).
57+
58+
| Prerequisite | Minimum Version | Purpose |
59+
| --------------------------------------------------- | --------------- | -------------------------------------- |
60+
| [python](https://www.python.org/downloads/) | `3.9` | Python programming language |
61+
| [pyperclip](https://github.com/asweigart/pyperclip) | `1.8` | Cross-platform clipboard functions |
62+
| [wcwidth](https://pypi.python.org/pypi/wcwidth) | `0.2.10` | Measure the displayed width of unicode |
63+
64+
> `macOS` and `Windows` each have an extra dependency to ensure they have a viable alternative to [readline](https://tiswww.case.edu/php/chet/readline/rltop.html) available.
5465
5566
#### Additional prerequisites to build and publish cmd2
5667

57-
| Prerequisite | Minimum Version |
58-
| -------------------------------------------------------- | --------------- |
59-
| [build](https://pypi.org/project/build/) | `1.2.2` |
60-
| [setuptools](https://pypi.org/project/setuptools/) | `72.1.0` |
61-
| [setuptools-scm](https://github.com/pypa/setuptools-scm) | `8.0.4` |
62-
| [twine](https://github.com/pypa/twine) | `5.1.1` |
68+
See the `build` list under the `[dependency-groups]` heading in [pyproject.toml](../pyproject.toml) for a list of dependencies needed for building `cmd2`.
69+
70+
| Prerequisite | Minimum Version | Purpose |
71+
| -------------------------------------------------------- | --------------- | -------------------------------- |
72+
| [build](https://pypi.org/project/build/) | `1.2.2` | Python build frontend |
73+
| [setuptools](https://pypi.org/project/setuptools/) | `72.1.0` | Python package management |
74+
| [setuptools-scm](https://github.com/pypa/setuptools-scm) | `8.0.4` | Manage your versions by scm tags |
75+
76+
> [twine](https://github.com/pypa/twine) 5.1 or newer is also needed for publishing releases to PyPI, but that is something only core maintainers need to worry about.
6377
6478
#### Additional prerequisites for developing cmd2
6579

80+
See the `dev` list under the `[dependency-groups]` heading in [pyproject.toml](../pyproject.toml) for a list of dependencies needed for building `cmd2`.
81+
6682
| Prerequisite | Minimum Version | Purpose |
6783
| ------------------------------------------------------------------------------------------ | --------------- | -------------------------------- |
6884
| [codecov](http://doc.pytest.org/en/latest/) | `2.1.13` | Cover coverage reporting |
@@ -205,8 +221,7 @@ _[this](https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git
205221

206222
### Setting up for cmd2 development
207223

208-
For doing cmd2 development, it is recommended you create a virtual environment using Conda or Virtualenv and install the
209-
package from the source.
224+
For doing `cmd2` development, it is strongly recommended you create a virtual environment `uv` using the instructions in the next section.
210225

211226
#### Create a new environment for cmd2 using uv
212227

@@ -216,18 +231,14 @@ package from the source.
216231
contains configuration for using `uv` in it's `pyproject.toml` file which makes it extremely easy to setup a `cmd2`
217232
development environment using `uv`.
218233

219-
To create a virtual environment and install everything needed for `cmd2` development using `uv`, do the following
220-
from a GitHub checkout:
234+
To create a virtual environment using the latest stable version of Python and install everything needed for `cmd2` development using `uv`,
235+
do the following from the root of your cloned `cmd2` repository:
221236

222237
```sh
223238
make install
224239
```
225240

226-
To install the recommended Git pre-commit hooks for auto-formatting locally, do the following:
227-
228-
```sh
229-
uv run pre-commit run -a
230-
```
241+
This will also install the recommended Git pre-commit hooks for auto-formatting and linting locally.
231242

232243
To create a new virtualenv, using a specific version of Python you have installed, use the
233244
--python VERSION flag, like so:
@@ -264,35 +275,31 @@ testing, rendering documentation, and building and distributing releases. These
264275
modules can be configured many different ways, which can make it difficult to
265276
learn the specific incantations required for each project you're familiar with.
266277

267-
This project uses `invoke <http://www.pyinvoke.org>` to provide a clean,
268-
high-level interface for these development tasks. To see the full list of functions
269-
available:
278+
This project uses [make]() to provide a clean, high-level interface for these development tasks. To see the full list of make commands available:
270279

271280
```sh
272-
$ uv run inv -l
281+
$ make help
273282
```
274283

275-
You can run multiple tasks in a single invocation, for example::
284+
You can run multiple make commands in a single invocation, for example::
276285

277286
```sh
278-
$ uv run inv docs sdist wheel
287+
$ make test docs-test
279288
```
280289

281-
That one command will remove all superfluous cache, testing, and build
282-
files, render the documentation, and build a source distribution and a
283-
wheel distribution.
290+
That one command will run all unit and integration tests and also ensure the documentation builds without any warnings.
284291

285-
If you want to see the details about what `invoke` is doing under the hood,
286-
have a look at `tasks.py`.
292+
If you want to see the details about what any of these commands are doing under the hood, just look at the [Makefile](../Makefile).
287293

288294
Now you can check if everything is installed and working:
289295

290296
```sh
291297
$ cd ~src/cmd2
292-
$ uv run inv pytest
298+
$ make check
293299
```
294300

295-
If the tests are executed it means that dependencies and project are installed successfully.
301+
This will run all auto-formatters, linters, and type checkers to ensure code quality. You should run this every time before committing any code.
302+
If this all runs successfully, then your virtual environment is setup and working properly.
296303

297304
You can also run the example app and see a prompt that says "(Cmd)" running the command:
298305

@@ -315,67 +322,71 @@ This bit is up to you!
315322
The cmd2 project directory structure is pretty simple and straightforward. All
316323
actual code for cmd2 is located underneath the `cmd2` directory. The code to
317324
generate the documentation is in the `docs` directory. Unit tests are in the
318-
`tests` directory. The `examples` directory contains examples of how to use
319-
cmd2. There are various other files in the root directory, but these are
320-
primarily related to continuous integration and release deployment.
325+
`tests` directory. Integration tests are in the `tests_isolated` directory.
326+
The `examples` directory contains examples of how to use cmd2. There are various
327+
other files in the root directory, but these are primarily related to continuous
328+
integration and release deployment.
321329

322330
#### Changes to the documentation files
323331

324332
If you made changes to any file in the `/docs` directory, you need to build the
325333
MkDocs documentation and make sure your changes look good:
326334

327335
```sh
328-
$ uv inv docs
336+
$ make docs-test
329337
```
330338

331-
In order to see the changes, use your web browser of choice to open `~/cmd2/docs/_build/html/index.html`.
339+
In order to see the changes, use your web browser of choice to open `~/cmd2/build/html/index.html`.
332340

333341
If you would rather use a webserver to view the documentation, including
334342
automatic page refreshes as you edit the files, use:
335343

336344
```sh
337-
$ uv inv livehtml
345+
$ make docs
338346
```
339347

340348
You will be shown the IP address and port number where the documents are now
341-
served (usually [http://localhost:8000](http://localhost:8000)).
349+
served, usually [http://127.0.0.1:8000/](http://127.0.0.1:8000/).
342350

343351
### Code Quality Checks
344352

345-
You should have some sort of [PEP 8](https://www.python.org/dev/peps/pep-0008/)-based linting running in your editor or
346-
IDE or at the command line before you commit code. `cmd2` uses [ruff](https://github.com/astral-sh/ruff) as part of
347-
its continuous integration (CI) process for both linting and auto-formatting.
353+
You should have idiomatic formatters and linters running in your IDE or at the command line before you commit code.
354+
`cmd2` uses [ruff](https://github.com/astral-sh/ruff) as part of its continuous integration (CI) process for both linting and auto-formatting of
355+
Python code. It also uses [prettier](https://prettier.io/) for auto-formatting other file types and [mypy](https://mypy-lang.org/) for doing
356+
static type checking of Python code based on type annotations.
348357

349358
> Please do not ignore any linting errors in code you write or modify, as they are meant to **help** you and to ensure a
350359
> clean and simple code base. Don't worry about linting errors in code you don't touch though - cleaning up the legacy
351360
> code is a work in progress.
352361
353-
#### Formatting
354-
355-
To check if formatting is correct:
362+
You can quickly run all code quality stuff in one fell swoop using:
356363

357364
```sh
358-
uv run inv format
365+
make check
359366
```
360367

361-
To automatically fix formatting:
368+
#### Python Formatting
369+
370+
To check if Python formatting is correct:
362371

363372
```sh
364-
uv run ruff format
373+
make format
365374
```
366375

376+
NOTE: This will automatically fix the formatting, so just run it twice and it should be good.
377+
367378
#### Linting
368379

369-
To run the linter:
380+
To run the Python linter:
370381

371382
```shell
372-
uv run inv lint
383+
make lint
373384
```
374385

375386
#### Static Type Checking
376387

377388
```shell
378-
uv run inv mypy
389+
make typecheck
379390
```
380391

381392
### Running the test suite
@@ -384,7 +395,7 @@ When you're ready to share your code, run the test suite:
384395

385396
```sh
386397
$ cd ~/cmd2
387-
$ uv run pytest
398+
$ make test
388399
```
389400

390401
and ensure all tests pass.
@@ -394,9 +405,9 @@ is shown on the screen. A full report is available in `~/cmd2/htmlcov/index.html
394405

395406
### Squashing your commits
396407

397-
When you make a pull request, it is preferable for all of your changes to be in one commit.
398-
If you have made more then one commit, then you can _squash_ your commits.
399-
To do this, see [this article](http://forum.freecodecamp.com/t/how-to-squash-multiple-commits-into-one-with-git/13231).
408+
While squashing your commits is best practice, don't worry about it. We do this automatically when we merge in Pull Requests (PRs).
409+
410+
If you want to understand how to do this manually, see [this article](http://forum.freecodecamp.com/t/how-to-squash-multiple-commits-into-one-with-git/13231).
400411

401412
### Creating a pull request
402413

@@ -515,9 +526,9 @@ how to do it.
515526
### How we review and merge pull requests
516527

517528
cmd2 has a team of volunteer Maintainers. These Maintainers routinely go through open pull requests in a process
518-
called [Quality Assurance](https://en.wikipedia.org/wiki/Quality_assurance) (QA). We also use multiple continuous
519-
integration (CI) providers to automatically run all of the unit tests on multiple operating systems and versions of
520-
Python.
529+
called [Quality Assurance](https://en.wikipedia.org/wiki/Quality_assurance) (QA). We use [GitHub Actions](https://github.com/features/actions)
530+
to automatically run all of the unit tests on multiple operating systems and versions of Python and to also run the code quality checks
531+
on at least one version of Python.
521532

522533
1. If your changes can merge without conflicts and all unit tests pass for all OSes and supported versions of Python,
523534
then your pull request (PR) will have a big green checkbox which says something like "All Checks Passed" next to it.
@@ -601,6 +612,93 @@ excellent support for debugging console applications.
601612
[PyCharm](https://www.jetbrains.com/pycharm/) is also quite good and has very
602613
nice [code inspection](https://www.jetbrains.com/help/pycharm/code-inspection.html) capabilities.
603614

615+
#### PyCharm Settings
616+
617+
One of the best things about **PyCharm** is that it "just works" with essentially no configuration tweaks required. The
618+
default out-of-the-box experience is excellent.
619+
620+
The one plugin we consider essential for PyCharm is [RyeCharm](https://plugins.jetbrains.com/plugin/25230-ryecharm). `RyeCharm` is an all-in-one PyCharm plugin for [Astral](https://astral.sh/)-backed Python tools: [uv](https://github.com/astral-sh/uv), [Ruff](https://github.com/astral-sh/ruff), and [ty](https://github.com/astral-sh/ty). NOTE: `ty` support is provisional as that new type checker is in early alpha developement.
621+
622+
#### VSCode Settings
623+
624+
While **VSCode** is a phenomenal IDE for developing in Python, the out-of-the-box experience leaves a lot to be desired. You will need to install a
625+
number of extenstions and tweak the default configuration for many of them in order to get an optimal developer experience.
626+
627+
Recommended VSCode extensions:
628+
629+
- [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) - Python language support with extension access points for IntelliSense (Pylance), Debugging (Python Debugger), linting, formatting, etc.
630+
- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) - Code formatter for Markdown and YAML files
631+
- [GitLens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) - Supercharges Git support in VSCode
632+
- [YAML](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) - YAML language support
633+
- [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) - Spell checker for source code
634+
- [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) - All you need to write Markdown (keyboard shortcuts, table of contents, auto preview and more)
635+
- [Makefile Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools) - Provide makefile support in VS Code
636+
- [Even Better TOML](https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml) - Fully-featured TOML support
637+
- [Markdown Preview Mermaid Support](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid) - Adds Mermaid diagram and flowchart support to VS Code's builtin markdown preview
638+
- [Ruff](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff) - Support for the Ruff linter and formatter
639+
640+
Depending on what file types you are editing, you may only need a subset of those extensions.
641+
642+
Here is an example of what your `User Settings JSON` file in VSCode might look like for a good experience, take it as a starting point and tweak as you see fit
643+
644+
```json
645+
{
646+
"[css]": {
647+
"editor.defaultFormatter": "esbenp.prettier-vscode"
648+
},
649+
"editor.formatOnSave": true,
650+
"editor.largeFileOptimizations": false,
651+
"editor.renderWhitespace": "trailing",
652+
"git.blame.editorDecoration.enabled": false,
653+
"git.openRepositoryInParentFolders": "always",
654+
"gitlens.telemetry.enabled": false,
655+
"[html]": {
656+
"editor.defaultFormatter": "esbenp.prettier-vscode"
657+
},
658+
"[json]": {
659+
"editor.defaultFormatter": "esbenp.prettier-vscode"
660+
},
661+
"[markdown]": {
662+
"editor.defaultFormatter": "esbenp.prettier-vscode",
663+
"editor.formatOnSave": true,
664+
"editor.formatOnPaste": true
665+
},
666+
"python.analysis.ignore": ["*"],
667+
"python.terminal.shellIntegration.enabled": true,
668+
"[python]": {
669+
"editor.formatOnSave": true,
670+
"editor.defaultFormatter": "charliermarsh.ruff",
671+
"editor.codeActionsOnSave": {
672+
"source.fixAll": "explicit",
673+
"source.organizeImports": "explicit"
674+
}
675+
},
676+
"redhat.telemetry.enabled": false,
677+
"ruff.lineLength": 127,
678+
"security.workspace.trust.untrustedFiles": "open",
679+
"telemetry.telemetryLevel": "off",
680+
"[toml]": {
681+
"editor.defaultFormatter": "esbenp.prettier-vscode",
682+
"editor.formatOnSave": true
683+
},
684+
"yaml.schemas": {
685+
"https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml"
686+
},
687+
"yaml.customTags": [
688+
"!ENV scalar",
689+
"!ENV sequence",
690+
"!relative scalar",
691+
"tag:yaml.org,2002:python/name:material.extensions.emoji.to_svg",
692+
"tag:yaml.org,2002:python/name:material.extensions.emoji.twemoji",
693+
"tag:yaml.org,2002:python/name:pymdownx.superfences.fence_code_format",
694+
"tag:yaml.org,2002:python/object/apply:pymdownx.slugs.slugify mapping"
695+
],
696+
"[yaml]": {
697+
"editor.defaultFormatter": "esbenp.prettier-vscode"
698+
}
699+
}
700+
```
701+
604702
## Branching Strategy and Semantic Versioning
605703

606704
Starting with version 1.0.0, `cmd2` has adopted [Semantic Versioning](https://semver.org).

.pre-commit-config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ repos:
44
hooks:
55
- id: check-case-conflict
66
- id: check-merge-conflict
7+
- id: check-toml
78
- id: end-of-file-fixer
89
- id: trailing-whitespace
910

@@ -13,7 +14,7 @@ repos:
1314
- id: ruff-format
1415
args: [--config=pyproject.toml]
1516
- id: ruff-check
16-
args: [--config=pyproject.toml, --fix]
17+
args: [--config=pyproject.toml, --fix, --exit-non-zero-on-fix]
1718

1819
- repo: https://github.com/pre-commit/mirrors-prettier
1920
rev: "v3.1.0"

0 commit comments

Comments
 (0)