|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +This is the **Cortex CLI** (`cortexapps-cli`), a command-line interface for interacting with the Cortex API (https://cortex.io). The CLI is built with Python 3.11+ using the Typer framework and provides commands for managing catalog entities, scorecards, teams, workflows, integrations, and other Cortex resources. |
| 8 | + |
| 9 | +## Development Commands |
| 10 | + |
| 11 | +### Setup |
| 12 | +```bash |
| 13 | +# Install dependencies |
| 14 | +poetry install |
| 15 | + |
| 16 | +# Set required environment variables for testing |
| 17 | +export CORTEX_API_KEY=<your-api-key> |
| 18 | +export CORTEX_BASE_URL=https://api.getcortexapp.com # optional, defaults to this |
| 19 | +export CORTEX_API_KEY_VIEWER=<viewer-api-key> # for viewer permission tests |
| 20 | +``` |
| 21 | + |
| 22 | +### Testing |
| 23 | +The project uses [just](https://just.systems/) for task automation: |
| 24 | + |
| 25 | +```bash |
| 26 | +# Run all available recipes |
| 27 | +just |
| 28 | + |
| 29 | +# Run all tests (requires prior test-import) |
| 30 | +just test-all |
| 31 | + |
| 32 | +# Run import test (prerequisite for other tests - loads test data) |
| 33 | +just test-import |
| 34 | + |
| 35 | +# Run a single test file |
| 36 | +just test tests/test_catalog.py |
| 37 | +``` |
| 38 | + |
| 39 | +### Manual Testing |
| 40 | +```bash |
| 41 | +# Run the CLI locally |
| 42 | +poetry run cortex <command> |
| 43 | + |
| 44 | +# Examples: |
| 45 | +poetry run cortex catalog list |
| 46 | +poetry run cortex -t my-tenant catalog list |
| 47 | +``` |
| 48 | + |
| 49 | +### Linting & Formatting |
| 50 | +Not currently configured in this project. |
| 51 | + |
| 52 | +## Architecture |
| 53 | + |
| 54 | +### Entry Point & CLI Structure |
| 55 | +- **Main entry point**: `cortexapps_cli/cli.py` - Defines the main Typer app and global options |
| 56 | +- **Command structure**: Each major resource has its own command module in `cortexapps_cli/commands/` |
| 57 | +- **Subcommands**: Some commands have nested subcommands in subdirectories (e.g., `backup_commands/`, `integrations_commands/`, `packages_commands/`, `scorecards_commands/`) |
| 58 | + |
| 59 | +### Global Options |
| 60 | +All commands inherit global options defined in `cli.py:global_callback()`: |
| 61 | +- `-k, --api-key`: API key (or `CORTEX_API_KEY` env var) |
| 62 | +- `-u, --url`: Base URL (or `CORTEX_BASE_URL` env var) |
| 63 | +- `-c, --config`: Config file path (defaults to `~/.cortex/config`) |
| 64 | +- `-t, --tenant`: Tenant alias (defaults to "default") |
| 65 | +- `-l, --log-level`: Logging level (defaults to INFO) |
| 66 | + |
| 67 | +### Configuration |
| 68 | +The CLI supports two authentication methods: |
| 69 | +1. **Config file** (`~/.cortex/config`): INI-style file with sections per tenant |
| 70 | +2. **Environment variables**: `CORTEX_API_KEY` and `CORTEX_BASE_URL` |
| 71 | + |
| 72 | +Environment variables take precedence over config file values. |
| 73 | + |
| 74 | +### Client Architecture |
| 75 | +- **`CortexClient`** (`cortexapps_cli/cortex_client.py`): Core HTTP client that handles all API requests |
| 76 | + - Provides `get()`, `post()`, `put()`, `patch()`, `delete()` methods |
| 77 | + - `fetch()`: Auto-paginated fetch for list endpoints |
| 78 | + - `fetch_or_get()`: Conditionally fetches all pages or single page based on parameters |
| 79 | + - Error handling with formatted error output using Rich |
| 80 | + |
| 81 | +### Command Patterns |
| 82 | +Each command module follows a similar pattern: |
| 83 | +1. Creates a Typer app instance |
| 84 | +2. Defines command-specific option classes (following `CommandOptions` pattern in `command_options.py`) |
| 85 | +3. Implements command functions decorated with `@app.command()` |
| 86 | +4. Commands receive `ctx: typer.Context` to access the shared `CortexClient` via `ctx.obj["client"]` |
| 87 | +5. Uses utility functions from `utils.py` for output formatting |
| 88 | + |
| 89 | +### Common Options Classes |
| 90 | +- **`ListCommandOptions`** (`command_options.py`): Standard options for list commands |
| 91 | + - `--table`, `--csv`: Output format options |
| 92 | + - `--columns, -C`: Select specific columns for table/csv output |
| 93 | + - `--filter, -F`: Filter rows using JSONPath and regex |
| 94 | + - `--sort, -S`: Sort rows by JSONPath fields |
| 95 | + - `--page, -p`, `--page-size, -z`: Pagination controls |
| 96 | + |
| 97 | +- **`CommandOptions`**: Base options (e.g., `--print` for internal testing) |
| 98 | + |
| 99 | +### Output Handling |
| 100 | +- Default: JSON output via Rich's `print_json()` |
| 101 | +- Table/CSV output: Configurable via `--table` or `--csv` flags with column selection |
| 102 | +- Output utilities in `utils.py`: |
| 103 | + - `print_output()`: JSON output |
| 104 | + - `print_output_with_context()`: Formatted output with table/csv support |
| 105 | + - `guess_data_key()`: Infers the data key in paginated responses |
| 106 | + |
| 107 | +### Testing |
| 108 | +- **Test framework**: pytest with pytest-cov for coverage |
| 109 | +- **Test utilities**: `tests/helpers/utils.py` provides a `cli()` helper that wraps the Typer CLI runner |
| 110 | +- **Test data setup**: Tests depend on `test_import.py` running first to load test entities |
| 111 | +- Tests use the real Cortex API (not mocked) and require valid `CORTEX_API_KEY` |
| 112 | +- Parallel execution: Tests run with `pytest-xdist` (`-n auto`) for speed |
| 113 | +- Serial marker: Use `@pytest.mark.serial` for tests that must run sequentially |
| 114 | + |
| 115 | +## Command Naming Style Guide |
| 116 | + |
| 117 | +Follow the conventions in `STYLE.md`: |
| 118 | +- **Flags over arguments**: Use named flags for clarity and future compatibility |
| 119 | +- **Long and short versions**: All flags should have both (e.g., `--long-version, -l`) |
| 120 | +- **Consistent short flags**: Reuse short flags across commands where possible |
| 121 | +- **Kebab-case**: Multi-word flags use kebab-case (e.g., `--api-key`) |
| 122 | + |
| 123 | +### Standard Verbs |
| 124 | +- **list**: Paginated list of resources (fetch all pages by default) |
| 125 | +- **get**: Retrieve full details of a single object |
| 126 | +- **create**: Create new object (fails if exists, unless `--replace-existing` or `--update-existing`) |
| 127 | +- **delete**: Delete object (interactive prompt unless `--force`) |
| 128 | +- **update**: Modify existing object (accepts full or partial definitions) |
| 129 | +- **archive/unarchive**: Archive operations |
| 130 | +- **add/remove**: Add/remove items from list attributes |
| 131 | +- **set/unset**: Set/unset single-value attributes |
| 132 | +- **open**: Open resource in browser |
| 133 | + |
| 134 | +## Build & Release Process |
| 135 | + |
| 136 | +### Release Workflow |
| 137 | +1. Create feature branch for changes |
| 138 | +2. Merge to `staging` branch for testing |
| 139 | +3. Merge `staging` to `main` to trigger release |
| 140 | +4. Version bumping: |
| 141 | + - Default: Patch version bump |
| 142 | + - `#minor` in commit message: Minor version bump |
| 143 | + - `#major` in commit message: Major version bump |
| 144 | +5. Release publishes to: |
| 145 | + - PyPI |
| 146 | + - Docker Hub (`cortexapp/cli:VERSION` and `cortexapp/cli:latest`) |
| 147 | + - Homebrew tap (`cortexapps/homebrew-tap`) |
| 148 | + |
| 149 | +### Commit Message Format |
| 150 | +Commits should be prefixed with: |
| 151 | +- `add`: New features |
| 152 | +- `fix`: Bug fixes |
| 153 | +- `change`: Changes to existing features |
| 154 | +- `remove`: Removing features |
| 155 | + |
| 156 | +Only commits with these prefixes appear in the auto-generated `HISTORY.md`. |
| 157 | + |
| 158 | +### GitHub Actions |
| 159 | +- **`publish.yml`**: Triggered on push to `main`, handles versioning and multi-platform publishing |
| 160 | +- **`test-pr.yml`**: Runs tests on pull requests |
| 161 | + |
| 162 | +## Key Files |
| 163 | + |
| 164 | +- `cli.py`: Main CLI entry point and global callback |
| 165 | +- `cortex_client.py`: HTTP client for Cortex API |
| 166 | +- `command_options.py`: Reusable command option definitions |
| 167 | +- `utils.py`: Output formatting utilities |
| 168 | +- `commands/*.py`: Individual command implementations |
| 169 | +- `pyproject.toml`: Poetry configuration and dependencies |
| 170 | +- `Justfile`: Task automation recipes |
| 171 | +- `DEVELOPER.md`: Developer-specific testing and workflow notes |
| 172 | +- `STYLE.md`: Command design guidelines |
0 commit comments