-
Notifications
You must be signed in to change notification settings - Fork 7
Move CRUD commands under object subgroup #931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
8756687
Move CRUD commands under object subgroup
gmazoyer 409861c
Re-generate documentation
gmazoyer 0043ac0
Adding some knowledge for AI agents
gmazoyer 620fed9
Fix examples
gmazoyer 8a79baa
Fix integration tests
gmazoyer d50bdc5
Rename files
gmazoyer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # CLI Architecture | ||
|
|
||
| The `infrahubctl` CLI is built with [Typer](https://typer.tiangolo.com/) via a custom `AsyncTyper` subclass that supports async command functions. | ||
|
|
||
| ## Entry point | ||
|
|
||
| The main Typer app lives in `infrahub_sdk/ctl/cli_commands.py`. It is re-exported through `infrahub_sdk/ctl/cli.py` which adds the `infrahubctl` entry point name. | ||
|
|
||
| ## Command hierarchy | ||
|
|
||
| Commands are organized in two tiers: | ||
|
|
||
| - **Root commands** are registered directly on the main app with `app.command()`. These are standalone operations that don't belong to a logical group (e.g. `dump`, `load`, `check`, `render`, `run`, `transform`, `protocols`, `version`, `info`). | ||
| - **Subcommand groups** are separate `AsyncTyper()` instances registered with `app.add_typer(sub_app, name="group")`. Each group lives in its own module under `infrahub_sdk/ctl/`. Current groups: `branch`, `schema`, `validate`, `repository`, `menu`, `object`, `graphql`, `task`. | ||
|
|
||
| ## Adding a new command | ||
|
|
||
| For a **root command**, define the function in the appropriate module and register it in `cli_commands.py`: | ||
|
|
||
| ```python | ||
| app.command(name="mycommand")(my_function) | ||
| ``` | ||
|
|
||
| For a **subcommand**, add it to the relevant group's module. For example, object subcommands go in `infrahub_sdk/ctl/object.py` or in dedicated files under `infrahub_sdk/ctl/commands/` and are registered on the object app. | ||
|
|
||
| ## The `commands/` directory | ||
|
|
||
| `infrahub_sdk/ctl/commands/` contains modular command implementations that are imported and registered on a group app. This keeps individual command logic separated from the group wiring. Shared utilities live in `commands/utils.py`. | ||
|
|
||
| ## Decorators | ||
|
|
||
| - `@catch_exception(console=console)` wraps commands for consistent error handling via Rich. | ||
| - Async commands work natively thanks to `AsyncTyper`. | ||
|
|
||
| ## Design rules | ||
|
|
||
| **Always check if a new command belongs in an existing group before adding it at the root.** A command that operates on a specific resource type (objects, branches, schemas, etc.) should go under the matching subgroup, not at the top level. Root-level commands are reserved for cross-cutting or standalone operations (e.g. `run`, `version`, `info`). | ||
|
|
||
| When in doubt, look at what the command acts on and find the group that matches. For example, anything that creates, reads, updates, or deletes Infrahub objects belongs under `object`, not at the root. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # Documentation Generation | ||
|
|
||
| CLI and SDK documentation is auto-generated from code. Always regenerate after changing commands, config, or public docstrings. | ||
|
|
||
| ## How to run | ||
|
|
||
| ```bash | ||
| uv run invoke docs-generate # Generate all docs (CLI + SDK) | ||
| uv run invoke docs-validate # Verify generated docs match committed versions | ||
| ``` | ||
|
|
||
| ## CLI documentation | ||
|
|
||
| Defined in `tasks.py` (`_generate_infrahubctl_documentation`). The process: | ||
|
|
||
| 1. Deletes all existing `infrahubctl-*.mdx` files in `docs/docs/infrahubctl/`. | ||
| 2. Iterates `app.registered_commands` and creates a `TyperSingleCommand` for each. | ||
| 3. Iterates `app.registered_groups` and creates a `TyperGroupCommand` for each. | ||
| 4. Each command object generates an mdx file via `typer ... utils docs`. | ||
|
|
||
| ### How it maps to files | ||
|
|
||
| - A **root command** named `foo` produces `infrahubctl-foo.mdx` using: | ||
| `uv run typer --func foo infrahub_sdk.ctl.cli_commands utils docs --name "infrahubctl foo"` | ||
| - A **subcommand group** named `bar` produces `infrahubctl-bar.mdx` using: | ||
| `uv run typer infrahub_sdk.ctl.bar utils docs --name "infrahubctl bar"` | ||
|
|
||
| The group variant documents all subcommands within that group automatically. | ||
|
|
||
| ### Key implication | ||
|
|
||
| Moving a command from root to a group (or vice versa) changes which mdx files get generated. The old files are cleaned up automatically by the glob delete, but the new ones only appear after running `docs-generate`. Always regenerate and commit the result. | ||
|
|
||
| ## SDK documentation | ||
|
|
||
| Other doc generators cover SDK config, compatibility matrix, templates, and API reference. These are independent of CLI structure and are also triggered by `docs-generate`. | ||
|
|
||
| ## Validation in CI | ||
|
|
||
| `docs-validate` diffs the generated output against the committed files. If they don't match, CI fails. This ensures docs stay in sync with code. |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.