Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,7 @@ __marimo__/
plans/**/*
!plans/templates/*
repomix-output.xml
AGENTS.md
.claude/
.opencode/
release-manifest.json
22 changes: 22 additions & 0 deletions .repomixignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
docs/*
plans/*
assets/*
dist/*
coverage/*
build/*
ios/*
android/*
tests/*
__tests__/*
__pycache__/*
node_modules/*

.opencode/*
.claude/*
.serena/*
.pnpm-store/*
.github/*
.dart_tool/*
.idea/*
.husky/*
.venv/*
14 changes: 7 additions & 7 deletions docs/code-standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Config validated at startup. Early detection prevents side effects on invalid in

### Input Validation
- **Regex patterns** - All config fields validated with specific patterns:
- Versions: `^\d+\.\d+$`
- Versions: `^(?:\d+\.\d+|master)$` (supports semver and "master" branch)
- UV tools: `^[a-zA-Z0-9][a-zA-Z0-9._\-\[\]@=<>!,]*$`
- Repo names: `^[a-zA-Z0-9._-]+$`
- **Pydantic models** - No ad-hoc parsing of config
Expand Down Expand Up @@ -169,12 +169,12 @@ Follow [Conventional Commits](https://www.conventionalcommits.org/):
## File Structure

**Max file size**: 500 LOC (split if larger)
- `main.py`: CLI commands and orchestration (452 LOC)
- `installers.py`: Installation strategies (282 LOC)
- `utils.py`: Config, platform detection, helpers (264 LOC)
- `concurrency.py`: Task runner with progress (60 LOC)
- `exceptions.py`: Custom exception classes (38 LOC)
- `tests/`: pytest unit tests for all modules
- `main.py`: CLI commands and orchestration (455 LOC)
- `installers.py`: Installation strategies (283 LOC)
- `utils.py`: Config, platform detection, helpers (275 LOC)
- `concurrency.py`: Task runner with progress (61 LOC)
- `exceptions.py`: Custom exception classes (39 LOC)
- `tests/`: pytest unit tests (613 LOC total, 69% coverage)

**Imports in each module**:
- No circular imports
Expand Down
24 changes: 14 additions & 10 deletions docs/codebase-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ Technical overview of the `trobz_local` codebase structure, implementation patte

| Metric | Value |
|---|---|
| **Language** | Python 3.12+ |
| **Total LOC** | ~1,096 lines (core logic) + tests |
| **Core Modules** | 6 files (main, installers, utils, concurrency, exceptions, \__init\_\_) |
| **Test Modules** | tests/ directory with pytest unit tests |
| **Language** | Python 3.10+ |
| **Core LOC** | 1,109 lines (production code across 6 files) |
| **Test LOC** | 613 lines (4 test files, 69% coverage, 20 passing tests) |
| **Core Modules** | 6 files: main (455), installers (282), utils (274), concurrency (60), exceptions (38), __init__ (0) |
| **Test Modules** | test_pull_repos (211), test_install_tools (253), test_create_venvs (123), test_utils (26) |
| **Primary Frameworks** | Typer (CLI), Pydantic (validation), Rich (UI), GitPython (git) |
| **Concurrency Model** | ThreadPoolExecutor, max 4 workers, I/O-bound tasks |
| **License** | AGPL-3.0 |

## Module Breakdown

### `main.py` (452 LOC)
### `main.py` (455 LOC)
**Purpose**: CLI entry point and command orchestration

**Responsibilities**:
Expand All @@ -41,7 +42,7 @@ Technical overview of the `trobz_local` codebase structure, implementation patte

---

### `installers.py` (282 LOC)
### `installers.py` (283 LOC)
**Purpose**: Multi-source tool installation strategies

**Strategies**:
Expand All @@ -64,7 +65,7 @@ Technical overview of the `trobz_local` codebase structure, implementation patte

---

### `utils.py` (264 LOC)
### `utils.py` (275 LOC)
**Purpose**: Configuration validation, platform detection, utilities

**Pydantic Models**:
Expand All @@ -74,13 +75,14 @@ Technical overview of the `trobz_local` codebase structure, implementation patte
- `RepoConfig` - Repository definitions (odoo, oca)

**Validation**:
- Versions: Pattern `^\d+\.\d+$`
- Versions: Pattern `^(?:\d+\.\d+|master)$` (supports semver and "master" branch)
- UV tools: Pattern `^[a-zA-Z0-9][a-zA-Z0-9._\-\[\]@=<>!,]*$`
- NPM packages: Scoped and unscoped validation
- Scripts: HTTPS-only enforcement
- Repo names: Pattern `^[a-zA-Z0-9._-]+$`

**Key Functions**:
- `get_code_root()` - Resolve code root directory from TLC_CODE_DIR env var or default to ~/code
- `get_config()` - Load and validate config.toml with error handling
- `get_uv_path()` - Locate uv executable
- `get_os_info()` - Return {system, distro} for platform detection
Expand All @@ -91,7 +93,7 @@ Technical overview of the `trobz_local` codebase structure, implementation patte

---

### `concurrency.py` (60 LOC)
### `concurrency.py` (61 LOC)
**Purpose**: Generic parallel task execution with progress tracking

**TaskResult Dataclass**:
Expand All @@ -113,7 +115,7 @@ class TaskResult:

---

### `exceptions.py` (38 LOC)
### `exceptions.py` (39 LOC)
**Purpose**: Custom exception hierarchy for granular error handling

**Exception Classes**:
Expand Down Expand Up @@ -162,6 +164,8 @@ The `get_code_root()` function (utils.py) resolves the code root directory by:
1. First checking for `TLC_CODE_DIR` environment variable
2. Falling back to `~/code` if not set

This enables flexible deployment: developers can customize the base directory via environment variable while maintaining consistent configuration file location at `{CODE_ROOT}/config.toml`.

---

## External Dependencies
Expand Down
12 changes: 7 additions & 5 deletions docs/project-overview-pdr.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,11 @@ oca = ["server-tools", "server-ux", "web"]
### Field Reference & Validation

#### `versions` (Required)
Odoo versions to set up. Format: Major.Minor (e.g., "16.0", "17.0")
Odoo versions to set up. Supports semantic versioning (Major.Minor) or "master" branch.
- **Type**: List of strings
- **Pattern**: `^\d+\.\d+$`
- **Example**: `["16.0", "17.0", "18.0"]`
- **Pattern**: `^(?:\d+\.\d+|master)$`
- **Examples**: `["16.0", "17.0", "18.0"]` or `["master", "17.0"]`
- **Note**: "master" branch for development, semver (16.0, 17.0) for stable releases

#### `tools.uv` (Optional)
UV tools to install globally via `uv tool install`
Expand Down Expand Up @@ -188,7 +189,7 @@ System packages are automatically merged with defaults for your OS:

**Valid configurations:**
```toml
versions = ["16.0", "17.0"] # ✓ Correct format
versions = ["16.0", "17.0", "master"] # ✓ Correct format with master branch
tools.uv = ["package[extra]@1.0", "tool"] # ✓ Supports extras syntax
tools.npm = ["@babel/core", "prettier"] # ✓ Scoped and unscoped
repos.odoo = ["odoo", "enterprise"] # ✓ Both sources
Expand All @@ -197,7 +198,8 @@ repos.oca = ["server-tools", "web"] # ✓ Valid names

**Invalid configurations:**
```toml
versions = ["16", "17.0"] # ✗ First version invalid format
versions = ["16", "17.0"] # ✗ First version invalid (missing minor)
versions = ["main", "17.0"] # ✗ "main" not supported (use "master")
tools.uv = [" invalid"] # ✗ Leading space
tools.npm = ["__invalid"] # ✗ Double underscore
tools.script = [{url = "http://..."}] # ✗ HTTP not allowed (HTTPS only)
Expand Down
6 changes: 6 additions & 0 deletions docs/system-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,12 @@ Script Execution
- Can be customized per operation type if needed
- Example: `run_tasks(tasks, max_workers=8)` for more parallelization

### Version Support
- **Semantic Versioning**: "16.0", "17.0", "18.0" (standard Odoo releases)
- **Master Branch**: "master" for development/cutting-edge versions
- **Pattern**: `^(?:\d+\.\d+|master)$` enforced via Pydantic validation
- **Branch Mapping**: Version strings map to git branch names during pull-repos

---

## Performance Characteristics
Expand Down
2 changes: 1 addition & 1 deletion trobz_local/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
)

TOOL_NAME_REGEX = re.compile(r"^[a-zA-Z0-9][a-zA-Z0-9._\-\[\]@=<>!,]*$")
VERSION_REGEX = re.compile(r"^\d+\.\d+$")
VERSION_REGEX = re.compile(r"^(?:\d+\.\d+|master)$")

ARCH_PACKAGES = [
"gcc",
Expand Down