gencodo-py 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. gencodo_py-0.1.0/.github/workflows/publish.yml +44 -0
  2. gencodo_py-0.1.0/.gitignore +3 -0
  3. gencodo_py-0.1.0/CHANGELOG.md +15 -0
  4. gencodo_py-0.1.0/PKG-INFO +144 -0
  5. gencodo_py-0.1.0/README.md +117 -0
  6. gencodo_py-0.1.0/examples/demo_cli/app.py +105 -0
  7. gencodo_py-0.1.0/examples/demo_cli/docs_output/md/farewell.md +38 -0
  8. gencodo_py-0.1.0/examples/demo_cli/docs_output/md/greet.md +57 -0
  9. gencodo_py-0.1.0/examples/demo_cli/docs_output/md/hello.md +28 -0
  10. gencodo_py-0.1.0/examples/demo_cli/docs_output/md/index.md +23 -0
  11. gencodo_py-0.1.0/examples/demo_cli/docs_output/rst/farewell.rst +47 -0
  12. gencodo_py-0.1.0/examples/demo_cli/docs_output/rst/greet.rst +74 -0
  13. gencodo_py-0.1.0/examples/demo_cli/docs_output/rst/hello.rst +34 -0
  14. gencodo_py-0.1.0/examples/demo_cli/docs_output/rst/index.rst +39 -0
  15. gencodo_py-0.1.0/examples/demo_cli/generate_docs.py +56 -0
  16. gencodo_py-0.1.0/pyproject.toml +47 -0
  17. gencodo_py-0.1.0/src/gencodo/__init__.py +23 -0
  18. gencodo_py-0.1.0/src/gencodo/_core.py +287 -0
  19. gencodo_py-0.1.0/src/gencodo/_jinja_env.py +31 -0
  20. gencodo_py-0.1.0/src/gencodo/_types.py +92 -0
  21. gencodo_py-0.1.0/src/gencodo/py.typed +0 -0
  22. gencodo_py-0.1.0/src/gencodo/templates/md/command.md.j2 +43 -0
  23. gencodo_py-0.1.0/src/gencodo/templates/md/index.md.j2 +25 -0
  24. gencodo_py-0.1.0/src/gencodo/templates/rst/command.rst.j2 +54 -0
  25. gencodo_py-0.1.0/src/gencodo/templates/rst/index.rst.j2 +39 -0
  26. gencodo_py-0.1.0/tests/__init__.py +0 -0
  27. gencodo_py-0.1.0/tests/conftest.py +176 -0
  28. gencodo_py-0.1.0/tests/test_build_context.py +147 -0
  29. gencodo_py-0.1.0/tests/test_bundled_templates.py +97 -0
  30. gencodo_py-0.1.0/tests/test_extract_flags.py +57 -0
  31. gencodo_py-0.1.0/tests/test_gen_docs.py +56 -0
  32. gencodo_py-0.1.0/tests/test_gen_docs_tree.py +112 -0
  33. gencodo_py-0.1.0/tests/test_infer_related.py +64 -0
  34. gencodo_py-0.1.0/tests/test_jinja_env.py +66 -0
  35. gencodo_py-0.1.0/tests/test_types.py +118 -0
@@ -0,0 +1,44 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ id-token: write
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.12"
19
+
20
+ - name: Install build dependencies
21
+ run: pip install build
22
+
23
+ - name: Build package
24
+ run: python -m build
25
+
26
+ - name: Upload build artifacts
27
+ uses: actions/upload-artifact@v4
28
+ with:
29
+ name: dist
30
+ path: dist/
31
+
32
+ publish:
33
+ needs: build
34
+ runs-on: ubuntu-latest
35
+ environment: pypi
36
+ steps:
37
+ - name: Download build artifacts
38
+ uses: actions/download-artifact@v4
39
+ with:
40
+ name: dist
41
+ path: dist/
42
+
43
+ - name: Publish to PyPI
44
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,3 @@
1
+ .claude/
2
+ .pytest_cache/
3
+ .venv/
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ Initial release.
6
+
7
+ - Protocol-based `Command` interface (no inheritance required)
8
+ - `gen_docs()` for single-command documentation
9
+ - `gen_docs_tree()` for full documentation trees
10
+ - `get_bundled_templates()` with reST and Markdown formats
11
+ - Jinja2-based template rendering with `indent` and `repeat` filters
12
+ - `ExampleInfo`, `FlagInfo`, `TemplateInfo` dataclasses
13
+ - `CommandGroup` named tuple for organizing commands
14
+ - Automatic related-command inference from sibling commands
15
+ - PEP 561 type stubs (`py.typed`)
@@ -0,0 +1,144 @@
1
+ Metadata-Version: 2.4
2
+ Name: gencodo-py
3
+ Version: 0.1.0
4
+ Summary: Generate CLI reference documentation from argparse-based applications using Jinja2 templates
5
+ Project-URL: Homepage, https://github.com/canonical/gencodo-py
6
+ Project-URL: Issues, https://github.com/canonical/gencodo-py/issues
7
+ Author: gencodo contributors
8
+ License-Expression: LGPL-3.0-only
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Documentation
18
+ Classifier: Topic :: Software Development :: Documentation
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: jinja2>=3.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest-cov; extra == 'dev'
25
+ Requires-Dist: pytest>=7.0; extra == 'dev'
26
+ Description-Content-Type: text/markdown
27
+
28
+ # gencodo-py
29
+
30
+ Generate CLI reference documentation from argparse-based applications using Jinja2 templates.
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ pip install gencodo-py
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ Define your CLI commands as plain Python classes (no base class required):
41
+
42
+ ```python
43
+ import argparse
44
+
45
+ class GreetCommand:
46
+ name = "greet"
47
+ help_msg = "Greet a specific person"
48
+ overview = "Personalize your greeting by specifying a name."
49
+ hidden = False
50
+ examples = [("Greet Alice", "myapp greet Alice")]
51
+ related_commands = None
52
+
53
+ def fill_parser(self, parser: argparse.ArgumentParser) -> None:
54
+ parser.add_argument("name", help="Name to greet")
55
+ parser.add_argument("--formal", action="store_true", default=False,
56
+ help="Use formal style")
57
+ ```
58
+
59
+ Generate documentation:
60
+
61
+ ```python
62
+ from gencodo import CommandGroup, gen_docs_tree, get_bundled_templates
63
+
64
+ groups = [CommandGroup(name="Greetings", commands=[GreetCommand])]
65
+ templates = get_bundled_templates("md") # or "rst"
66
+
67
+ gen_docs_tree(
68
+ appname="myapp",
69
+ command_groups=groups,
70
+ output_dir="docs/cli-ref",
71
+ templates=templates,
72
+ )
73
+ ```
74
+
75
+ ## API Reference
76
+
77
+ ### Types
78
+
79
+ - **`Command`** -- Protocol that any CLI command class must satisfy (structural subtyping).
80
+ - **`CommandGroup`** -- NamedTuple grouping commands under a name.
81
+ - **`ExampleInfo`** -- Dataclass for a usage example (info, usage).
82
+ - **`FlagInfo`** -- Dataclass for a CLI flag (name, usage, default_value).
83
+ - **`TemplateInfo`** -- Dataclass for Jinja2 template configuration.
84
+
85
+ ### Functions
86
+
87
+ - **`gen_docs(command_class, writer, template, appname, command_groups)`** -- Render docs for a single command to a TextIO writer.
88
+ - **`gen_docs_tree(appname, command_groups, output_dir, templates, ...)`** -- Generate a full documentation tree (one file per command + index).
89
+ - **`get_bundled_templates(format="rst", index_file_name=None)`** -- Load bundled reST or Markdown templates.
90
+
91
+ ### Command Protocol
92
+
93
+ Your command classes need these attributes/methods:
94
+
95
+ | Attribute | Type | Description |
96
+ |-----------|------|-------------|
97
+ | `name` | `str` | Command name |
98
+ | `help_msg` | `str` | Short help string |
99
+ | `overview` | `str` | Longer description |
100
+ | `hidden` | `bool` | Exclude from docs if True |
101
+ | `examples` | `list[tuple[str, str]]` | (description, command) pairs |
102
+ | `related_commands` | `list[str] \| None` | Explicit related commands, or None to auto-infer |
103
+ | `fill_parser(parser)` | method | Add arguments to an ArgumentParser |
104
+
105
+ ## Template Customization
106
+
107
+ ### Bundled Templates
108
+
109
+ Use `get_bundled_templates("rst")` or `get_bundled_templates("md")` for the built-in templates.
110
+
111
+ ### Custom Templates
112
+
113
+ Pass your own Jinja2 template strings via `TemplateInfo`:
114
+
115
+ ```python
116
+ from gencodo import TemplateInfo
117
+
118
+ templates = TemplateInfo(
119
+ index_file_name="index.md",
120
+ index_template="# Commands\n{% for f in files %}...\n{% endfor %}",
121
+ command_template="# {{ command_name }}\n{{ short }}\n...",
122
+ )
123
+ ```
124
+
125
+ Available template variables for command templates:
126
+
127
+ | Variable | Type | Description |
128
+ |----------|------|-------------|
129
+ | `ref` | `str` | Anchor reference (underscored name) |
130
+ | `command_name` | `str` | Command name |
131
+ | `short` | `str` | Short help message |
132
+ | `long` | `str` | Overview text |
133
+ | `synopsis` | `str` | Usage synopsis |
134
+ | `examples` | `list[ExampleInfo]` | Usage examples |
135
+ | `flags` | `list[FlagInfo]` | Optional flags |
136
+ | `related_commands` | `list[str]` | Related command names |
137
+ | `heading_len` | `int` | Length of command name |
138
+ | `appname` | `str` | Application name |
139
+
140
+ Custom Jinja2 filters available: `indent(width)`, `repeat(n)`.
141
+
142
+ ## License
143
+
144
+ LGPL-3.0-only
@@ -0,0 +1,117 @@
1
+ # gencodo-py
2
+
3
+ Generate CLI reference documentation from argparse-based applications using Jinja2 templates.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install gencodo-py
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ Define your CLI commands as plain Python classes (no base class required):
14
+
15
+ ```python
16
+ import argparse
17
+
18
+ class GreetCommand:
19
+ name = "greet"
20
+ help_msg = "Greet a specific person"
21
+ overview = "Personalize your greeting by specifying a name."
22
+ hidden = False
23
+ examples = [("Greet Alice", "myapp greet Alice")]
24
+ related_commands = None
25
+
26
+ def fill_parser(self, parser: argparse.ArgumentParser) -> None:
27
+ parser.add_argument("name", help="Name to greet")
28
+ parser.add_argument("--formal", action="store_true", default=False,
29
+ help="Use formal style")
30
+ ```
31
+
32
+ Generate documentation:
33
+
34
+ ```python
35
+ from gencodo import CommandGroup, gen_docs_tree, get_bundled_templates
36
+
37
+ groups = [CommandGroup(name="Greetings", commands=[GreetCommand])]
38
+ templates = get_bundled_templates("md") # or "rst"
39
+
40
+ gen_docs_tree(
41
+ appname="myapp",
42
+ command_groups=groups,
43
+ output_dir="docs/cli-ref",
44
+ templates=templates,
45
+ )
46
+ ```
47
+
48
+ ## API Reference
49
+
50
+ ### Types
51
+
52
+ - **`Command`** -- Protocol that any CLI command class must satisfy (structural subtyping).
53
+ - **`CommandGroup`** -- NamedTuple grouping commands under a name.
54
+ - **`ExampleInfo`** -- Dataclass for a usage example (info, usage).
55
+ - **`FlagInfo`** -- Dataclass for a CLI flag (name, usage, default_value).
56
+ - **`TemplateInfo`** -- Dataclass for Jinja2 template configuration.
57
+
58
+ ### Functions
59
+
60
+ - **`gen_docs(command_class, writer, template, appname, command_groups)`** -- Render docs for a single command to a TextIO writer.
61
+ - **`gen_docs_tree(appname, command_groups, output_dir, templates, ...)`** -- Generate a full documentation tree (one file per command + index).
62
+ - **`get_bundled_templates(format="rst", index_file_name=None)`** -- Load bundled reST or Markdown templates.
63
+
64
+ ### Command Protocol
65
+
66
+ Your command classes need these attributes/methods:
67
+
68
+ | Attribute | Type | Description |
69
+ |-----------|------|-------------|
70
+ | `name` | `str` | Command name |
71
+ | `help_msg` | `str` | Short help string |
72
+ | `overview` | `str` | Longer description |
73
+ | `hidden` | `bool` | Exclude from docs if True |
74
+ | `examples` | `list[tuple[str, str]]` | (description, command) pairs |
75
+ | `related_commands` | `list[str] \| None` | Explicit related commands, or None to auto-infer |
76
+ | `fill_parser(parser)` | method | Add arguments to an ArgumentParser |
77
+
78
+ ## Template Customization
79
+
80
+ ### Bundled Templates
81
+
82
+ Use `get_bundled_templates("rst")` or `get_bundled_templates("md")` for the built-in templates.
83
+
84
+ ### Custom Templates
85
+
86
+ Pass your own Jinja2 template strings via `TemplateInfo`:
87
+
88
+ ```python
89
+ from gencodo import TemplateInfo
90
+
91
+ templates = TemplateInfo(
92
+ index_file_name="index.md",
93
+ index_template="# Commands\n{% for f in files %}...\n{% endfor %}",
94
+ command_template="# {{ command_name }}\n{{ short }}\n...",
95
+ )
96
+ ```
97
+
98
+ Available template variables for command templates:
99
+
100
+ | Variable | Type | Description |
101
+ |----------|------|-------------|
102
+ | `ref` | `str` | Anchor reference (underscored name) |
103
+ | `command_name` | `str` | Command name |
104
+ | `short` | `str` | Short help message |
105
+ | `long` | `str` | Overview text |
106
+ | `synopsis` | `str` | Usage synopsis |
107
+ | `examples` | `list[ExampleInfo]` | Usage examples |
108
+ | `flags` | `list[FlagInfo]` | Optional flags |
109
+ | `related_commands` | `list[str]` | Related command names |
110
+ | `heading_len` | `int` | Length of command name |
111
+ | `appname` | `str` | Application name |
112
+
113
+ Custom Jinja2 filters available: `indent(width)`, `repeat(n)`.
114
+
115
+ ## License
116
+
117
+ LGPL-3.0-only
@@ -0,0 +1,105 @@
1
+ """Example CLI app using plain argparse classes (no framework dependency).
2
+
3
+ Each command class satisfies the gencodo.Command protocol via duck typing.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import argparse
9
+
10
+
11
+ class HelloCommand:
12
+ """Say hello to the world."""
13
+
14
+ name = "hello"
15
+ help_msg = "Say hello to the world"
16
+ overview = (
17
+ "Prints a friendly hello message to standard output.\n\n"
18
+ "This is the simplest possible command with no arguments."
19
+ )
20
+ hidden = False
21
+ examples = [
22
+ ("Say hello", "democli hello"),
23
+ ]
24
+ related_commands = None
25
+
26
+ def __init__(self, config=None):
27
+ self.config = config
28
+
29
+ def fill_parser(self, parser: argparse.ArgumentParser) -> None:
30
+ pass
31
+
32
+
33
+ class GreetCommand:
34
+ """Greet a specific person."""
35
+
36
+ name = "greet"
37
+ help_msg = "Greet a specific person"
38
+ overview = (
39
+ "The greet command allows you to personalize your greeting by specifying\n"
40
+ "a name. You can also customize the greeting style and add an optional\n"
41
+ "message suffix.\n\n"
42
+ "This command demonstrates how to use positional and optional arguments."
43
+ )
44
+ hidden = False
45
+ examples = [
46
+ ("Greet Alice", "democli greet Alice"),
47
+ ("Greet Bob formally", "democli greet Bob --formal"),
48
+ ("Greet Charlie with enthusiasm", "democli greet Charlie --enthusiasm 5"),
49
+ ("Greet with a suffix", "democli greet Alice --suffix ', have a great day!'"),
50
+ ]
51
+ related_commands = None
52
+
53
+ def __init__(self, config=None):
54
+ self.config = config
55
+
56
+ def fill_parser(self, parser: argparse.ArgumentParser) -> None:
57
+ parser.add_argument("name", help="Name of the person to greet")
58
+ parser.add_argument(
59
+ "--formal",
60
+ action="store_true",
61
+ default=False,
62
+ help="Use formal greeting style",
63
+ )
64
+ parser.add_argument(
65
+ "--enthusiasm",
66
+ type=int,
67
+ default=1,
68
+ help="Enthusiasm level (1-5)",
69
+ )
70
+ parser.add_argument(
71
+ "--suffix",
72
+ default=None,
73
+ help="Optional message suffix",
74
+ )
75
+
76
+
77
+ class FarewellCommand:
78
+ """Say goodbye."""
79
+
80
+ name = "farewell"
81
+ help_msg = "Say goodbye"
82
+ overview = "Prints a farewell message. Supports formal and informal styles."
83
+ hidden = False
84
+ examples = [
85
+ ("Say farewell", "democli farewell"),
86
+ ("Formal farewell", "democli farewell --formal"),
87
+ ]
88
+ related_commands = None
89
+
90
+ def __init__(self, config=None):
91
+ self.config = config
92
+
93
+ def fill_parser(self, parser: argparse.ArgumentParser) -> None:
94
+ parser.add_argument(
95
+ "--formal",
96
+ action="store_true",
97
+ default=False,
98
+ help="Use formal farewell style",
99
+ )
100
+
101
+
102
+ # Command groups for use with gencodo
103
+ COMMAND_GROUPS = [
104
+ ("Greetings", [HelloCommand, GreetCommand, FarewellCommand]),
105
+ ]
@@ -0,0 +1,38 @@
1
+ # farewell
2
+
3
+ Say goodbye
4
+
5
+ **Usage:**
6
+
7
+ ```
8
+ democli farewell [--formal]
9
+ ```
10
+
11
+ ## Overview
12
+
13
+ Prints a farewell message. Supports formal and informal styles.
14
+
15
+ ## Options
16
+
17
+ | Flag | Description | Default |
18
+ |------|-------------|---------|
19
+ | `--formal` | Use formal farewell style | `False` |
20
+
21
+ ## Examples
22
+
23
+ **Say farewell**
24
+
25
+ ```
26
+ democli farewell
27
+ ```
28
+
29
+ **Formal farewell**
30
+
31
+ ```
32
+ democli farewell --formal
33
+ ```
34
+
35
+ ## See also
36
+
37
+ - [greet](greet.md)
38
+ - [hello](hello.md)
@@ -0,0 +1,57 @@
1
+ # greet
2
+
3
+ Greet a specific person
4
+
5
+ **Usage:**
6
+
7
+ ```
8
+ democli greet [--formal] [--enthusiasm ENTHUSIASM] [--suffix SUFFIX]
9
+ name
10
+ ```
11
+
12
+ ## Overview
13
+
14
+ The greet command allows you to personalize your greeting by specifying
15
+ a name. You can also customize the greeting style and add an optional
16
+ message suffix.
17
+
18
+ This command demonstrates how to use positional and optional arguments.
19
+
20
+ ## Options
21
+
22
+ | Flag | Description | Default |
23
+ |------|-------------|---------|
24
+ | `--formal` | Use formal greeting style | `False` |
25
+ | `--enthusiasm` | Enthusiasm level (1-5) | `1` |
26
+ | `--suffix` | Optional message suffix | |
27
+
28
+ ## Examples
29
+
30
+ **Greet Alice**
31
+
32
+ ```
33
+ democli greet Alice
34
+ ```
35
+
36
+ **Greet Bob formally**
37
+
38
+ ```
39
+ democli greet Bob --formal
40
+ ```
41
+
42
+ **Greet Charlie with enthusiasm**
43
+
44
+ ```
45
+ democli greet Charlie --enthusiasm 5
46
+ ```
47
+
48
+ **Greet with a suffix**
49
+
50
+ ```
51
+ democli greet Alice --suffix ', have a great day!'
52
+ ```
53
+
54
+ ## See also
55
+
56
+ - [farewell](farewell.md)
57
+ - [hello](hello.md)
@@ -0,0 +1,28 @@
1
+ # hello
2
+
3
+ Say hello to the world
4
+
5
+ **Usage:**
6
+
7
+ ```
8
+ democli hello
9
+ ```
10
+
11
+ ## Overview
12
+
13
+ Prints a friendly hello message to standard output.
14
+
15
+ This is the simplest possible command with no arguments.
16
+
17
+ ## Examples
18
+
19
+ **Say hello**
20
+
21
+ ```
22
+ democli hello
23
+ ```
24
+
25
+ ## See also
26
+
27
+ - [farewell](farewell.md)
28
+ - [greet](greet.md)
@@ -0,0 +1,23 @@
1
+ # CLI Reference
2
+
3
+ Command-line interface reference for **democli**.
4
+
5
+ This reference documentation is automatically generated from the command
6
+ definitions and provides detailed information about each available command.
7
+
8
+ ## Available Commands
9
+
10
+ ### Greetings
11
+
12
+ - [hello](hello.md) -- Say hello to the world
13
+ - [greet](greet.md) -- Greet a specific person
14
+ - [farewell](farewell.md) -- Say goodbye
15
+
16
+
17
+ ## Quick Reference Table
18
+
19
+ | Command | Description |
20
+ |---------|-------------|
21
+ | [hello](hello.md) | Say hello to the world |
22
+ | [greet](greet.md) | Greet a specific person |
23
+ | [farewell](farewell.md) | Say goodbye |
@@ -0,0 +1,47 @@
1
+ .. _ref_farewell:
2
+
3
+ farewell
4
+ ========
5
+
6
+ Say goodbye
7
+
8
+ **Usage:**
9
+
10
+ .. code-block:: bash
11
+
12
+ democli farewell [--formal]
13
+
14
+ Overview
15
+ --------
16
+
17
+ Prints a farewell message. Supports formal and informal styles.
18
+
19
+ Options
20
+ -------
21
+
22
+ .. option:: --formal
23
+
24
+ Use formal farewell style
25
+
26
+ Default: ``False``
27
+
28
+ Examples
29
+ --------
30
+
31
+ **Say farewell**
32
+
33
+ .. code-block:: bash
34
+
35
+ democli farewell
36
+
37
+ **Formal farewell**
38
+
39
+ .. code-block:: bash
40
+
41
+ democli farewell --formal
42
+
43
+ See also
44
+ --------
45
+
46
+ - :ref:`greet <ref_greet>`
47
+ - :ref:`hello <ref_hello>`
@@ -0,0 +1,74 @@
1
+ .. _ref_greet:
2
+
3
+ greet
4
+ =====
5
+
6
+ Greet a specific person
7
+
8
+ **Usage:**
9
+
10
+ .. code-block:: bash
11
+
12
+ democli greet [--formal] [--enthusiasm ENTHUSIASM] [--suffix SUFFIX]
13
+ name
14
+
15
+ Overview
16
+ --------
17
+
18
+ The greet command allows you to personalize your greeting by specifying
19
+ a name. You can also customize the greeting style and add an optional
20
+ message suffix.
21
+
22
+ This command demonstrates how to use positional and optional arguments.
23
+
24
+ Options
25
+ -------
26
+
27
+ .. option:: --formal
28
+
29
+ Use formal greeting style
30
+
31
+ Default: ``False``
32
+
33
+ .. option:: --enthusiasm
34
+
35
+ Enthusiasm level (1-5)
36
+
37
+ Default: ``1``
38
+
39
+ .. option:: --suffix
40
+
41
+ Optional message suffix
42
+
43
+ Examples
44
+ --------
45
+
46
+ **Greet Alice**
47
+
48
+ .. code-block:: bash
49
+
50
+ democli greet Alice
51
+
52
+ **Greet Bob formally**
53
+
54
+ .. code-block:: bash
55
+
56
+ democli greet Bob --formal
57
+
58
+ **Greet Charlie with enthusiasm**
59
+
60
+ .. code-block:: bash
61
+
62
+ democli greet Charlie --enthusiasm 5
63
+
64
+ **Greet with a suffix**
65
+
66
+ .. code-block:: bash
67
+
68
+ democli greet Alice --suffix ', have a great day!'
69
+
70
+ See also
71
+ --------
72
+
73
+ - :ref:`farewell <ref_farewell>`
74
+ - :ref:`hello <ref_hello>`