silkaj issueshttps://git.duniter.org/clients/python/silkaj/-/issues2024-03-13T21:17:47+01:00https://git.duniter.org/clients/python/silkaj/-/issues/433Set up new website structure with MkDocs2024-03-13T21:17:47+01:00MoulSet up new website structure with MkDocs## MkDocs
- https://www.mkdocs.org/
- https://github.com/mkdocs/mkdocs
- https://github.com/mkdocs/catalog
- https://repology.org/badge/vertical-allrepos/python:mkdocs.svg
- https://repology.org/badge/vertical-allrepos/mkdocs.svg
- Used ...## MkDocs
- https://www.mkdocs.org/
- https://github.com/mkdocs/mkdocs
- https://github.com/mkdocs/catalog
- https://repology.org/badge/vertical-allrepos/python:mkdocs.svg
- https://repology.org/badge/vertical-allrepos/mkdocs.svg
- Used by [substrate-interface](https://polkascan.github.io/py-substrate-interface/), [Textual](https://textual.textualize.io/), [Pipx](https://pypa.github.io/pipx/), and [Ruff](https://docs.astral.sh/ruff/)
- Allows to build markdown docs from the repository
- Very simple static framework website written in Python
## Tasks
### MkDocs initial set-up
- [x] Read the User Guide
- [x] `pyproject.toml`: Introduce `mkdocs` dependencies in `doc` group
- [x] Set-up initial project `mkdocs.yml`
- [x] Move `md` files to default `docs` directory
- [x] Set symlinks for changelog, contributing(, readme)
- [x] Choose theme: [material](https://squidfunk.github.io/mkdocs-material/)
- [x] Set favicon
- [x] Night/day switch
- [x] Set-up navigation with current content
### Deployment
```yaml
poetry install --only docs
poetry run mkdocs build -d public
```
- [x] Support website/documentation per releases and development one with [Mike](https://github.com/jimporter/mike):
- Drop-down support to switch between ie `v0.12` and `main`
- [x] Mike git commits changes to `pages` branch. Add `.gitlab-ci.yml` on this branch to publish the website and its’s multiple versions (no need schedule)
- [x] On `pages` branch: basic `.gitlab-ci.yml` to copy the content into a `public` directory and publish to GitLab Pages via a `pages` job
- [GitLab Pages implementation](https://gitlab.com/groups/gitlab-org/-/epics/10914), will come later in the Community edition
- https://pypi.org/project/lightweight-versioned-gitlab-pages/
- https://stackoverflow.com/questions/55596789/deploying-gitlab-pages-for-different-branches/58915486#58915486
- only on `main` branch and `tag`? Set `RELEASE` variable to `0.12` or to `0.20-dev`.
- how to handle the coverage and website deployments?
- [`mkdocs-coverage`](https://github.com/pawamoy/mkdocs-coverage)
- `website` job [`needs:`](https://docs.gitlab.com/ee/ci/yaml/#needs) `tests:3.12:cov` job artifact
- https://stackoverflow.com/a/64008569
- handle coverage display on `main` branch, don’t display `Coverage` tab when on release branch? Always display.
- [x] Protect `pages` branch
- [ ] Update coverage badge link to website coverage path
- [x] Adapt GitLab Pages deployment: Ansible role, now from Silkaj repository
- Not sure if Ansible configuration would work with three paths `clients/python/silkaj`
### Document contribution
- [x] How to install `mkdocs`, serve the docs, build locally
- Link mkdocs, material, mike, coverage, gitlab … docs
### Set up structure and use existing content
- [x] Fix `mkdocs serve` warnings
- [x] Update links in release notes, contributing(, readme)
- [x] `README.md` `CONTRIBUTING.md`: update links to the URL of this website
- [x] Create index/main page inspired from [Textual one](https://github.com/Textualize/textual/blob/d958f5bf778a3807ba75884fe15134c6dc294460/docs/index.md)
- [x] Clean and proofread current documentation
- move container usage (and poetry installation) to install section? Advanced installation, somehow contributing stuff. Nope?
- [x] enable syntax highlight, fix code block where we don’t want it
- [x] enable code block copy where needed
- [x] Id anchors in changelog
- [x] Move `CHANGELOG.md` to `docs/changelog.md`, with the `{ id=0.11.0 }` it might get ugly looking at it on GitLab. Same for `CONTRIBUTING.md`, Drop them from GitLab "syntax", not sure for the logos
- [x] create `CHANGELOG.md` and `CONTRIBUTING.md` referring to those pages on the website
- [x] structure `docs` folder: `usage`, `contributing`
- [x] Introduce [`mdformat-mkdocs`](https://github.com/KyleKing/mdformat-mkdocs) to format with four spaces bullet points
- [x] Keep `mike` `prefix_path` to `public`, serving to http://localhost:8000/pages (needs doc precision) or select `version.json`, `latest`, and `0.12` items in the artifact
- [x] Integrate generated coverage with [`mkdocs-coverage`](https://github.com/pawamoy/mkdocs-coverage)
- [x] Changelog with [`mkdocs-gitlab-plugin`](https://pypi.org/project/mkdocs-gitlab-plugin/):
- had to find the `gitlab_links` plugins name in `setup.py`, report that it would be great to have it in the readme: contribute
- Would be great to being able to [link other projects such as DuniterPy](https://gitlab.inria.fr/vidjil/mkdocs-gitlab-plugin/-/issues/1)
- [x] Blog tab containing releases notes:
- [x] Move `releases_notes` directory in `docs/blog` directory
- [x] Set up built-in `mkdocs-material` blog (not [`mkdocs-blogging-plugin`](https://github.com/liang2kl/mkdocs-blogging-plugin))
- Yaml frontmatter kept: [`mdformat-frontmatter`](https://github.com/butler54/mdformat-frontmatter)
- [x] Add [excerpts](https://squidfunk.github.io/mkdocs-material/setup/setting-up-a-blog/#adding-an-excerpt)
- [x] Add [authors](https://squidfunk.github.io/mkdocs-material/setup/setting-up-a-blog/#adding-authors)
- [x] Local author profile picture not available from archive, category slug, set up url formats
- [x] Set up categories/tags for the releases and RC testing to separated them
- [x] [Add badge](https://squidfunk.github.io/mkdocs-material/blog/2023/11/30/adding-a-badge-to-your-project/) to readme and GitLab repo badges
- [x] [disable fonts coming from Google gstatic](https://github.com/squidfunk/mkdocs-material/issues/739#issuecomment-377978270)
- [x] Retrieve valuable content from current and Vue websites (no real value left: intro text maybe?)
### Archive current websites
- [x] Archive [two other websites repositories](https://git.duniter.org/websites)
- https://git.duniter.org/websites/silkaj_website
- https://git.duniter.org/websites/doc_silkaj
Set them as archives. Visible in [the archived tab](https://git.duniter.org/groups/websites/-/archived). Redirect, saying that the website is now in Silkaj repository
Thank Manutopik for the Vue website solution which wasn’t retained.
I prefer MkDocs: it’s written in Python, it’s simple, (no JS), I have full control over it0.12.0MoulMoulhttps://git.duniter.org/clients/python/silkaj/-/issues/314Display option to display the generated document before sending it2022-06-05T15:28:04+02:00MoulDisplay option to display the generated document before sending itImplement `--display/-d` option for the five send-documents commands. Implement it as a general option that would be used by the five commands: `tx`, `cert`, `membership`, `identity`, and `revocation`.
It would display the generated doc...Implement `--display/-d` option for the five send-documents commands. Implement it as a general option that would be used by the five commands: `tx`, `cert`, `membership`, `identity`, and `revocation`.
It would display the generated document, and would ask to send it or not. Afterwards, a confirmation prompt ask to send it after a visual check have been performed.
This would allow to be sure we are sending the correct document and it can also be used for debugging and testing purposes.
### Tasks
- [x] By-pass prompts?: license approval, send doc confirmation. No, since it would allow to send a document by by-passing them.
- [x] Merge table summary and document display confirmations when this option is passed
- [x] Global option over command-specific options? Would not duplicate five decorators on the five send-documents commands.
- [x] Display the document with and without the signature in case the `key` is not defined
- [x] In case the document have been signed (`key` provided), suggest to send the document after displaying it
#### Commands
- [x] `cert`
- [x] #88: `membership`
- [ ] #380: `tx`
- [ ] #89: `revocation`
- [ ] #90: `identity`BacklogMoulMoulhttps://git.duniter.org/clients/python/silkaj/-/issues/166Document shell completion set up2024-03-27T23:28:41+01:00Jonas SmedegaardDocument shell completion set upHi,
Would be nice if silkaj registered with bash to offer TAB-completion of its various command-line options and arguments.
This seems helpful: https://stackoverflow.com/questions/52282173/extending-bash-completion-with-python-clickHi,
Would be nice if silkaj registered with bash to offer TAB-completion of its various command-line options and arguments.
This seems helpful: https://stackoverflow.com/questions/52282173/extending-bash-completion-with-python-click0.12.0MoulMoulhttps://git.duniter.org/clients/python/silkaj/-/issues/147Add integration tests2021-04-08T14:18:22+02:00Sébastien DA ROCHAAdd integration testsAccording to https://git.duniter.org/clients/python/silkaj/merge_requests/83#note_11369
We can make some simple end to end test, but to ensure data is correct, we should use something to mock the blockchain, either by using duniterpy-mi...According to https://git.duniter.org/clients/python/silkaj/merge_requests/83#note_11369
We can make some simple end to end test, but to ensure data is correct, we should use something to mock the blockchain, either by using duniterpy-mirage or by using a generic tool like betamax (records the http requests while play the test for the first time, and replay the record the next times).Backloghttps://git.duniter.org/clients/python/silkaj/-/issues/90Implement the identity and all the process around to create a member identity2023-10-21T08:44:34+02:00MoulImplement the identity and all the process around to create a member identity- Display a summary of what have to be done
- license approval
- define `id`, `credentials` with strong rules:
- clients/python/duniterpy#150
- [mnemotic](https://forum.duniter.org/t/dup-mnemonic-cli-mnemotic-passphrase-generator/692...- Display a summary of what have to be done
- license approval
- define `id`, `credentials` with strong rules:
- clients/python/duniterpy#150
- [mnemotic](https://forum.duniter.org/t/dup-mnemonic-cli-mnemotic-passphrase-generator/6922): [PyPI](https://github.com/trezor/python-mnemonic), [Debian](https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=python3-mnemonic)
- special char, lengh, use a python module for checking this rules
- [pip](https://pypi.org/search/?q=password), [haven’t found any package on Debian](https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=python3-password), [YnH class](https://github.com/YunoHost/yunohost/blob/stretch-unstable/src/yunohost/utils/password.py).
- warn that the credentials can’t be changed afterwards
- [save revocation document](#89)
- send the identity document
- propose to [send the membership document](#88)0.21.0https://git.duniter.org/clients/python/silkaj/-/issues/487Move sources in `src` directory2024-03-27T21:18:01+01:00MoulMove sources in `src` directory…as [recommended by Python packaging](https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/).
- [ ] Move `silkaj` directory in `src` directory
- [ ] Add this commit in a `.git-blame-ignore-revs`?…as [recommended by Python packaging](https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/).
- [ ] Move `silkaj` directory in `src` directory
- [ ] Add this commit in a `.git-blame-ignore-revs`?Backloghttps://git.duniter.org/clients/python/silkaj/-/issues/486Website follow-ups2024-03-11T22:39:00+01:00MoulWebsite follow-ups### Advanced content
- [ ] Add new content to documentation: #479+
- [ ] Improve index/readme/first page
- [ ] #277+
- [ ] Set up [`mkdocs-rss-plugin`](https://guts.github.io/mkdocs-rss-plugin/)
- Fix warnings about temporary files gen...### Advanced content
- [ ] Add new content to documentation: #479+
- [ ] Improve index/readme/first page
- [ ] #277+
- [ ] Set up [`mkdocs-rss-plugin`](https://guts.github.io/mkdocs-rss-plugin/)
- Fix warnings about temporary files generated in `/tmp` for coverage and blog
- [ ] Website navigation thinking
- [ ] Automatically generate CLI usage with [`mkdocs-click`](https://github.com/mkdocs/mkdocs-click) (#179+)
- [ ] #468+: automatically generate screenshots
- [ ] Donation page: to Silkaj and Duniter projects
### Set up new domain name
- [ ] Domain name: silkaj.${tld}?
- [ ] Choose domain name, rent it
- [ ] CNAME to pages.duniter.org
- [ ] Adapt Ansible conf
- [ ] Set silkaj.duniter.org redirection to new domain
<!--
- https://en.wikipedia.org/wiki/.ml
- https://en.wikipedia.org/wiki/.lc
.click, .site, .website, .world
-->0.20.0https://git.duniter.org/clients/python/silkaj/-/issues/485Bump copyright to 20252023-12-09T14:01:05+01:00MoulBump copyright to 2025- [ ] Update to 2025:
- [In the header file](https://git.duniter.org/clients/python/silkaj/-/blob/main/CONTRIBUTING.md#update-copyright-year)
- In MkDocs config once #433+ is done
- [ ] Open ticket for 2026 and link it to this one- [ ] Update to 2025:
- [In the header file](https://git.duniter.org/clients/python/silkaj/-/blob/main/CONTRIBUTING.md#update-copyright-year)
- In MkDocs config once #433+ is done
- [ ] Open ticket for 2026 and link it to this one0.20.02024-12-10https://git.duniter.org/clients/python/silkaj/-/issues/482Add support for Python v3.132023-11-20T14:27:16+01:00MoulAdd support for Python v3.13### Python pre-releases
- [ ] Set up v3.13 test job
- [ ] With `allow_failure: true`, to allow tests to fail
### Python stable release
- [ ] Remove `allow_failure: true`, now on the tests should pass
- [ ] Move coverage to v3.13 job
-...### Python pre-releases
- [ ] Set up v3.13 test job
- [ ] With `allow_failure: true`, to allow tests to fail
### Python stable release
- [ ] Remove `allow_failure: true`, now on the tests should pass
- [ ] Move coverage to v3.13 job
- [ ] Set default container used by jobs to v3.13
- [ ] Handle deprecation warning and breaking features
- [ ] Switch Silkaj image build to v3.13
### Post
- [ ] Open follow-up v3.14 tickets
### References
- Expected to be release the [October 1st 2024](https://peps.python.org/pep-0719/).
- docker/python3/poetry#10+
- clients/python/duniterpy#208+0.20.02024-10-01https://git.duniter.org/clients/python/silkaj/-/issues/479Document Silkaj usage2024-03-11T22:36:40+01:00MoulDocument Silkaj usage- [ ] Installation
- [ ] CLI basics: group of commands, general and command specific options
- [ ] Authentication: already in `account_storage`, move it somewhere else?
- [x] #477+
- [ ] `wot` commands:
- [ ] `lookup`
- [ ] `status`
...- [ ] Installation
- [ ] CLI basics: group of commands, general and command specific options
- [ ] Authentication: already in `account_storage`, move it somewhere else?
- [x] #477+
- [ ] `wot` commands:
- [ ] `lookup`
- [ ] `status`
- [ ] `certify`
- [ ] `membership`
- [ ] `revocation`
- [ ] `money` commands:
- [ ] `transfer`
- [ ] transfer to multiple recipients
- [ ] transfer with recipients from a file
- [ ] `balance`
- [ ] `history`
- [ ] `license`
- [ ] `blockchain` commands:
- [ ] `info`
- [ ] `blocks`
- [ ] How to
- [ ] How to create a wallet
- [ ] How to become member
- [ ] FAQ
To be put later on the website #433+0.20.0https://git.duniter.org/clients/python/silkaj/-/issues/478Implement authentication on money history command2023-08-16T21:12:04+02:00MoulImplement authentication on money history commandConvenient with account authentication.
- Can be done together with #350 refactoring
- [ ] Implement authentication on `money history` command
- [ ] Write tests
- [ ] Document usage also for `balance` commandConvenient with account authentication.
- Can be done together with #350 refactoring
- [ ] Implement authentication on `money history` command
- [ ] Write tests
- [ ] Document usage also for `balance` commandBackloghttps://git.duniter.org/clients/python/silkaj/-/issues/477Account storage support: authentication, revocation2024-02-29T08:56:19+01:00MoulAccount storage support: authentication, revocation- https://askubuntu.com/a/14536
- Storage per currency, per account name
- `$XDG_DATA_HOME`|`$HOME/.local/share/silkaj/${currency}`
- `${account_name}`: defined by the user, passed via general/specific option `-a/--account`
- `revo...- https://askubuntu.com/a/14536
- Storage per currency, per account name
- `$XDG_DATA_HOME`|`$HOME/.local/share/silkaj/${currency}`
- `${account_name}`: defined by the user, passed via general/specific option `-a/--account`
- `revocation.txt`
- `authentication_file_${format}.json`: Silkaj would discover which format is it, v1 formats will be dropped at some point
## Implementation
### Account storage
* [x] Introduce global `-a/--account` option
* [x] Storage class into `silkaj/storage.py` with tests `tests/units/test_storage.py`
### Authentication
Read from `--auth-*` method, store into account storage:
```plaintext
silkaj --account <account> authentication --auth-*
```
Need special handling of `--auth-*` and `--account` options separately in the authentication selection handling for the `authentication` command. Other commands using the authentication should read only from `--account`. The `authentication` command is kind of a converter command from `--auth-*` methods to account storage.
Use `authentication` command as an importer from scattered files to this account storage structure
* [x] Move `--auth-*` options as `authentication` specific options?
- Con: Would no longer allow easy authentication on other commands
- Pro: Would force more secure account storage usage, conversion
* [x] Set authentication methods as `MutuallyExclusive`
* [x] Implementation in `authentication` command to store in the account storage
* [x] Support a better default authentication file format creation in the storage than `seedhex`?
* [x] Implement [(E)WIF](https://git.duniter.org/documents/rfcs/-/blob/master/rfc/0013_Duniter_Encrypted_Wallet_Import_Format.md) authfile saving #173
* [ ] Discover which authfile format it is: v1 (seedhex, pubsec), v2 (encrypted json)
- `authentication_file_ed25519.txt`, `authentication_file_sr25519.json`
* [ ] Write tests
### Revocation
```plaintext
# read auth file, write revocation file
silkaj --account <account> wot revocation create
# read revocation file
silkaj --account <account> wot revocation {verify,publish}
```
* [x] `create` read authfile from `--account` and write revocation file into `--account`
* [x] `verify`/`publish`: consume file from general `--account` option
* [ ] Write tests
### Importer command?
- `account import`
- import already generated auth and revocation files to an account?
### New Account label
- [x] replace `Storage` label
### Documentation
- [x] Write documentation how this works (input as general option, output as command-specific option)
- [x] Update `README.md§Features` with `Account (storage)` and `Authentication methods`.
### `account` commands
- `account list` command
```py
def list(self):
for root, dirnames, filenames in self.path.parent.walk():
print(root, dirnames, filenames)
```
- list available accounts per currencies: there contents, auth file, revocation file
- following implementations can all be done with Unix commands. To be done in a follow-up ticket?
- instead of a copy to the right place?
- `account remove $account`: remove complete account, remove only authentication or revocation file?
- `account rename $old_name $new_name`0.12.0MoulMoulhttps://git.duniter.org/clients/python/silkaj/-/issues/471Rename transfer’s comment to reference2023-06-30T16:20:34+02:00MoulRename transfer’s comment to referenceBanks are using this term: _Payment reference_.
This is more what we are aiming for.
- [ ] Rename CLI option: `silkaj money transfer -c/--comment` −> `-ref/--reference`. `-r` is already used by `--recipient`
- [ ] Rename UI fields of `t...Banks are using this term: _Payment reference_.
This is more what we are aiming for.
- [ ] Rename CLI option: `silkaj money transfer -c/--comment` −> `-ref/--reference`. `-r` is already used by `--recipient`
- [ ] Rename UI fields of `transfer` and `history` commands
- [ ] Adapt run time code and tests. Keep it named `comment` when using DuniterPy document, that’s the interface we won’t change.Backloghttps://git.duniter.org/clients/python/silkaj/-/issues/468rich-codex: Automate terminal screenshot for doc2024-03-11T22:36:41+01:00Moulrich-codex: Automate terminal screenshot for doc- https://github.com/ewels/rich-codex
- https://ewels.github.io/rich-codex/- https://github.com/ewels/rich-codex
- https://ewels.github.io/rich-codex/Backloghttps://git.duniter.org/clients/python/silkaj/-/issues/467Consider trogon: turn Click CLI app into a powerful terminal app2023-06-04T19:45:25+02:00MoulConsider trogon: turn Click CLI app into a powerful terminal app- https://github.com/Textualize/trogon- https://github.com/Textualize/trogonBackloghttps://git.duniter.org/clients/python/silkaj/-/issues/464Drop Python v3.8 support2023-09-22T16:15:29+02:00MoulDrop Python v3.8 support### Date when Python project won’t support v3.8
- [Python 3.8 support will be dropped in October 14th of 2024](https://devguide.python.org/versions/) [[1](https://endoflife.date/python)]
- [Platform which still uses Py3.8](https://repolo...### Date when Python project won’t support v3.8
- [Python 3.8 support will be dropped in October 14th of 2024](https://devguide.python.org/versions/) [[1](https://endoflife.date/python)]
- [Platform which still uses Py3.8](https://repology.org/badge/vertical-allrepos/python.svg)
## Todos
### DuniterPy
- [ ] Create DuniterPy follow-up? duniterpy#193+
### Silkaj
- [ ] `pyproject.toml`: Bump minimum versions:
- [ ] `tools.poetry.dependency.python`
- [ ] `tools.ruff.target-version`
- [ ] Delete test job for v3.8 from `.gitlab-ci.yml`
### Container
- [ ] Remove v3.8 Docker image generation. Can be removed when no Silkaj or DuniterPy maintenance releases support are stopped
---
- [ ] Create ticket for dropping Python 3.9 supportBacklog2024-10-14https://git.duniter.org/clients/python/silkaj/-/issues/463Consider Ward test framework2023-04-10T14:50:27+02:00MoulConsider Ward test framework- https://github.com/darrenburns/ward
- https://ward.readthedocs.io/en/latest/- https://github.com/darrenburns/ward
- https://ward.readthedocs.io/en/latest/Backloghttps://git.duniter.org/clients/python/silkaj/-/issues/462DeathReaper enhancements2023-11-13T15:06:54+01:00MoulDeathReaper enhancements### Display job link in the message
- [ ] New `--{job,pipeline}-link` Silkaj option to pass the link to the job which generated the message.
- [ ] [Predefined variables reference](https://docs.gitlab.com/ee/ci/variables/predefined_vari...### Display job link in the message
- [ ] New `--{job,pipeline}-link` Silkaj option to pass the link to the job which generated the message.
- [ ] [Predefined variables reference](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html): `CI_JOB_URL`, `CI_PIPELINE_URL`
- [ ] DeathReaper CI: pass `CI_JOB_URL` [GitLab predefined variable](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)
`Generated [from job](link).`
### Report number of exclusions in the report
- [ ] as a header: `Number of exclusions since $T: $X`
### Ability to pass Discourse forums URLs as an option
- Great pre-requisite for #446+
- With multiple-values: `@click.option(multiple=True)`
- [ ] `--discourse-forums-urls/-dfu forum.monnaie-libre.fr forum.duniter.org foro.moneda-libre.org` `--api-key ml-fr, duniter, ml-es`
### Tests
- [ ] Add tests, since `excluded` coverage is 38%, and makes the total coverage drop from 81 to 77%Backloghttps://git.duniter.org/clients/python/silkaj/-/issues/461Publish Silkaj container to DockerHub2023-03-10T13:48:58+01:00MoulPublish Silkaj container to DockerHubPublish additionally Silkaj container to DockerHub for more visibility.
- [ ] Publish `pip` image
- [ ] Publish readme as Duniter-v2s is doingPublish additionally Silkaj container to DockerHub for more visibility.
- [ ] Publish `pip` image
- [ ] Publish readme as Duniter-v2s is doingBackloghttps://git.duniter.org/clients/python/silkaj/-/issues/460Harden Ruff rules2023-02-18T18:06:11+01:00MoulHarden Ruff rules#### Rules to introduce
- "C90", "N", "ANN", "EM", "T20", "TCH", "ARG"
```toml
[tool.ruff.mccabe]
# Unlike Flake8, default to a complexity level of 10.
max-complexity = 8
```#### Rules to introduce
- "C90", "N", "ANN", "EM", "T20", "TCH", "ARG"
```toml
[tool.ruff.mccabe]
# Unlike Flake8, default to a complexity level of 10.
max-complexity = 8
```Backlog