Skip to content

Commit e65bc26

Browse files
committed
Add more diagrams
1 parent ecf4dd2 commit e65bc26

6 files changed

Lines changed: 120 additions & 2 deletions

File tree

changelog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
> [!WARNING]
66
> This version is **not released yet** and is under active development.
77
8-
- Add Mermaid diagrams to the configuration documentation. A new "Resolving a configuration file" section charts how a config source is selected (explicit `--config` versus autodiscovery, CWD `pyproject.toml` search, app-dir glob, first parseable file wins), and the "Precedence" section now renders the value-resolution chain (interactive prompt, CLI parameters, environment variables, configuration file, defaults) as a flowchart instead of a nested list.
8+
- Add Mermaid diagrams throughout the documentation to render resolution and layering rules previously carried by prose or nested lists: configuration-file source selection and value precedence (`config.md`), the Click / Cloup / click-extra class layering and the `@command`/`@group` default-option bundle (`commands.md`), `--color`/`--no-color` ANSI enablement (`colorize.md`), the `{version}` and `{exec_name}` fallback chains (`version.md`), the `decorator_factory` subclass guardrail (`decorators.md`), and environment-variable id resolution (`envvar.md`).
99

1010
## [`7.17.1` (2026-05-25)](https://github.com/kdeldycke/click-extra/compare/v7.17.0...v7.17.1)
1111

docs/colorize.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,21 @@ Click Extra adds a `--color`/`--no-color` flag (aliased as `--ansi`/`--no-ansi`)
215215

216216
The option respects the [`NO_COLOR`](https://no-color.org), `CLICOLOR`, and `CLICOLOR_FORCE` environment variables. When any of these signals "no color", the environment takes precedence over the default value (but an explicit `--color` or `--no-color` on the command line always wins).
217217

218+
```mermaid
219+
:align: center
220+
221+
flowchart TD
222+
start(["echo() must decide: emit ANSI codes?"]) --> cli{"--color / --no-color<br/>set on CLI or via config?"}
223+
cli -->|yes| useflag["use that value"]
224+
cli -->|"no (built-in default)"| env{"a recognized color env var set?<br/>NO_COLOR, CLICOLOR, CLICOLOR_FORCE,<br/>FORCE_COLOR, LLM, ..."}
225+
env -->|yes| envval["ON if any signals color,<br/>OFF otherwise"]
226+
env -->|no| deflt["default: color ON"]
227+
useflag --> ctxcolor(["ctx.color"])
228+
envval --> ctxcolor
229+
deflt --> ctxcolor
230+
ctxcolor --> strip["echo() strips ANSI when OFF;<br/>NO_COLOR also blanks --theme output"]
231+
```
232+
218233
All Click Extra commands and groups include this option by default. Use `color_option` as a standalone decorator when building CLIs with plain `click.command`:
219234

220235
```{click:source}

docs/commands.md

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,43 @@ At the module level, `click_extra` imports all elements from `click.*`, then all
1212

1313
Which means all elements not redefined by Click Extra fallback to Cloup. And if Cloup itself does not redefine them, they fallback to Click.
1414

15+
For the types Click Extra does re-implement, each subclasses its Cloup counterpart, which in turn subclasses Click's (arrows point from a child to the parent it inherits from):
16+
17+
```mermaid
18+
:align: center
19+
20+
flowchart TB
21+
subgraph CE["click_extra (extends and overrides)"]
22+
direction LR
23+
XCmd["ExtraCommand"]
24+
XGrp["ExtraGroup"]
25+
XOpt["Option"]
26+
XCtx["ExtraContext"]
27+
XSty["Style"]
28+
end
29+
subgraph CL["cloup (first fallback)"]
30+
direction LR
31+
CCmd["cloup.Command"]
32+
CGrp["cloup.Group"]
33+
COpt["cloup.Option"]
34+
CCtx["cloup.Context"]
35+
CSty["cloup.Style"]
36+
end
37+
subgraph CK["click (base)"]
38+
direction LR
39+
KCmd["click.Command"]
40+
KGrp["click.Group"]
41+
KOpt["click.Option"]
42+
KCtx["click.Context"]
43+
KSty["click.style()"]
44+
end
45+
XCmd --> CCmd --> KCmd
46+
XGrp --> CGrp --> KGrp
47+
XOpt --> COpt --> KOpt
48+
XCtx --> CCtx --> KCtx
49+
XSty --> CSty -.->|wraps| KSty
50+
```
51+
1552
For example:
1653

1754
- `click_extra.echo` is a direct alias to `click.echo` because neither Click Extra or Cloup re-implements an `echo` helper.
@@ -77,7 +114,29 @@ You can inspect the implementation details in:
77114

78115
## Default options
79116

80-
The `@command` and `@group` decorators are pre-configured with a set of {py:func}`default options <click_extra.commands.default_extra_params>`.
117+
The `@command` and `@group` decorators are pre-configured with a set of {py:func}`default options <click_extra.commands.default_extra_params>`. The `--help`/`-h` option is added separately through `help_option_names`, which is why it survives even when `default_extra_params()` is reset:
118+
119+
```mermaid
120+
:align: center
121+
122+
flowchart LR
123+
cmd(["@command / @group"]) --> params
124+
cmd --> help["--help / -h"]
125+
subgraph params["default_extra_params()"]
126+
direction TB
127+
opt1["--time / --no-time"]
128+
opt2["--config"]
129+
opt3["--no-config"]
130+
opt4["--validate-config"]
131+
opt5["--color / --no-color"]
132+
opt6["--theme"]
133+
opt7["--show-params"]
134+
opt8["--table-format"]
135+
opt9["--verbosity"]
136+
opt10["--verbose / -v"]
137+
opt11["--version"]
138+
end
139+
```
81140

82141
```{tip}
83142
Each default option publishes its resolved value on `ctx.meta` so you can pick it up from anywhere in your CLI. See the [available keys](context.md#available-keys) table for the full inventory and worked examples.

docs/decorators.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,21 @@ group = decorator_factory(
3030
)
3131
```
3232

33+
```mermaid
34+
:align: center
35+
36+
flowchart TD
37+
call(["@command / @option(...)<br/>possibly with cls=Custom"]) --> paren{"called with<br/>or without parens?"}
38+
paren -->|"@command"| norm["allow_missing_parenthesis<br/>normalizes both call forms"]
39+
paren -->|"@command()"| norm
40+
norm --> has{"user passed cls= ?"}
41+
has -->|no| build["use the factory's default cls<br/>(ExtraCommand / ExtraGroup / ...)"]
42+
has -->|yes| sub{"cls subclasses<br/>the factory's cls?"}
43+
sub -->|yes| build
44+
sub -->|no| err["raise TypeError<br/>with the full MRO listing"]
45+
build --> out["decorator with merged defaults<br/>and a fresh params() list"]
46+
```
47+
3348
After that wiring, `@command` always produces an `ExtraCommand`, and `@command(cls=MyExtraCommand)` is accepted *only if* `MyExtraCommand` is a subclass of `ExtraCommand`. Anything else raises a `TypeError` with a full MRO listing of the offending class, so the caller sees *why* their override was rejected:
3449

3550
```{python:run}

docs/envvar.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ with click.Context(show) as ctx:
7777

7878
Returns the deduplicated, ordered tuple of environment variables Click would consider for an option or argument: the user-declared `envvar=` value (single string or iterable) followed by the auto-generated one. Click reads them in this order and stops at the first one set, which means **user-declared envvars take precedence over the auto-generated one**`param_envvar_ids` preserves that ordering.
7979

80+
```mermaid
81+
:align: center
82+
83+
flowchart LR
84+
decl["param.envvar<br/>user-declared:<br/>string or nested iterable"] --> merge
85+
auto["param_auto_envvar_id()<br/>PREFIX_NAME,<br/>if auto-envvar enabled"] --> merge
86+
merge["merge_envvar_ids()<br/>flatten, drop empty,<br/>dedupe, upper-case on Windows"] --> tup["ordered tuple<br/>user-declared first,<br/>auto-generated last"]
87+
tup --> reader["Click reads in order,<br/>stops at first set<br/>so user-declared wins"]
88+
```
89+
8090
```{python:run}
8191
import click
8292

docs/version.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,25 @@ The `{version}` variable is resolved in this order:
9797
4. `None` if none of the above succeeds (e.g. unpackaged scripts without `__version__`).
9898
```
9999

100+
Both `{exec_name}` and `{version}` are derived through a short fallback chain (`{version}` additionally appends the Git short hash for `.dev` builds):
101+
102+
```mermaid
103+
:align: center
104+
105+
flowchart TD
106+
subgraph EXEC["exec_name"]
107+
direction TB
108+
x1["module name"] -->|"is __main__"| x2["package name"]
109+
x2 -->|"not packaged"| x3["script filename"]
110+
end
111+
subgraph VER["version"]
112+
direction TB
113+
m["module __version__"] -->|unset| p["package metadata"]
114+
p -->|unset| nil["None"]
115+
end
116+
VER -.->|"if .dev without +local, and git available"| gh["append the Git short hash<br/>e.g. 1.2.3.dev0+abc1234"]
117+
```
118+
100119
```{error}
101120
Some Click's built-in variables are not recognized:
102121
- `%(package)s` should be replaced by `{package_name}`

0 commit comments

Comments
 (0)