Skip to content

Commit 5a1c9d7

Browse files
committed
feat: add --with flag to dbx project add for installing local clones
Adds a repeatable --with <repo-name> option to dbx project add. After normal project creation and auto-install, each named repo is looked up on disk via find_repo_by_name and installed as an editable package into the project venv. Warns and skips if a clone is not found locally. Examples: dbx project add myproject --with medical-records dbx project add myproject --with django --with django-mongodb-extensions
1 parent a655534 commit 5a1c9d7

1 file changed

Lines changed: 47 additions & 1 deletion

File tree

src/dbx_python_cli/commands/project.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import subprocess
77
import sys
88
from pathlib import Path
9-
from typing import Optional
9+
from typing import List, Optional
1010

1111
import typer
1212

@@ -248,6 +248,11 @@ def add_project(
248248
hidden=True,
249249
help="Override the Python executable used for django-admin (bypasses venv detection).",
250250
),
251+
with_repos: List[str] = typer.Option(
252+
[],
253+
"--with",
254+
help="Install a local clone into the project venv after creation (repeatable).",
255+
),
251256
):
252257
"""
253258
Create a new Django project using bundled templates.
@@ -269,6 +274,8 @@ def add_project(
269274
dbx project add -d ~/custom/path # Create with random name in custom directory
270275
dbx project add myproject -d ~/custom/path # Create in custom directory
271276
dbx project add myproject --base-dir ~/path/to/myproject # Create directly at path
277+
dbx project add myproject --with medical-records # Install a local clone
278+
dbx project add myproject --with django --with django-mongodb-extensions
272279
"""
273280
# Normalize parameters when called programmatically (not via CLI).
274281
# When called directly, typer.Option/Argument defaults are OptionInfo/ArgumentInfo objects.
@@ -288,6 +295,8 @@ def add_project(
288295
auto_install = True
289296
if not isinstance(python_path_override, (str, type(None))):
290297
python_path_override = None
298+
if not isinstance(with_repos, list):
299+
with_repos = []
291300

292301
# Determine project directory and name
293302
use_base_dir_override = False
@@ -581,6 +590,43 @@ def add_project(
581590
err=True,
582591
)
583592

593+
if with_repos:
594+
try:
595+
_install_with_repos(with_repos, python_path)
596+
except Exception as e:
597+
typer.echo(f"⚠️ --with install failed: {e}", err=True)
598+
599+
600+
def _install_with_repos(
601+
repo_names: List[str], python_path: str, verbose: bool = False
602+
) -> None:
603+
"""Install local clones into the project venv by name."""
604+
from dbx_python_cli.utils.repo import find_repo_by_name
605+
606+
config = get_config()
607+
base_dir = get_base_dir(config)
608+
for repo_name in repo_names:
609+
repo_info = find_repo_by_name(repo_name, base_dir, config)
610+
if not repo_info:
611+
typer.echo(
612+
f"⚠️ Clone '{repo_name}' not found locally — skipping.", err=True
613+
)
614+
continue
615+
clone_path = repo_info["path"]
616+
typer.echo(f"📦 Installing '{repo_name}' from local clone at {clone_path}...")
617+
result = install_package(
618+
clone_path,
619+
python_path,
620+
install_dir=None,
621+
extras=None,
622+
groups=None,
623+
verbose=verbose,
624+
)
625+
if result == "success":
626+
typer.echo(f"✅ '{repo_name}' installed")
627+
elif result == "failed":
628+
typer.echo(f"⚠️ Failed to install '{repo_name}'", err=True)
629+
584630

585631
def _create_venv(venv_path: Path) -> str:
586632
"""Create a venv with uv and return the python executable path."""

0 commit comments

Comments
 (0)