Skip to content

Commit 63d8e48

Browse files
committed
fix: extract project-dir detection into helpers to fix potential NameError
detected_paths was only assigned inside an `if project_dir_value` block but referenced outside it, risking a NameError. Extract detection logic into _detect_project_layout() and _resolve_odoo_dir_and_version() helpers, which also reduces create() complexity enough to remove noqa: C901.
1 parent 5a4cb9f commit 63d8e48

1 file changed

Lines changed: 68 additions & 34 deletions

File tree

odoo_venv/cli/main.py

Lines changed: 68 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,73 @@ def project_dir_callback(ctx: typer.Context, param: typer.CallbackParam, value:
5757
if not value:
5858
return None
5959

60-
# Auto-apply "project" preset if no preset was explicitly set
60+
# Auto-apply "project" preset if no preset was explicitly set.
61+
# --preset is also is_eager and declared before --project-dir, so if the user
62+
# passed --preset explicitly, ctx.default_map is already populated here.
6163
if not ctx.default_map:
6264
preset_callback(ctx, param, "project")
6365

6466
ctx.ensure_object(dict)["project_dir"] = value
6567
return value
6668

6769

70+
def _detect_project_layout(project_dir_value: str) -> tuple[Path | None, str | None, str | None]:
71+
"""Detect odoo_dir, odoo_version, and addons_path from a project directory.
72+
73+
Returns:
74+
(odoo_dir_path, odoo_version, addons_path) — any value may be None if not detected.
75+
"""
76+
project_dir_path = Path(project_dir_value).expanduser().resolve()
77+
detected_paths = detect_codebase_layout(project_dir_path)
78+
79+
addons_path = get_addons_path(project_dir_path, detected_paths=detected_paths)
80+
81+
# Resolve odoo_dir from detected layout
82+
odoo_dir_path = None
83+
if detected_paths.get("odoo_dir"):
84+
odoo_dir_path = detected_paths["odoo_dir"][0].parent
85+
86+
# Infer version from release.py inside the detected odoo dir
87+
odoo_version = None
88+
if odoo_dir_path:
89+
odoo_version = get_odoo_version_from_release(odoo_dir_path)
90+
91+
return odoo_dir_path, odoo_version, addons_path
92+
93+
94+
def _resolve_odoo_dir_and_version(
95+
odoo_dir: str | None,
96+
odoo_version: str | None,
97+
detected_odoo_dir: Path | None,
98+
detected_version: str | None,
99+
) -> tuple[Path, str]:
100+
"""Determine odoo_dir and odoo_version from explicit args or detected values.
101+
102+
Priority: explicit CLI flags > auto-detected from --project-dir > default path.
103+
Exits with an error if neither can be resolved.
104+
"""
105+
# Resolve odoo_dir: explicit flag > detected > default path from version
106+
if odoo_dir:
107+
odoo_dir_path = Path(odoo_dir).expanduser().resolve()
108+
elif detected_odoo_dir:
109+
odoo_dir_path = detected_odoo_dir
110+
elif odoo_version:
111+
odoo_dir_path = Path(f"~/code/odoo/odoo/{odoo_version}").expanduser()
112+
else:
113+
typer.secho("error: ODOO_VERSION is required when --project-dir is not used.", fg=typer.colors.RED)
114+
raise typer.Exit(1)
115+
116+
# Resolve odoo_version: explicit arg > detected from release.py
117+
resolved_version = odoo_version or detected_version
118+
if not resolved_version:
119+
typer.secho(
120+
"error: Could not detect Odoo version from source. Provide ODOO_VERSION explicitly.", fg=typer.colors.RED
121+
)
122+
raise typer.Exit(1)
123+
124+
return odoo_dir_path, resolved_version
125+
126+
68127
def version_callback(value: bool):
69128
if value:
70129
typer.echo(f"odoo-venv {version('odoo-venv')}")
@@ -88,7 +147,7 @@ def main_callback(
88147

89148

90149
@app.command()
91-
def create( # noqa: C901
150+
def create(
92151
ctx: typer.Context,
93152
odoo_version: Annotated[
94153
str | None, typer.Argument(help="Odoo version, e.g: 18.0. Inferred from --project-dir if omitted.")
@@ -185,40 +244,15 @@ def create( # noqa: C901
185244
] = None,
186245
):
187246
"""Create virtual environment to run Odoo"""
188-
# Handle --project-dir: auto-detect addons_path and odoo_dir
247+
# Auto-detect layout from --project-dir if provided
189248
project_dir_value = ctx.obj.get("project_dir") if ctx.obj else None
190-
detected_addons_path = None
191-
if project_dir_value:
192-
project_dir_path = Path(project_dir_value).expanduser().resolve()
193-
detected_paths = detect_codebase_layout(project_dir_path)
194-
detected_addons_path = get_addons_path(
195-
project_dir_path,
196-
detected_paths=detected_paths,
197-
)
198-
199-
# Resolve odoo_dir (before odoo_version, which may be inferred from it)
200-
if odoo_dir:
201-
odoo_dir_path = Path(odoo_dir).expanduser().resolve()
202-
elif project_dir_value and detected_paths.get("odoo_dir"):
203-
odoo_dir_path = detected_paths["odoo_dir"][0].parent
204-
elif odoo_version:
205-
odoo_dir_path = Path(f"~/code/odoo/odoo/{odoo_version}").expanduser()
206-
else:
207-
typer.secho(
208-
"error: ODOO_VERSION is required when --project-dir is not used.",
209-
fg=typer.colors.RED,
210-
)
211-
raise typer.Exit(1)
249+
detected_odoo_dir, detected_version, detected_addons_path = (
250+
_detect_project_layout(project_dir_value) if project_dir_value else (None, None, None)
251+
)
212252

213-
# Infer odoo_version from release.py if not provided
214-
if not odoo_version:
215-
odoo_version = get_odoo_version_from_release(odoo_dir_path)
216-
if not odoo_version:
217-
typer.secho(
218-
"error: Could not detect Odoo version from source. Provide ODOO_VERSION explicitly.",
219-
fg=typer.colors.RED,
220-
)
221-
raise typer.Exit(1)
253+
odoo_dir_path, odoo_version = _resolve_odoo_dir_and_version(
254+
odoo_dir, odoo_version, detected_odoo_dir, detected_version
255+
)
222256

223257
if not python_version:
224258
python_version = ODOO_PYTHON_VERSIONS.get(odoo_version)

0 commit comments

Comments
 (0)