Core Components
Main Entry Point
Main CLI entry point that orchestrates command discovery and registration.Steps:
- Discovers and registers project-specific commands
- Discovers and registers shared commands
- Invokes Typer app to parse arguments and execute command
Typer Application
Main Typer application instance.Root Typer app that all commands are registered to. Configured with
no_args_is_help=True to display help when invoked without a command.Usage:Command Discovery
Project Commands
Discover and register project-specific CLI commands.Discovers:
- Main entry point:
main()from<package>.main - Subcommands: All functions from
<package>.rig.cli.subcommands
- Extracts package name from
sys.argv[0] - Replaces root module name in pyrig’s paths with current package
- Imports modules with fallback handling
- Extracts all functions from subcommands module
- Registers each function as a Typer command
Shared Commands
Discover and register shared CLI commands from the dependency chain.Commands defined in
<package>.rig.cli.shared_subcommands modules are automatically available in all dependent projects.Discovery Process:- Extracts current package name from
sys.argv[0] - Imports current package
- Finds all packages in dependency chain from pyrig to current package
- For each package, looks for
rig.cli.shared_subcommandsmodule - Extracts all public functions from each module
- Registers each function as a Typer command
Logging Configuration
Configure logging based on verbosity flags.Typer callback that runs before any command executes. Configures the Python logging system based on user-provided verbosity flags.Parameters:Logging Levels:
Verbosity level from number of
-v flags.0: INFO level (default)1: DEBUG level with level prefix2: DEBUG level with module names3+: DEBUG level with timestamps and full details
If True, sets WARNING level. Takes precedence over verbose.
- Default: INFO level, clean formatting (just messages)
-q/--quiet: WARNING level (only warnings and errors)-v: DEBUG level with level prefix-vv: DEBUG level with module names-vvv+: DEBUG level with timestamps and full details
Built-in Commands
Pyrig includes several built-in commands inpyrig.rig.cli.subcommands:
mkroot
Create or update project configuration files and directory structure.Discovers all ConfigFile subclasses across the project and its dependencies, then validates each one to create or update configuration files. Generates the complete project structure including pyproject.toml, .gitignore, GitHub workflows, pre-commit hooks, and other configuration files.The command is idempotent: safe to run multiple times, overwrites incorrect files but respects opt-out markers.Example:
mktests
Generate test skeleton files for all source code.Creates test files mirroring the source package structure. For each module, class, function, and method in the source code, generates corresponding test skeletons with
NotImplementedError placeholders.Naming Conventions:- Test modules:
test_<module_name>.py - Test classes:
Test<ClassName> - Test functions:
test_<function_name> - Test methods:
test_<method_name>
mkinits
Create missing init.py files for all namespace packages.Scans the project for namespace packages (directories with Python files but no init.py) and creates minimal init.py files for them. Ensures all packages follow traditional Python package conventions and are properly importable.The command is idempotent and non-destructive: safe to run multiple times, only creates missing files, never modifies existing ones.Example:
init
Initialize a complete pyrig project from scratch.Transforms a basic Python project into a fully-configured, production-ready pyrig project through a comprehensive automated sequence.Steps executed in order:
- Initialize version control (git init)
- Add development dependencies (uv add —group dev)
- Sync virtual environment (uv sync)
- Create project root (mkroot)
- Sync virtual environment again (apply new configs)
- Generate test skeletons (mktests)
- Install pre-commit hooks (pre-commit install)
- Add all files to version control (git add .)
- Run pre-commit hooks (format/lint all files)
- Run test suite (pytest)
- Create initial git commit
build
Build all distributable artifacts for the project.Discovers and invokes all BuilderConfigFile subclasses across the project and its dependencies to create distributable artifacts (e.g., PyInstaller executables, documentation archives, custom build processes).Build Process:
- Discovers all non-abstract BuilderConfigFile subclasses
- Validates each builder (triggers build via
dump()) - Creates artifacts in temporary directories
- Renames with platform-specific suffixes (e.g.,
-Linux,-Windows) - Moves artifacts to
dist/directory
protect-repo
Configure GitHub repository protection rules and security settings.Applies comprehensive security protections to the GitHub repository, including repository-level settings and branch protection rulesets.Repository Settings:
- Description from pyproject.toml
- Default branch set to ‘main’
- Delete branches on merge enabled
- Merge commits disabled (squash and rebase only)
- Required pull request reviews with code owner approval
- Required status checks (health check workflow must pass)
- Linear commit history required
- Signed commits required
- Force pushes and branch deletions disabled
REPO_TOKEN environment variable with repo scope permissions.Example:scratch
Execute the .scratch file for temporary, ad-hoc code.The .scratch file is a Python script located at the project root, intended for temporary, experimental code that doesn’t belong in the main source files.Example:
rmpyc
Remove all pycache directories and their contents from the project.Recursively searches the project directory for any pycache directories and deletes them along with their contents.Example:
Creating Custom Commands
Project-Specific Commands
Add functions to<package>.rig.cli.subcommands:
Shared Commands
Add functions to<package>.rig.cli.shared_subcommands for commands that should be available in all dependent projects:
Best Practices
- Use descriptive docstrings: Docstrings become command help text
- Leverage Typer features: Use
typer.Option()for arguments with validation - Handle errors gracefully: Use
typer.echo()for output, raise exceptions for errors - Keep commands focused: Each command should do one thing well
- Use shared commands sparingly: Only for truly universal functionality
- Test command functions: Command functions are regular Python functions and can be tested directly
Related APIs
- Configuration API - For managing project configuration files
- Tools API - For wrapping external CLI tools