Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ If you need to pass arguments that look like options for `idae` to the script yo
```python
# script.py
import sys

print(" ".join(sys.argv[1:]))
```

Expand Down
14 changes: 12 additions & 2 deletions idae/cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""CLI interface."""

import itertools
import platform
import shlex
Expand All @@ -15,7 +16,7 @@

from idae.pep723 import read
from idae.resolver import get_python_or_exit
from idae.venv import Python, clean_venvs, get_venv
from idae.venv import IDAE_VENV_DIR_NAME, Python, clean_venvs, get_venv

if sys.version_info < (3, 9): # pragma: no cover
from typing_extensions import Annotated
Expand Down Expand Up @@ -71,6 +72,15 @@ def run( # noqa: PLR0913
help="Force idae to use a specific Python version",
),
] = None,
in_cwd: Annotated[
bool,
typer.Option(
"--in-cwd",
"-c",
help=f"Create the venv in a {IDAE_VENV_DIR_NAME} in the current "
"working directory",
),
] = False,
) -> None:
"""Automatically install necessary dependencies to run a Python script.

Expand Down Expand Up @@ -108,7 +118,7 @@ def run( # noqa: PLR0913
):
python = get_python_or_exit(pyproject["requires-python"], console)

venv_path = get_venv(script_deps, python)
venv_path = get_venv(script_deps, python, Path.cwd() if in_cwd else None)

extra_flags = list(
itertools.chain.from_iterable(
Expand Down
15 changes: 13 additions & 2 deletions idae/venv.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Utils for venv creation."""

from __future__ import annotations

import platform
Expand All @@ -19,6 +20,7 @@
from .dependencies import hash_dependencies

CACHE_DIR = platformdirs.user_cache_path("idae")
IDAE_VENV_DIR_NAME = ".idae"


@dataclass
Expand All @@ -29,10 +31,19 @@ class Python:
executable: str | PathLike[str]


def get_venv(requirements: list[Requirement], python: Python) -> Path:
def get_venv(
requirements: list[Requirement],
python: Python,
in_dir: PathLike | None = None,
venv_name: str = IDAE_VENV_DIR_NAME,
) -> Path:
"""Create or fetch a cached venv."""
dep_hash = hash_dependencies(requirements)
venv_path = CACHE_DIR / f"{python.version.major}.{python.version.minor}" / dep_hash
venv_path = (
(in_dir / venv_name if in_dir is not None else CACHE_DIR)
/ f"{python.version.major}.{python.version.minor}"
/ dep_hash
)
if venv_path.is_dir():
return venv_path
# This automatically includes pip
Expand Down
Loading