From a6a5f8e1b7747a82e7b6c86976700a04001f3484 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Wed, 13 May 2026 10:30:37 -0700 Subject: [PATCH 1/6] add argument allowing specification of local wheel dependencies --- riot/cli.py | 10 ++++++++-- riot/runner.py | 10 ++++++---- riot/session.py | 6 ++++-- riot/venv.py | 9 +++++---- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/riot/cli.py b/riot/cli.py index 525be90..4ad9065 100644 --- a/riot/cli.py +++ b/riot/cli.py @@ -31,6 +31,7 @@ def convert(self, value, param, ctx): PATTERN_ARG = click.argument("pattern", envvar="RIOT_PATTERN", default=r".*") VENV_PATTERN_ARG = click.option("--venv-pattern", "venv_pattern", default=r".*") +WHEEL_PATH_ARG = click.option("--wheel-path", "wheel_path", default=r"") RECREATE_VENVS_ARG = click.option( "-r", "--recreate-venvs", @@ -151,7 +152,8 @@ def list_venvs(ctx, pythons, pattern, venv_pattern, interpreters, hash_only): ) -@main.command(help="""Generate base virtual environments. +@main.command( + help="""Generate base virtual environments. A base virtual environment is a virtual environment with the local package installed. @@ -160,7 +162,8 @@ def list_venvs(ctx, pythons, pattern, venv_pattern, interpreters, hash_only): having to reinstall the local package repeatedly. Once the base virtual environments are built, the ``--skip-base-install`` option -can be used for the run command to avoid having to install the local package.""") +can be used for the run command to avoid having to install the local package.""" +) @RECREATE_VENVS_ARG @SKIP_BASE_INSTALL_ARG @PYTHON_VERSIONS_ARG @@ -188,6 +191,7 @@ def generate(ctx, recreate_venvs, skip_base_install, pythons, pattern): @PATTERN_ARG @VENV_PATTERN_ARG @RECOMPILE_REQS_ARG +@WHEEL_PATH_ARG @click.pass_context def run( ctx, @@ -200,6 +204,7 @@ def run( pattern, venv_pattern, recompile_reqs, + wheel_path, ): ctx.obj["session"].run( pattern=re.compile(pattern), @@ -212,6 +217,7 @@ def run( skip_missing=skip_missing, exit_first=exit_first, recompile_reqs=recompile_reqs, + wheel_path=wheel_path, ) diff --git a/riot/runner.py b/riot/runner.py index d5abec8..cda8e8d 100644 --- a/riot/runner.py +++ b/riot/runner.py @@ -1,11 +1,11 @@ import logging import os -from pathlib import Path import subprocess import sys import typing as t +from pathlib import Path -from .constants import _T_CompletedProcess, _T_stdio, ENCODING, SHELL +from .constants import ENCODING, SHELL, _T_CompletedProcess, _T_stdio from .exceptions import CmdFailure logger = logging.getLogger(__name__) @@ -86,7 +86,7 @@ def run_cmd_venv( return run_cmd(args, stdout=stdout, executable=executable, env=env, shell=True) -def install_dev_pkg(venv_path: str, force: bool = False) -> None: +def install_dev_pkg(venv_path: str, wheel_path: str, force: bool = False) -> None: dev_pkg_lockfile = Path(venv_path) / ".riot-dev-pkg-installed" if dev_pkg_lockfile.exists() and not force: logger.info("Dev package already installed. Skipping.") @@ -99,11 +99,13 @@ def install_dev_pkg(venv_path: str, force: bool = False) -> None: logger.warning("No Python setup file found. Skipping dev package installation.") return + find_links_flag = f"--find-links {wheel_path}" if wheel_path else "" + logger.info("Installing dev package (edit mode) in %s.", venv_path) try: run_cmd_venv( venv_path, - "pip --disable-pip-version-check install -e .", + f"pip --disable-pip-version-check install {find_links_flag} -e .", env=dict(os.environ), ) dev_pkg_lockfile.touch() diff --git a/riot/session.py b/riot/session.py index 56c20ca..32ef95d 100644 --- a/riot/session.py +++ b/riot/session.py @@ -9,8 +9,8 @@ import typing as t import click -from packaging.version import Version import pexpect +from packaging.version import Version from rich import print as rich_print from rich.pretty import Pretty from rich.status import Status @@ -21,7 +21,7 @@ from .interpreter import Interpreter from .runner import install_dev_pkg, run_cmd_venv from .utils import env_to_str -from .venv import nspkgs, Venv, VenvInstanceResult +from .venv import Venv, VenvInstanceResult, nspkgs logger = logging.getLogger(__name__) @@ -78,6 +78,7 @@ def run( skip_missing: bool = False, exit_first: bool = False, recompile_reqs: bool = False, + wheel_path: str = "", ) -> None: results = [] @@ -153,6 +154,7 @@ def run( skip_deps=skip_base_install or inst.venv.skip_dev_install, recreate=recreate_venvs, recompile_reqs=recompile_reqs, + wheel_path=wheel_path, ) pythonpath = inst.pythonpath diff --git a/riot/venv.py b/riot/venv.py index ecb4db5..23b8fab 100644 --- a/riot/venv.py +++ b/riot/venv.py @@ -1,13 +1,13 @@ -from contextlib import contextmanager import dataclasses import functools -from hashlib import sha256 import logging import os -from pathlib import Path import shutil import subprocess import typing as t +from contextlib import contextmanager +from hashlib import sha256 +from pathlib import Path from .constants import DEFAULT_RIOT_PATH from .exceptions import CmdFailure @@ -412,6 +412,7 @@ def prepare( skip_deps: bool = False, recompile_reqs: bool = False, child_was_installed: bool = False, + wheel_path: str = "", ) -> None: # Propagate the interpreter down the parenting relation self.py = py = py or self.py @@ -435,7 +436,7 @@ def prepare( if self.created: py.create_venv(recreate, venv_path) if not (self.venv.skip_dev_install or skip_deps): - install_dev_pkg(venv_path, force=True) + install_dev_pkg(venv_path, wheel_path, force=True) pkg_str = self.pkg_str compiled_requirements_file = ( From 94010b0245dd971b5c6b15a545a4048ff742b0b9 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Wed, 13 May 2026 10:44:01 -0700 Subject: [PATCH 2/6] add argument to generate command --- riot/cli.py | 2 ++ riot/session.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/riot/cli.py b/riot/cli.py index 4ad9065..2894373 100644 --- a/riot/cli.py +++ b/riot/cli.py @@ -168,6 +168,7 @@ def list_venvs(ctx, pythons, pattern, venv_pattern, interpreters, hash_only): @SKIP_BASE_INSTALL_ARG @PYTHON_VERSIONS_ARG @PATTERN_ARG +@WHEEL_PATH_ARG @click.pass_context def generate(ctx, recreate_venvs, skip_base_install, pythons, pattern): ctx.obj["session"].generate_base_venvs( @@ -175,6 +176,7 @@ def generate(ctx, recreate_venvs, skip_base_install, pythons, pattern): recreate=recreate_venvs, skip_deps=skip_base_install, pythons=pythons, + wheel_path=wheel_path, ) diff --git a/riot/session.py b/riot/session.py index 32ef95d..263b803 100644 --- a/riot/session.py +++ b/riot/session.py @@ -318,6 +318,7 @@ def generate_base_venvs( recreate: bool, skip_deps: bool, pythons: t.Optional[t.Set[Interpreter]], + wheel_path: str, ) -> None: """Generate all the required base venvs.""" # Find all the python interpreters used. @@ -354,7 +355,7 @@ def generate_base_venvs( continue # Install the dev package into the base venv. - install_dev_pkg(py.venv_path, force=True) + install_dev_pkg(py.venv_path, wheel_path, force=True) def _venvs_matching_identifier(self, identifier): for n, inst in enumerate(self.venv.instances()): From ccb23843b6472c6d48e215db76d6bc40637caa97 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Fri, 15 May 2026 07:20:24 -0700 Subject: [PATCH 3/6] forgot arg --- riot/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/riot/cli.py b/riot/cli.py index 2894373..5772e54 100644 --- a/riot/cli.py +++ b/riot/cli.py @@ -170,7 +170,7 @@ def list_venvs(ctx, pythons, pattern, venv_pattern, interpreters, hash_only): @PATTERN_ARG @WHEEL_PATH_ARG @click.pass_context -def generate(ctx, recreate_venvs, skip_base_install, pythons, pattern): +def generate(ctx, recreate_venvs, skip_base_install, pythons, pattern, wheel_path): ctx.obj["session"].generate_base_venvs( pattern=re.compile(pattern), recreate=recreate_venvs, From b67fb181bea23fe6be415a0c47f82a5c222b4d4b Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Fri, 15 May 2026 11:07:43 -0700 Subject: [PATCH 4/6] missing argument --- riot/session.py | 1 + 1 file changed, 1 insertion(+) diff --git a/riot/session.py b/riot/session.py index 263b803..ab9873c 100644 --- a/riot/session.py +++ b/riot/session.py @@ -87,6 +87,7 @@ def run( recreate=recreate_venvs, skip_deps=skip_base_install, pythons=pythons, + wheel_path=wheel_path, ) for inst in self.venv.instances(): From e94da0009ffa6af32a8eea329b4467f0d40c9cb9 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Wed, 20 May 2026 17:04:07 -0700 Subject: [PATCH 5/6] flake --- riot/cli.py | 3 --- riot/runner.py | 4 ++-- riot/session.py | 4 ++-- riot/venv.py | 6 +++--- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/riot/cli.py b/riot/cli.py index 75348ac..0e480a1 100644 --- a/riot/cli.py +++ b/riot/cli.py @@ -31,7 +31,6 @@ def convert(self, value, param, ctx): PATTERN_ARG = click.argument("pattern", envvar="RIOT_PATTERN", default=r".*") VENV_PATTERN_ARG = click.option("--venv-pattern", "venv_pattern", default=r".*") -WHEEL_PATH_ARG = click.option("--wheel-path", "wheel_path", default=r"") RECREATE_VENVS_ARG = click.option( "-r", "--recreate-venvs", @@ -202,7 +201,6 @@ def generate(ctx, recreate_venvs, skip_base_install, pythons, pattern): @PATTERN_ARG @VENV_PATTERN_ARG @RECOMPILE_REQS_ARG -@WHEEL_PATH_ARG @click.pass_context def run( ctx, @@ -215,7 +213,6 @@ def run( pattern, venv_pattern, recompile_reqs, - wheel_path, ): wheel_path = ctx.obj.get("wheel_path") ctx.obj["session"].run( diff --git a/riot/runner.py b/riot/runner.py index 9665c9d..5ef4599 100644 --- a/riot/runner.py +++ b/riot/runner.py @@ -1,12 +1,12 @@ import logging import os +from pathlib import Path import subprocess import sys import tempfile import typing as t -from pathlib import Path -from .constants import ENCODING, SHELL, _T_CompletedProcess, _T_stdio +from .constants import _T_CompletedProcess, _T_stdio, ENCODING, SHELL from .exceptions import CmdFailure logger = logging.getLogger(__name__) diff --git a/riot/session.py b/riot/session.py index 08706e0..3b77dba 100644 --- a/riot/session.py +++ b/riot/session.py @@ -9,8 +9,8 @@ import typing as t import click -import pexpect from packaging.version import Version +import pexpect from rich import print as rich_print from rich.pretty import Pretty from rich.status import Status @@ -21,7 +21,7 @@ from .interpreter import Interpreter from .runner import install_dev_pkg, run_cmd_venv from .utils import env_to_str -from .venv import Venv, VenvInstanceResult, nspkgs +from .venv import nspkgs, Venv, VenvInstanceResult logger = logging.getLogger(__name__) diff --git a/riot/venv.py b/riot/venv.py index b7ff722..524e5ae 100644 --- a/riot/venv.py +++ b/riot/venv.py @@ -1,13 +1,13 @@ +from contextlib import contextmanager import dataclasses import functools +from hashlib import sha256 import logging import os +from pathlib import Path import shutil import subprocess import typing as t -from contextlib import contextmanager -from hashlib import sha256 -from pathlib import Path from .constants import DEFAULT_RIOT_PATH from .exceptions import CmdFailure From 49e9f528ff1b6e724abdd48c911fc08c41360984 Mon Sep 17 00:00:00 2001 From: Emmett Butler Date: Wed, 20 May 2026 17:05:05 -0700 Subject: [PATCH 6/6] undo --- riot/cli.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/riot/cli.py b/riot/cli.py index 0e480a1..b9c426e 100644 --- a/riot/cli.py +++ b/riot/cli.py @@ -160,8 +160,7 @@ def list_venvs(ctx, pythons, pattern, venv_pattern, interpreters, hash_only): ) -@main.command( - help="""Generate base virtual environments. +@main.command(help="""Generate base virtual environments. A base virtual environment is a virtual environment with the local package installed. @@ -170,8 +169,7 @@ def list_venvs(ctx, pythons, pattern, venv_pattern, interpreters, hash_only): having to reinstall the local package repeatedly. Once the base virtual environments are built, the ``--skip-base-install`` option -can be used for the run command to avoid having to install the local package.""" -) +can be used for the run command to avoid having to install the local package.""") @RECREATE_VENVS_ARG @SKIP_BASE_INSTALL_ARG @PYTHON_VERSIONS_ARG