Metadata-Version: 2.4
Name: odoo-dev
Version: 1.2.1
Summary: Odoo Development Environment Helper
Project-URL: Homepage, https://git.bemade.org/bemade/odoo-dev
Project-URL: Repository, https://git.bemade.org/bemade/odoo-dev
Project-URL: Issues, https://git.bemade.org/bemade/odoo-dev/-/issues
License-Expression: LGPL-3.0
Requires-Python: >=3.12
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.0.0
Requires-Dist: typer>=0.9.0
Description-Content-Type: text/markdown

# odoo-dev

A CLI tool for managing Odoo development environments. Handles local Python setup, Docker containers, database operations, and more.

It is the successor to the older `odoo-deploy` shell scripts — if you have notes for `odoo-deploy`, the rough mapping is: `odoo-dev docker start/stop/build` replaces the old `odoo-dev.sh start/stop/build`, and `odoo-dev run`/`test`/`shell` give you a local (venv-based) workflow that `odoo-deploy` didn't.

## Installation

```bash
# Install with uv (recommended) — installs the published package from PyPI
uv tool install odoo-dev

# Or with pip
pip install odoo-dev
```

Then make sure the install location is on your `PATH` (uv prints the path; usually `~/.local/bin`):

```bash
uv tool update-shell   # or: export PATH="$HOME/.local/bin:$PATH"
```

## Quick Start

```bash
# In your Odoo project directory
cd my-odoo-project

# Full setup: clone Odoo repos, create venv, install deps, configure VSCode
odoo-dev setup

# Or for community edition only
odoo-dev setup --community
```

`setup` reads `ODOO_VERSION` / `PYTHON_VERSION` from a `.env` in the project root (or
prompts for them and offers to save). It then clones the Odoo repos, builds a `.venv`,
installs system dependencies, and generates `conf/odoo.conf`. It will offer to set up
Docker at the end — answer "no" if you only want the local venv workflow.

## Database setup (read this before your first `run`/`test`)

The generated `conf/odoo.conf` connects as PostgreSQL user **`odoo`** over the local
socket. **A running PostgreSQL server is a prerequisite you provide yourself** — on
every platform. `setup` installs only the PostgreSQL *client* and build dependencies
(macOS: `libpq`; Linux: `postgresql-client` + `libpq-dev`); it never installs, starts,
or configures a server, and never creates the `odoo` role. So on a fresh machine,
install a server, start it, and create the role once:

**macOS (Homebrew):**

```bash
brew install postgresql@18                  # install a server (pick your version)
brew services start postgresql@18           # start it
createuser -s odoo                          # create the role odoo.conf expects
# Homebrew's versioned postgres is keg-only; add its bin to PATH if psql/createuser aren't found:
#   export PATH="$(brew --prefix postgresql@18)/bin:$PATH"
```

**Debian/Ubuntu:**

```bash
sudo apt-get install postgresql     # install a server if you don't already have one
sudo systemctl start postgresql
sudo -u postgres createuser -s odoo
```

**Using a different / remote / Docker PostgreSQL:** set `DB_HOST`, `DB_PORT`,
`DB_USER`, `DB_PASSWORD` in `.env` before running `setup` (it writes them into
`conf/odoo.conf`), or edit `conf/odoo.conf` directly. With no `DB_HOST`, odoo-dev
connects over the local socket as the `odoo` role.

Before launching, `run`/`test`/`shell`/`update` run a quick connection preflight: if
the server is unreachable, the role is missing, or authentication fails, you get a
specific one-line fix instead of a stack trace.

## Commands

### Local Development (default)

```bash
odoo-dev run                          # Start Odoo locally (default port 8069)
odoo-dev run -d mydb -p 8070          # Pick a database and HTTP port
odoo-dev run -d mydb -i base          # Initialize module(s) on start
odoo-dev run -d mydb --dev reload     # With hot reload
odoo-dev run --debug                  # With debugpy (VSCode attach on 5678)
odoo-dev shell mydb                   # Open an Odoo shell
odoo-dev update base -d mydb          # Update modules
odoo-dev test my_module               # Run a module's tests (coverage on by default)
odoo-dev test my_module --test-tags my_module --no-coverage
odoo-dev test                         # Auto-discover & test all addons in addons/ + vendored/
odoo-dev scaffold my_module           # Create a new module
```

> Note: the HTTP port flag is `-p` / `--port` (not `--http-port`).

### Database Operations

```bash
odoo-dev db list                      # List databases
odoo-dev db restore backup.zip        # Restore from backup (neutralized by default)
odoo-dev db restore backup.zip mydb --no-neutralize
odoo-dev db drop mydb                  # Drop database
odoo-dev db neutralize mydb            # Disable emails/crons
```

### Docker (optional)

```bash
odoo-dev docker start                 # Start containers
odoo-dev docker stop                  # Stop containers
odoo-dev docker restart               # Restart containers
odoo-dev docker logs                  # View logs
odoo-dev docker build                 # Rebuild image
odoo-dev docker shell mydb            # Shell in container
odoo-dev docker psql                  # PostgreSQL shell
```

### Setup Commands

```bash
odoo-dev setup                        # Full setup (interactive; offers Docker)
odoo-dev setup --community            # Community edition only
odoo-dev setup --no-docker --yes      # Headless/agentic: clone + venv + conf, no Docker, no prompts
odoo-dev setup-venv                   # Just create the venv (no repo clone)
odoo-dev vscode                       # Configure VSCode debugging
```

### Vendored Addons

Shared addons can be **vendored** — materialized as real committed directories
under `vendored/`, pinned per-addon by `addons.lock` — instead of pulled in as
`.repos/` git submodules. This makes each promotion a normal, reviewable file
diff and deploys as plain files (what Odoo.sh needs). `vendored/` and `addons/`
are both on the addons path.

```bash
odoo-dev vendor migrate               # Convert .repos submodule+symlink addons -> vendored/
odoo-dev vendor migrate --dry-run     # Preview the pins without changing anything
odoo-dev vendor sync                  # Materialize vendored/ from addons.lock
odoo-dev vendor check                 # CI gate: verify vendored/ byte-matches the pins
odoo-dev vendor add fsm --source github.com/bemade/bemade-addons --version 18.0.1.3.2
odoo-dev vendor bump fsm --version 18.0.1.4.0   # Move a pin and re-materialize
odoo-dev vendor update                # Pull newest upstream for all tracked addons
odoo-dev vendor update fsm --dry-run  # Show what would update, change nothing
odoo-dev vendor develop fsm           # Edit fsm against a live source clone
odoo-dev vendor develop fsm --stop    # Leave develop mode (keeps the clone)
odoo-dev vendor status                # Show vendored pins, symlinks, develop mode
```

Because `vendored/<addon>` is a materialized copy (re-`sync` clobbers it), you
don't edit it in place. `vendor develop <addon>` clones the addon's source repo
into a git-ignored `.vendor-dev/`, checks out a work branch at the pinned commit,
and prepends an overlay to your **local** `conf/odoo.conf` addons_path so Odoo
loads the live tree instead of the vendored copy (first path wins). `vendored/`
stays byte-for-byte pristine and only the local conf is touched, so nothing
dev-only can leak into a commit or into CI/prod. Edit in the clone, run/test in
this project's Odoo, commit + push upstream, then `vendor bump` once the new
version is tagged. `--branch NAME` names the work branch; `--base REF` bases it on
something other than the current pin.

`vendor check` verifies, per addon: the vendored files byte-match the pinned
commit; a `version` tag (if set) still resolves to that commit; every manifest
`external_dependencies['python']` is named in `requirements.txt`; and no addon
name collides between `addons/` and `vendored/`.

`vendor update` is the **pull** side: each client owns its pins. For every addon
that tracks upstream — a `version` (bump to the newest `<addon>/<version>` tag) or
a `branch` (bump to its HEAD) — it moves the pin forward and re-materializes.
Addons pinned to a bare commit are left alone. Run it on a schedule (a client's own
CI, its own token, opening a `vendor-bump/…` MR) so shared-addon changes propagate
without any per-source push/fan-out machinery.

## Project Structure

odoo-dev expects this project structure:

```
my-odoo-project/
├── .env                 # Optional: ODOO_VERSION, PYTHON_VERSION
├── addons/              # Your custom addons
├── vendored/            # Vendored shared addons (real files, pinned by addons.lock)
├── addons.lock          # Per-addon pins for vendored/ (see `vendor`)
├── requirements.txt     # Project-specific Python deps
├── odoo/                # Cloned by setup
├── enterprise/          # Cloned by setup (unless --community)
├── design-themes/       # Cloned by setup
├── .venv/               # Created by setup
└── conf/
    └── odoo.conf        # Created by setup
```

`vendored/` and `addons.lock` are only present once a project adopts vendoring
(`odoo-dev vendor migrate`); submodule-based projects use `.repos/` + symlinks
into `addons/` instead.

## Configuration

Create a `.env` file in your project root:

```bash
ODOO_VERSION=19.0
PYTHON_VERSION=3.12

# Optional — DB connection, written into conf/odoo.conf by `setup`.
# Omit DB_HOST/DB_PORT to use the local socket (the default). Set these to
# point at a remote / Docker / non-default PostgreSQL:
# DB_HOST=localhost
# DB_PORT=5432
# DB_USER=odoo
# DB_PASSWORD=odoo
```

## Requirements

- Python 3.12+
- uv (recommended) or pip
- Git
- PostgreSQL (for local development — server + an `odoo` role; see "Database setup")
- Docker (optional, for containerized development)

## Development

```bash
# Clone and install for development
git clone git@github.com:bemade/odoo-dev.git
cd odoo-dev
uv sync

# Run tests
uv run pytest                 # All tests
uv run pytest -m "not slow"   # Fast tests only

# Build
uv build
```

## License

LGPL-3. For complete license terms, visit https://www.gnu.org/licenses/lgpl-3.0.en.html
