Documentation Index Fetch the complete documentation index at: https://mintlify.com/Winipedia/pyrig/llms.txt
Use this file to discover all available pages before exploring further.
Tools in pyrig are type-safe wrappers around command-line utilities used in Python development workflows. Each tool provides a clean, composable API for constructing commands without sacrificing the flexibility of raw CLI usage.
All tools follow a consistent pattern:
Each tool is a Tool subclass - Provides a consistent interface
Tool methods return Args objects - Immutable command argument tuples
Args objects execute directly - Call .run() to execute
All command construction is centralized - Easy to test and maintain
Benefits
Type Safety Arguments are validated at construction time, catching errors before execution
Composability Args objects can be combined and extended for complex workflows
Testability Command construction can be tested without executing subprocess calls
Discoverability IDE autocomplete shows all available commands and their parameters
Quick Example
from pyrig.rig.tools.package_manager import PackageManager
# Construct command arguments
args = PackageManager.I.install_dependencies_args()
# Inspect the command
print (args) # Output: uv sync
# Execute the command
result = args.run()
print (result.returncode) # 0
Pyrig includes wrappers for common development tools:
Package Manager UV package manager wrapper for dependency management
Version Controller Git wrapper for version control operations
Linter Ruff linter and formatter wrapper
Type Checker Ty type checker wrapper
Project Tester Pytest test runner wrapper
Location
pyrig.rig.tools.base.base.Tool (rig/tools/base/base.py:49)
Core Methods
All Tool subclasses must implement:
from abc import abstractmethod
from pyrig.rig.tools.base.base import Tool
from pyrig.src.processes import Args
class MyTool ( Tool ):
@abstractmethod
def name ( self ) -> str :
"""Return the command name (e.g., 'git', 'uv', 'pytest')"""
return "mytool"
@abstractmethod
def group ( self ) -> str :
"""Return the tool group for badge organization"""
return ToolGroup. TOOLING
@abstractmethod
def badge_urls ( self ) -> tuple[ str , str ]:
"""Return (badge_image_url, project_url) for README badges"""
return (
"https://img.shields.io/badge/MyTool-blue" ,
"https://example.com/mytool"
)
The args() Method
The base args() method constructs command arguments:
def args ( self , * args : str ) -> Args:
"""Construct command arguments with tool name prepended.
Args:
*args: Command arguments.
Returns:
Args object with tool name and arguments.
"""
return Args(( self .name(), * args))
Example Usage
class MyTool ( Tool ):
def name ( self ) -> str :
return "mytool"
def build_args ( self , * args : str ) -> Args:
"""Construct mytool build arguments."""
return self .args( "build" , * args)
def test_args ( self , verbose : bool = False ) -> Args:
"""Construct mytool test arguments."""
base = self .args( "test" )
if verbose:
return Args(( * base, "--verbose" ))
return base
# Usage
MyTool.I.build_args( "--release" ).run()
MyTool.I.test_args( verbose = True ).run()
The Args Class
Location
pyrig.src.processes.Args (src/processes.py:121)
Overview
Args is an immutable tuple subclass that represents a complete command ready for execution:
class Args (tuple[ str , ... ]):
"""Immutable command-line arguments container with execution capabilities."""
def run ( self , * args : str , ** kwargs : Any) -> subprocess.CompletedProcess[Any]:
"""Execute command via subprocess."""
return run_subprocess(( * self , * args), ** kwargs)
def run_cached ( self , * args : str , ** kwargs : Any) -> subprocess.CompletedProcess[Any]:
"""Execute command via cached subprocess."""
return run_subprocess_cached(( * self , * args), ** kwargs)
Execution Methods
Execute the command immediately: args = PackageManager.I.add_dependencies_args( "requests" )
result = args.run()
# With additional options
result = args.run( check = False , cwd = "/path/to/project" )
Execute with result caching for repeated calls: args = VersionController.I.config_get_user_name_args()
# First call executes subprocess
result1 = args.run_cached()
# Subsequent calls return cached result
result2 = args.run_cached() # No subprocess call
Common Parameters
Both run() and run_cached() accept:
check: bool = True - Raise exception on non-zero exit code
capture_output: bool = True - Capture stdout/stderr
cwd: str | Path | None = None - Working directory
timeout: int | None = None - Command timeout in seconds
text: bool = True - Decode output as text
You can customize tools by subclassing them:
from pyrig.rig.tools.package_manager import PackageManager
from pyrig.src.processes import Args
class CustomPackageManager ( PackageManager ):
"""Package manager with custom defaults."""
def install_dependencies_args ( self , * args : str ) -> Args:
"""Install dependencies with frozen versions."""
return super ().install_dependencies_args( "--frozen" , * args)
def dev_dependencies ( self ) -> tuple[ str , ... ]:
"""Add custom dev dependencies."""
return ( * super ().dev_dependencies(), "ipython" , "ipdb" )
Tools are organized into groups for badge organization:
from pyrig.rig.tools.base.base import ToolGroup
ToolGroup. CI_CD # ci/cd
ToolGroup. CODE_QUALITY # code-quality
ToolGroup. DOCUMENTATION # documentation
ToolGroup. PROJECT_INFO # project-info
ToolGroup. SECURITY # security
ToolGroup. TOOLING # tooling
ToolGroup. TESTING # testing
Best Practices
Use the singleton instance .I
All tools provide a singleton instance via .I: # Good
PackageManager.I.install_dependencies_args()
# Also works, but unnecessary
PackageManager().install_dependencies_args()
Compose args for complex commands
Build complex commands incrementally: base = Linter.I.check_args()
with_fix = Args(( * base, "--fix" ))
with_specific_files = Args(( * with_fix, "src/" , "tests/" ))
with_specific_files.run()
Test command construction without running subprocesses: def test_install_command ():
args = PackageManager.I.install_dependencies_args( "--no-dev" )
assert str (args) == "uv sync --no-dev"
assert args == ( "uv" , "sync" , "--no-dev" )
Use check=False for commands that may fail: result = VersionController.I.diff_quiet_args().run( check = False )
if result.returncode != 0 :
print ( "Uncommitted changes detected" )
Next Steps
Package Manager Learn about UV package management
Version Controller Explore Git operations
Code Quality Configure linting and formatting