Skip to content

[BETA] 4.25.0#132

Open
brinkflew wants to merge 34 commits into
mainfrom
beta
Open

[BETA] 4.25.0#132
brinkflew wants to merge 34 commits into
mainfrom
beta

Conversation

@brinkflew
Copy link
Copy Markdown
Contributor

Description

Only odoo/addons is required as other base modules are loaded by the framework. Explicitly adding that path in the addons-paths of odoo-bin introduces errors when running an upgrade locally.

Compliance

  • I have read the contribution guide
  • I made sure the documentation is up-to-date both in doctrings and the docs directory
  • I have added or modified unit tests where necessary
  • I have added new libraries to the requirements.txt file, if any
  • I have incremented the version number according the versioning guide
  • The PR contains my changes only and no other external commit

Only `odoo/addons` is required as other base modules are loaded by
the framework. Explicitly adding that path in the addons-paths of
`odoo-bin` introduces errors when running an upgrade locally.
@brinkflew brinkflew self-assigned this Jan 28, 2026
Instead, only load table definitions and constraints when the table
is created. This only impacts Odev's database, used for internal
operations.

Performance gains:
- Framework loaded: 5ms (1.3%)
- Framework started: 48ms (6.4%)
- Execution completed: 46ms (5.5%)
Avoid some costly operations when update is not needed.

Performance gains:
- Framework loaded: 6ms (1.7%)
- Framework started: 48ms (5.8%)
- Execution completed: 51ms (6.5%)
Plugins where installed at every run of odev, taking a substantial
amount of time. Also check for missing requirements before running
`pip install`, as the operation is generally 50 times faster and can
prevent running a useless install.

Performance gains:
- Framework loaded: 25ms (8.1%)
- Framework started: 211ms (42.3%)
- Execution completed: 184ms (31.1%)
Move some imports to lazy-load features only when required.

Performance gains: minimal
We noticed the implematation of `functools.ttl_cache` was not fit with
our needs and was failing to cache some subprocesses results.
This had an unnecessary toll on performances when listing databases.
Allow choosing a value for the bypass (do or do not).
Only run the subprocess once for all databases instead of once per
database. This makes it more efficient if coupled with proper caching.
@brinkflew brinkflew marked this pull request as draft January 28, 2026 18:52
Stop filtering detached and version-mismatched worktrees in the shared iterator so
commands can decide how to handle each case themselves. This avoids false
"worktree does not exist" errors when a command needs to inspect detached
worktrees before applying its own logic.
`warnings.deprecated` exists only from Python 3.13 onward; add
`odev.common.deprecation` with a pre-3.13 shim and use it from `console` so
CI on 3.10–3.12 can import the stack again.

Stop shadowing the `upgrade` argument in `Odev.update()` and run the post-
update path when the repo or plugins reported changes (or `upgrade=True`).
Fix `install_requirements` treating the `missing_requirements` generator as
always truthy, and skip cleanly when there is no `requirements.txt` so test
plugins can install.

Make `test_04_restart_on_update` force `__should_update_now` so `start()`
exercises update reliably. Add 3.13 to the unit-test matrix and ignore
`.cursor/` and `.agents/` for local tooling.
@brinkflew brinkflew changed the title [IMP] Do not load unecessary odoo/odoo/addons in addons-paths [BETA] 4.25.0 Mar 21, 2026
@brinkflew brinkflew marked this pull request as ready for review March 23, 2026 10:23
sea-odoo and others added 12 commits March 23, 2026 16:04
* fix: only process requested version worktrees in GitCommand

* fix: respect ODEV_NO_SSH_AGENT and handle decryption failure gracefully

* fix: correctly handle detached HEAD and missing upstream in worktrees

* fix: resolve pre-commit issues and improve robustness

* chore: bump version to 4.26.0
…134)

* [REF] core: support AI CLI sandboxed execution

* fix(rest): add ConnectionResetError to retryable exceptions

The REST connector now catches ConnectionResetError in addition to RequestsConnectionError during requests. This ensures that the built-in retry logic is triggered when a connection is reset by the peer, improving resilience against transient network issues.

* fix(test): improve debugger detection regex

* [IMP] rest: improve cookie handling and fix caching order
- Add head method to RESTConnector
- Fix virtualenv check in LocalDatabase
When topological_sort fails, enumerate simple_cycles and append a
human-readable chain to OdevError so users can see which plugins
participate in the cycle.
The workflow used a multiline Python version list, which made the matrix
non-deterministic; POSTGRES_HOST pointed at a non-existent hostname; and
--exitfirst hid secondary failures. CI now pins one Python per job, waits for
PostgreSQL, uses localhost for the DB host, pins the apt-cache action, refreshes
Odoo cache keys, and runs the full suite with `coverage report`.

Coverage had no floor, so regressions could slip through. `fail_under` and
`show_missing` align local and CI reporting with CONTRIBUTING.

REST had no default timeout and nocache could leave bypass flags set after
errors; Postgres `Cursor.transaction` committed after rollback. Defaults and
try/finally restore predictable behavior without changing call sites.

`fetch` referenced `self.args.name` in an error path (wrong attribute),
which crashed instead of surfacing a clean command error.

Tests previously picked up the user plugins directory in test mode, so
machine-local plugin cycles could break the whole suite. Pointing
`plugins_path` at the run temp dir isolates runs.

Added tests for `__main__`, connectors, plugin registration and dependency
cycles, git/scripts commands, and database info/neutralize/dump.
* [FIX] various improvements to test execution and rest connector

* core: miscellaneous improvements and bug fixes

- Use readlink -f in odev.sh for better script resolution
- Refactor database template creation logic
- Relax database name validation to allow colons
- Include request body in RestConnector cache key
- Fix odev.plugins module initialization for Python 3 compatibility
- Deduplicate addons paths
- Proper shell quoting for python script arguments

* [FIX] Version bump

* [IMP] core: improve odoo log parsing and argument handling

- Fixed carriage return handling in shell stream to avoid broken log formatting.
- Enhanced ODOO_LOG_REGEX to support logs without date or PID.
- Standardized version, venv, and worktree resolution to look for *_argument attributes in commands.
- Added combined_odoo_args to handle Odoo flags captured by positional 'addons' argument.
- Implemented --command flag support for 'odev shell' to pipe code via stdin.

* [IMP] core: introduce EmployeeUtils and refactor telemetry

- Added EmployeeUtils to centralize Odoo employee detection and xgram retrieval.
- Updated Telemetry to use the new utility.

* [IMP] core: add upgrade-code command for Odoo 18.0+

Implemented native 'upgrade_code' tool support. The command includes logic to automatically handle shell glob expansion and reconstruct target glob patterns for the Odoo upgrade tool.

* [FIX] Fix after review

* [FIX] Fix failing test
* [IMP] database/test: fetch auto-tags from runbot

* [REL] odev: version 4.28.0

* [FIX] tests: fix odev test and OdoobinMatch with auto-tags

* [REF] test: restore original argument order

* [REF] logging: revert log level regex fix
* Fix argparse greedy capture and misleading database warnings

* [FIX] Rescue positional values consumed by optional args after unknown flags, bump version

When using `parse_known_args` (for commands with `*...` nargs), argparse does not
know the arity of unknown flags. This caused values like `all` in `--without-demo all`
to be consumed by the `addons` optional positional instead of being passed through
to `odoo_args`. Detect and rescue such values by checking if the captured positional
value appears immediately after an unknown flag in the original argv.

Also bump __version__ to 4.28.1 to satisfy the version-bump CI check.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Refactor command instantiation into a dedicated _instantiate_command method.
- Move bypass_prompt reset from Command.__del__ to Odev.run_command cleanup for better reliability.
- Implement retry logic for git pull operations to handle transient race conditions.
- Improve Stash context manager to safely handle pop errors.
- Enhance TTLCache.__contains__ to respect entry expiration.
- Remove redundant shlex.quote from internal logging.
- Update .gitignore and .pre-commit-config.yaml.
Before this commit:
The restoration of a ZIP file with a dump and filestore would trigger 2 threads each restoring part of the archive.

This looks to cause concurrency on the zip archive reading, see:
#133
Which can theoretically be solved by opening another ZipFile object on the same archive (was tested experimentally locally and prove to be a solution).

However, opening 2 times the same archive is a bit overkilled and will scale poorly if other threads need the archive.

After this commit:
 1. Extract the archive once into a temporary folder
 2. Move the filestore folder (if any). Note: this is a very quick process, so there is no reason to thread this process

(like before):
 3. Restore the dump
 4. Neuter if there is no filestore
sea-odoo and others added 2 commits April 21, 2026 14:21
* [IMP] common: respect release channel during plugin installation

* [IMP] connectors/git: improve robustness and handle branch fallback during clone

This also fixes an infinite recursion in GitConnector when a path exists but is not a git repository, and addresses PR feedback by cloning the correct branch directly when possible.

* [FIX] common: clean up plugin installation branch logic

* ui: suppress progress spinners and logs in headless mode

* [FIX] common: differentiate headless mode from bypass prompt

* Introduce headless property to the Console class to better represent
non-interactive execution without decorative output.
* Update spinner to suppress logs based on headless rather than bypass_prompt,
which fixes test failures where bypass_prompt was incorrectly preventing
the output expected by the test assertions.
* Bump version to 4.29.1 to fix version-bump GitHub action check.

* chore: add debug logging to repository property

---------

Co-authored-by: Diag Test <diag@test.com>
* [IMP] various: centralize per-version pull interval logic

Introduce per-version tracking for repository pull dates to avoid
redundant daily network requests.

- Add get_date/set_date and interval logic to RepositoriesSection.
- Update PullCommand to verify timestamps before execution.
- Refactor OdoobinProcess to use version-specific pull schedules.

This ensures that odev pulls each Odoo version at most once per week
(resetting on Mondays) unless forced.

* [IMP] config: make repository pull interval configurable

Add repositories.interval setting (defaults to 7 days) to allow users to
customize how often odev pulls Odoo repositories in the background.

* [IMP] setup: add repository pull interval configuration to setup

Include the repositories.interval setting in the odev setup process,
allowing users to configure the background pull frequency during
initialization or reconfiguration.

* [IMP] config: refine pull interval logic with Monday alignment

Update next_pull_date to align with the start of the week (Monday) when
the interval allows, while ensuring the next pull is always scheduled
in the future. This keeps the weekly-on-Monday preference while
supporting any configurable interval duration.

---------

Co-authored-by: Diag Test <diag@test.com>
sea-odoo and others added 9 commits April 23, 2026 11:58
* [FIX] odoobin: fix AttributeError when addons is a list

The addons argument is defined as a List, but combined_odoo_args was
calling startswith() directly on the list object instead of its
elements.

Ensure we check the first element and join them back to a string when
needed to reconstruct the original Odoo option.

Assisted-by: gemini-3-flash <noreply@google.com>

* [IMP] odev: bump version to 4.29.2

Increment version number following the fix for the AttributeError in
odoobin.

Assisted-by: gemini-3-flash <noreply@google.com>
This commit:
- Simplifies README.md to a high-level overview.
- Points to the new odev.wiki for full command references and features.
- Reverts requirements and installation script changes.

Assisted-by: gemini-2.0-flash-exp <noreply@google.com>
…150)

* [IMP] various: implement sandbox log filtering and fix repo date logic

Add a token-efficient log filtering mechanism for the AI sandbox to suppress noisy HTTP logs and strip redundant metadata. This improves AI context clarity and reduces token usage. Also, fix RepositoriesSection.get_date to return a default epoch for new versions to ensure the initial pull logic works correctly.

Assisted-by: gemini-3-flash <noreply@google.com>

* [IMP] core: optimize odoo logs for AI sandbox and pretty-printing

- Robust ODOO_LOG_REGEX to handle aligned logs (multiple spaces).
- Suppress odoo-bin command and info messages in AI sandbox to save tokens.
- Remove redundant database name from pretty-printed logs.

Assisted-by: gemini-3-flash <noreply@google.com>

* [FIX] core: fix argument rescue logic for comma-separated lists

Fixed a bug where comma-separated lists (captured by 'addons' argument) were not correctly rescued from unknown flags, causing Odoo to misinterpret flags following '-i' as module names.

Assisted-by: gemini-3-flash <noreply@google.com>

* [IMP] skip self-update in AI sandbox

Assisted-by: Gemini 3 Flash <noreply@google.com>

* [FIX] various: fix flaky tests and improve sandbox filtering regex

- Fix duplicate test name test_16 in test_database.py
- Mock GitConnector in TestGitCommands to avoid real cloning and hangs
- Fix LOG_WERKZEUG_REGEX to handle standard Werkzeug logs
- Restore HOME_PATH in OdevTestCase.tearDownClass for better test isolation

Assisted-by: antigravity <noreply@google.com>

* refactor: make OdoobinProcess substitutable via odev.odoobin_process_class

- Add odoobin_process_class property to Odev with getter/setter
- Add should_skip_update() hook method to Odev (replaces direct AI_SANDBOX checks)
- Replace OdoobinProcess.run AI_SANDBOX checks with odev.should_skip_update()
- Add OdoobinProcess.get_stream_filter() as an overridable hook (returns None)
- Remove _ai_sandbox_filter from core OdoobinProcess (moved to plugin)
- Update all OdoobinProcess instantiation sites to use odev.odoobin_process_class

Assisted-by: claude-sonnet-4-5 <noreply@google.com>

* refactor: use _print_run_info() override instead of should_skip_update() in OdoobinProcess

Remove the odev.should_skip_update() call from OdoobinProcess.run — core stays
completely unaware of sandbox concepts. Instead, add an overridable
_print_run_info() that always prints by default; AI_OdoobinProcess overrides it
to be a no-op to save tokens inside the sandbox.

Assisted-by: claude-sonnet-4-5 <noreply@google.com>

* refactor: remove should_skip_update and all AI_SANDBOX references from core

Core odev now relies solely on ODEV_SKIP_GIT_UPDATE for update suppression,
leaving AI-specific behavior entirely to the plugin.

Assisted-by: claude-sonnet-4-5 <noreply@google.com>

* refactor: clean up update hooks and implement native stream filtering

- Revert check_release and rename __should_update_now to _should_update_now
- Implement native stream filtering in run_script (supporting None to skip)
- Move AI-specific sandbox logic entirely to the plugin via overrides
- Rename progress to stream_filter and update all call sites

Assisted-by: claude-sonnet-4-5 <noreply@google.com>

* [IMP] common: allow overriding OdoobinProcess class and improve plugin loading

- Add `_odoobin_process_class` to `OdevFrameworkMixin` for flexible Odoo process specialization.
- Refactor plugin loading to use direct imports and ensure `odev.plugins` namespace is correctly populated.
- Minor improvements to `OdoobinProcess` representation and output formatting.

Assisted-by: gemini-3-flash <noreply@google.com>

* [FIX] common: revert plugin path fallback and extra newline in run info

- Revert plugin path fallback logic in `plugins` property.
- Remove extra newline in `_print_run_info` to keep output compact.

Assisted-by: gemini-3-flash <noreply@google.com>

* [IMP] common: improve command run info display and restore spacing

- Use richer console output for the Odev run message.
- Restore the extra newline after the command for better readability.

Assisted-by: gemini-3-flash <noreply@google.com>

* [FIX] common: revert command run info display to fix tests\n\n- Restore logger.info for info_message to ensure tests can capture it\n- Remove custom rich styling and extra spacing\n\nAssisted-by: gemini-3-flash <noreply@google.com>
* [FIX] odev: sort help arguments and fix alignment

- Arguments in `odev help <command>` are now sorted alphabetically (positionals first, optionals next, greedy catch-all last).
- Fixed a long-standing alignment bug in the help output where the first line of an indented block (arguments, descriptions, command lists) was often double-indented or misaligned.
- Refactored `string.normalize_indent` to use `inspect.cleandoc` for more robust docstring handling.
- Unified indentation management in `HelpCommand` by using a consistent column-0 placeholder pattern.

Assisted-by: antigravity <noreply@google.com>

* fix: restore positional argument order and robust logging level parsing

- Fix positional argument sorting in base.py to preserve declaration order,
  preventing regressions in commands like 'restore'.
- Improve logging.py to avoid misinterpreting '-v' from tools like pytest
  as a log level.

Assisted-by: antigravity <noreply@google.com>

* [REF] common: move inspect import to top-level in string.py

Assisted-by: gemini-3-flash <noreply@google.com>
- Fix git requirements parsing when the package name is specified (pkg @ git+url).
- Improve RE_PACKAGE regex to support complex version strings (e.g. .post1, rc1).
- Add a warning for unnamed git requirements in requirements.txt.
- Cache the parsed installed packages to avoid redundant logs and processing.

Assisted-by: gemini-3-flash <noreply@google.com>
…154)

When a positional argument matches the name of a previous positional
argument (like the database name) and follows an unknown flag, argparse
incorrectly captures it. odev's rescue mechanism failed in this case
because it used list.index(), which returned the first occurrence.

This commit updates _rescue_positional_from_unknown_flag to check all
occurrences of the value in the original arguments list.

Assisted-by: gemini-3-flash <noreply@google.com>
* [FIX] odoobin: improve debugger detection and fix filtering logic

* [FIX] odoobin: check if addons paths exist before searching for debuggers
* [IMP] browsers: provision specific Chrome version for tours

This migrates the Chrome provisioning logic from odev-plugin-ai to odev.
When running tours (clic_all or tours tags), odev will now automatically:
1. Download a specific Chrome version (145.0.7632.116) if missing.
2. Use a wrapper script with optimized rendering flags for consistency.

Assisted-by: gemini-3-flash <noreply@google.com>

* [FIX] test: support 'click_all' tag for Chrome provisioning

* [IMP] browsers: fetch Chrome version dynamically from Runbot Dockerfile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants