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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,6 @@ __marimo__/
.streamlit/secrets.toml

.serena/
plans/**/*
!plans/templates/*
repomix-output.xml
22 changes: 22 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Quick Reference

`trobz_local` (CLI: `tlc`) - Odoo dev environment automation tool.

```bash
uv sync && uv run pre-commit install # Setup
make check # Lint + type check
make test # Run tests
uv run pytest tests/test_file.py -v # Single test
make build # Build wheel
```

## Documentation

**Read `docs/` for details** - architecture, code standards, config examples:
- `docs/project-overview-pdr.md` - Features, requirements, config schema
- `docs/codebase-summary.md` - Module analysis
- `docs/code-standards.md` - Conventions, security practices
115 changes: 95 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,116 @@
# trobz_local
# trobz_local (tlc)

[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL--3.0-lightgrey.svg)](https://www.gnu.org/licenses/agpl-3.0)

Local is a CLI tool to streamline Odoo development environments.
It automates repository management, directory structures, and virtual environments using `uv` and `odoo-venv`.
A developer tool for automating setup and management of local Odoo development environments. Streamlines directory structure creation, source code repository management, and installation of required development tools.

![Demo](./assets/demo.gif)
## What is trobz_local?

`trobz_local` (CLI: `tlc`) automates repetitive tasks when setting up an Odoo development environment. Instead of manually creating directories, cloning repositories, and installing dependencies, developers declare their desired environment in a TOML configuration file and `tlc` handles the rest.

## Key Features

- **Environment Initialization** (`init`): Creates standardized directory structure at `~/code/`
- **Repository Management** (`pull-repos`): Clones/updates Odoo and OCA repos in parallel
- **Tool Installation** (`install-tools`): Installs from four sources: scripts, system packages, NPM, and UV tools
- **Virtual Environments** (`create-venvs`): Creates Odoo venvs for each configured version
- **Interactive Mode**: Newcomer mode with confirmations and guidance
- **Security**: HTTPS enforcement for all downloads

## Installation

With [`uv`](https://docs.astral.sh/uv/):
Install globally using [uv](https://docs.astral.sh/uv/):

```bash
uv tool install git+ssh://[email protected]:trobz/local.py.git
```

### Getting Started

The first step is to initialize the directory structure for your local environment:
## Quick Start

```bash
# 1. Initialize directory structure
tlc init

# 2. Create config file
cat > ~/code/config.toml << 'EOF'
versions = ["16.0", "17.0"]

[tools]
uv = ["odoo-venv", "pre-commit"]
npm = ["prettier"]
system_packages = ["postgresql"]

[repos]
odoo = ["odoo", "enterprise"]
oca = ["server-tools"]
EOF

# 3. Setup environment
tlc pull-repos # Clone repositories
tlc create-venvs # Create virtual environments
tlc install-tools # Install tools
```

## Commands

| Command | Purpose |
|---------|---------|
| `tlc init` | Create directory structure in `~/code/` |
| `tlc pull-repos` | Clone or update Odoo/OCA repositories |
| `tlc create-venvs` | Create Python virtual environments |
| `tlc install-tools` | Install scripts, packages, and tools |

Use `--newcomer=false` to skip confirmation prompts. Use `--help` on any command for options.

## Configuration

Place `~/code/config.toml` with your environment definition:

```toml
versions = ["16.0", "17.0", "18.0"]

[tools]
uv = ["odoo-venv", "odoo-addons-path", "pre-commit"]
npm = ["prettier", "eslint"]
system_packages = ["git", "postgresql", "pnpm"]

[[tools.script]]
url = "https://astral.sh/uv/install.sh"
name = "uv installer"

[repos]
odoo = ["odoo", "enterprise"]
oca = ["server-tools", "server-ux", "web"]
```

* `tlc pull-repos`: Clone or update Odoo and OCA repositories.
* **Filtering**: You can filter specific repositories using the `-f` or `--filter` flag.
```bash
tlc pull-repos -f odoo -f web
```
* `tlc create-venvs`: Create virtual environments for your Odoo versions.
* `tlc install-tools`: Install other CLI tools defined in your config.
* `tlc install-packages`: Install required system packages.
See [Configuration Schema](./docs/project-overview-pdr.md#configuration-schema) for all options and validation rules.

## System Requirements

### Configuration
- Python 3.10+
- `uv` package manager
- Linux (Arch, Ubuntu) or macOS
- System tools: `git`, `wget` or `curl`, `sh`

You can configure the tool using environment variables:
## Documentation

For detailed information:

- [**Project Overview & PDR**](./docs/project-overview-pdr.md): Features, requirements, configuration schema
- [**System Architecture**](./docs/system-architecture.md): Design patterns, component interactions
- [**Codebase Summary**](./docs/codebase-summary.md): Module-by-module technical details
- [**Code Standards**](./docs/code-standards.md): Development guidelines and conventions

## Development

```bash
git clone [email protected]:trobz/local.py.git && cd local.py
uv sync && uv run pre-commit install
make check # Linters and type checks
make test # Run tests
```

* `NEWCOMER_MODE`: Set to `false` or `0` to disable interactive confirmations and help messages for a faster workflow.
## License

Run `tlc --help` for more information on all commands.
AGPL-3.0 - See [LICENSE](./LICENSE) for details.
213 changes: 213 additions & 0 deletions docs/code-standards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
# Code Standards & Structure

Development guidelines, architectural patterns, and best practices for `trobz_local`.

## Project Architecture

Four-layer modular design with clear separation of concerns:

| Layer | Module(s) | Responsibility |
|---|---|---|
| **CLI Layer** | `main.py` | Command routing, user interaction, newcomer mode |
| **Implementation** | `installers.py` | Four installation strategies (script, system, npm, uv) |
| **Utility Layer** | `utils.py` | Config validation, platform detection, helpers |
| **Infrastructure** | `concurrency.py`, `exceptions.py` | Parallel execution, custom exceptions |

---

## Code Style Guidelines

### Python Conventions
- **Standard**: PEP 8 compliance
- **Formatter**: ruff (fast, deterministic)
- **Line Length**: Max 120 characters (ruff.toml config)
- **Import Order**: stdlib → third-party → local (ruff-managed)
- **Active Rules**: YTT, S (security), B, A, C4, T10, SIM, I, C90, E, W, F, PGH, UP, RUF, TRY

### Type Safety (Mandatory)
- All function signatures must have type hints
- Complex variables must be annotated
- Static analysis via mypy (ty wrapper)
- Pydantic for external data validation (config.toml)

### Naming Rules

| Element | Pattern | Example |
|---|---|---|
| Modules | snake_case | `installers.py` |
| Classes | PascalCase | `ConfigModel` |
| Functions | snake_case | `pull_repos` |
| Constants | SCREAMING_SNAKE_CASE | `ARCH_PACKAGES` |
| Private | _snake_case | `_run_installers` |

---

## Architectural Patterns

### 1. Declarative Configuration
System state defined in TOML. Tool reconciles local environment with definition. Pydantic validates before any side effects.

### 2. Strategy Pattern
`installers.py`: Multiple strategies per tool source (script, system packages, npm, uv) with OS-aware selection.

### 3. Command Pattern
`main.py`: Each CLI command is discrete but shares context (newcomer mode, dry-run). Easy to add new commands.

### 4. Observer Pattern
`GitProgress` and `run_tasks()`: Real-time progress callbacks to Rich UI. Decoupled from execution logic.

### 5. Fail-Fast Validation
Config validated at startup. Early detection prevents side effects on invalid input.

---

## Security Requirements

### Subprocess Safety
- **Never use shell=True** - Always pass arguments as list
- **Full paths only** - Use shutil.which() instead of relying on PATH
- **No user input in commands** - Build commands from validated config only

### Download Security
- **HTTPS enforcement** - Pydantic validator rejects non-HTTPS URLs
- **Trusted sources only** - Script URLs must be whitelisted or reviewed

### Input Validation
- **Regex patterns** - All config fields validated with specific patterns:
- Versions: `^\d+\.\d+$`
- UV tools: `^[a-zA-Z0-9][a-zA-Z0-9._\-\[\]@=<>!,]*$`
- Repo names: `^[a-zA-Z0-9._-]+$`
- **Pydantic models** - No ad-hoc parsing of config
- **Ruff S* rules** - Security linting enabled in make check

### Credential Handling
- No credentials stored in code
- No sensitive data logged
- Environment variables used for user-specific paths only

---

## Error Handling Patterns

### Custom Exceptions
Use specialized exceptions from `exceptions.py` with context:
```python
raise DownloadError(url=script_url, reason=str(e))
raise ExecutableNotFoundError(executable="wget")
```

### Fail Paths
1. **Config errors**: Print message + example, exit 1
2. **Task failures**: Catch exception, record in TaskResult, continue
3. **Validation errors**: Pydantic prints field-level details, exit 1

### Cleanup
- Use context managers for temporary files
- Temporary directories auto-deleted on function exit
- No partial state on failure

---

## Testing Requirements

### Framework
- **Tool**: pytest
- **Mocking**: unittest.mock for filesystem, network, subprocesses
- **Coverage**: All new features must include tests
- **No real I/O**: Tests must not actually download, install, or git-clone

### Test Organization
- Test file naming: `test_{module}.py`
- Test function naming: `test_{function}_case_description`
- Fixtures for common setup
- Parametrized tests for multiple scenarios

### Running Tests
```bash
make test # Full suite
pytest -xvs file.py # Single file with verbose output
pytest --cov # Coverage report
```

---

## Development Workflow

### Setup
```bash
uv sync # Install dependencies
uv run pre-commit install # Setup git hooks
make check # Verify setup (lint + type check)
```

### Code Quality Checklist
- [ ] Code follows naming conventions and style guidelines
- [ ] Type hints on all function signatures
- [ ] Tests written and passing (make test)
- [ ] Linting passes (make check)
- [ ] No security issues (ruff S rules)
- [ ] Error handling implemented
- [ ] Documentation updated

### Before Committing
```bash
make check # Linters + type checkers
make test # Full test suite
```

### Commit Message Format
Follow [Conventional Commits](https://www.conventionalcommits.org/):
- `feat: description` - New feature
- `fix: description` - Bug fix
- `docs: description` - Documentation
- `refactor: description` - Code restructuring
- `test: description` - Test additions
- `chore: description` - Maintenance

---

## File Structure

**Max file size**: 500 LOC (split if larger)
- `main.py`: CLI commands and orchestration
- `installers.py`: Installation strategies
- `utils.py`: Config, platform detection, helpers
- `concurrency.py`: Task runner with progress
- `exceptions.py`: Custom exception classes

**Imports in each module**:
- No circular imports
- Public functions documented
- Private functions start with underscore

---

## Documentation Standards

### Docstrings (Google Style)
```python
def function(param: Type) -> ReturnType:
"""Brief one-line description.

Longer description if needed.

Args:
param: Description

Returns:
Description of return value

Raises:
CustomError: When this happens
"""
```

### Code Comments
- Explain "why", not "what"
- Comment complex logic only
- Keep comments synchronized with code

### Inline Documentation
- Update docs/ files when changing features
- Keep code examples in docs/ current
- Reference specific line numbers when helpful
Loading