diff --git a/scripts/bootstrap.ps1 b/scripts/bootstrap.ps1 index 4675793..538bafd 100644 --- a/scripts/bootstrap.ps1 +++ b/scripts/bootstrap.ps1 @@ -181,50 +181,24 @@ if (-not $NoInstall) { & $venvPython -c "import importlib; importlib.import_module('CLI')" 2>$null if ($LASTEXITCODE -eq 0) { Write-Log "Top-level 'CLI' is importable in the venv." } else { - Write-Log "Top-level 'CLI' not importable; attempting to add repo root to venv site-packages via .pth" "INFO" - $sites = Get-SitePackages -python $venvPython - $siteDir = $sites | Where-Object { Test-Path $_ } | Select-Object -First 1 - if ($siteDir) { - $pth = Join-Path $siteDir 'medeia_repo.pth' - if (Test-Path $pth) { - if (-not (Select-String -Path $pth -Pattern ([regex]::Escape($repoRoot)) -Quiet)) { - Add-Content -Path $pth -Value $repoRoot - Write-Log "Appended repo root to existing .pth: $pth" "INFO" - } else { - Write-Log ".pth already contains repo root: $pth" "INFO" - } - } else { - Set-Content -LiteralPath $pth -Value $repoRoot -Encoding UTF8 - Write-Log "Wrote .pth adding repo root to venv site-packages: $pth" "INFO" - } + Write-Log "Top-level 'CLI' not importable; writing venv site-packages .pth pointing at repo root..." "INFO" - # Re-check import - & $venvPython -c "import importlib; importlib.import_module('CLI')" 2>$null - if ($LASTEXITCODE -eq 0) { - Write-Log "Top-level 'CLI' import works after adding .pth" "INFO" - } else { - Write-Log "Adding .pth did not make top-level 'CLI' importable." "ERROR" - if ($Editable) { - Write-Log "Editable install already requested; attempting editable reinstall for good measure..." "INFO" - try { & $venvPython -m pip install -e . } catch { Write-Log "Editable reinstall failed: $_" "ERROR"; exit 6 } - & $venvPython -c "import importlib; importlib.import_module('CLI')" 2>$null - if ($LASTEXITCODE -eq 0) { Write-Log "Top-level 'CLI' is now importable after reinstall." "INFO" } - else { Write-Log "Editable reinstall did not make 'CLI' importable; inspect the venv or create an egg-link manually." "ERROR"; exit 6 } - } else { - if (-not $Quiet) { - $ans = Read-Host "Top-level 'CLI' not importable; install project in editable mode now? (Y/n)" - if ($ans -eq 'y' -or $ans -eq 'Y') { try { & $venvPython -m pip install -e . } catch { Write-Log "Editable install failed: $_" "ERROR"; exit 6 } } - else { Write-Log "Warning: continuing without top-level 'CLI' importable; some entrypoints may fail." "ERROR" } - } else { Write-Log "Top-level 'CLI' not importable and cannot prompt (quiet mode); aborting." "ERROR"; exit 6 } - } - } + $siteDir = (& $venvPython -c "import sysconfig; print(sysconfig.get_paths().get('purelib',''))" 2>$null).Trim() + if (-not $siteDir -or -not (Test-Path $siteDir)) { + Write-Log "ERROR: unable to determine venv site-packages directory (purelib='$siteDir'); aborting." "ERROR" + exit 6 + } + + $pth = Join-Path $siteDir 'medeia_repo.pth' + Set-Content -LiteralPath $pth -Value $repoRoot -Encoding UTF8 + Write-Log "Wrote .pth adding repo root to venv site-packages: $pth" "INFO" + + & $venvPython -c "import importlib; importlib.import_module('CLI')" 2>$null + if ($LASTEXITCODE -eq 0) { + Write-Log "OK: top-level 'CLI' is now importable (after .pth)." "INFO" } else { - Write-Log "Unable to determine site-packages to write .pth; falling back to editable install prompt" "WARNING" - if ($Editable) { try { & $venvPython -m pip install -e . } catch { Write-Log "Editable install failed: $_" "ERROR"; exit 6 } } - elseif (-not $Quiet) { - $ans = Read-Host "Top-level 'CLI' not importable; install project in editable mode now? (Y/n)" - if ($ans -eq 'y' -or $ans -eq 'Y') { try { & $venvPython -m pip install -e . } catch { Write-Log "Editable install failed: $_" "ERROR"; exit 6 } } - } else { Write-Log "Top-level 'CLI' not importable and cannot prompt (quiet mode); aborting." "ERROR"; exit 6 } + Write-Log "ERROR: top-level 'CLI' still not importable after writing .pth ($pth); aborting." "ERROR" + exit 6 } } } catch { diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh index 65d94c8..aecf8bb 100644 --- a/scripts/bootstrap.sh +++ b/scripts/bootstrap.sh @@ -282,127 +282,43 @@ if [[ "$NOINSTALL" != "true" ]]; then # If not explicitly requested, auto-selec if "$VENV_PY" -c 'import importlib; importlib.import_module("medeia_macina.cli_entry")' >/dev/null 2>&1; then echo "OK: 'medeia_macina.cli_entry' is importable in the venv." - # Additional compatibility check: top-level 'CLI' module may be required by - # older entrypoints or direct imports when running from a development checkout. - if ! "$VENV_PY" -c 'import importlib,sys; importlib.import_module("CLI")' >/dev/null 2>&1; then - echo "Note: top-level 'CLI' module not importable; attempting to add the repo root to venv site-packages via a .pth file so top-level imports work." >&2 + # Ensure the top-level 'CLI' module is importable (required by legacy entrypoints). + # For PEP 660 editable installs, create a small .pth in the venv site-packages + # pointing at the repo root so `import CLI` works from any working directory. + if ! "$VENV_PY" -c 'import importlib; importlib.import_module("CLI")' >/dev/null 2>&1; then + echo "Top-level 'CLI' not importable; writing venv site-packages .pth pointing at repo root..." >&2 - # Try to discover venv site-packages and write a .pth pointing at the repo root - site_pkgs=$("$VENV_PY" - <<'PY' -import site, sysconfig -out=[] + site_pkg_dir=$("$VENV_PY" - <<'PY' +import os, site, sysconfig +candidates = [] try: - out.extend(site.getsitepackages()) + candidates.append(sysconfig.get_paths().get('purelib')) except Exception: pass try: - p = sysconfig.get_paths().get('purelib') - if p: - out.append(p) + candidates.extend(site.getsitepackages()) except Exception: pass -seen=set(); res=[] -for x in out: - if x and x not in seen: - seen.add(x); res.append(x) -for s in res: - print(s) +for p in candidates: + if p and os.path.isdir(p): + print(p) + break PY ) - site_pkg_dir="" - while IFS= read -r sp; do - if [[ -d "$sp" ]]; then site_pkg_dir="$sp"; break; fi - done <<< "$site_pkgs" - if [[ -n "$site_pkg_dir" ]]; then - pth_file="$site_pkg_dir/medeia_repo.pth" - if [[ -f "$pth_file" ]]; then - if grep -qxF "$REPO" "$pth_file" >/dev/null 2>&1; then - echo ".pth already present and contains repo root: $pth_file" >&2 - else - echo "$REPO" >> "$pth_file" - echo "Appended repo root to existing .pth: $pth_file" >&2 - fi - else - echo "$REPO" > "$pth_file" - echo "Wrote .pth adding repo root to venv site-packages: $pth_file" >&2 - fi - - # Re-check whether 'CLI' is now importable - if "$VENV_PY" -c 'import importlib,sys; importlib.import_module("CLI")' >/dev/null 2>&1; then - echo "Top-level 'CLI' import works after adding .pth" >&2 - else - echo "Adding .pth did not make top-level 'CLI' importable." >&2 - - # Fallback: if this is a git checkout, try editable reinstall or prompt user - if [[ -d "$REPO/.git" ]] || git -C "$REPO" rev-parse --is-inside-work-tree >/dev/null 2>&1; then - if [[ "$EDITABLE" == "true" ]]; then - echo "Editable install already requested; attempting editable reinstall for good measure..." >&2 - "$VENV_PY" -m pip install -e "$REPO" || { echo "Editable install failed" >&2; exit 6; } - if "$VENV_PY" -c 'import importlib,sys; importlib.import_module("CLI")' >/dev/null 2>&1; then - echo "Top-level 'CLI' is now importable after reinstall." >&2 - else - echo "Editable reinstall did not make 'CLI' importable. Please inspect the venv or create an egg-link." >&2 - exit 6 - fi - else - if [[ "$QUIET" != "true" && -t 0 ]]; then - read -p "Top-level 'CLI' not importable; install project in editable mode now? (Y/n) " devans2 - if [[ -z "$devans2" || "$devans2" == "y" || "$devans2" == "Y" ]]; then - "$VENV_PY" -m pip install -e "$REPO" || { echo "Editable install failed" >&2; exit 6; } - else - echo "Warning: continuing without top-level 'CLI' importable; some entrypoints may fail." >&2 - fi - else - echo "Top-level 'CLI' not importable and cannot prompt (quiet mode); aborting." >&2 - exit 6 - fi - fi - else - echo "Top-level 'CLI' not importable and not a git checkout; continuing at your own risk." >&2 - fi - fi - else - echo "Unable to determine site-packages directory to write .pth; skipping .pth fallback." >&2 - if [[ -d "$REPO/.git" ]] || git -C "$REPO" rev-parse --is-inside-work-tree >/dev/null 2>&1; then - if [[ "$EDITABLE" == "true" ]]; then - echo "Attempting editable install to provide top-level 'CLI'..." - "$VENV_PY" -m pip install -e "$REPO" || { echo "Editable install failed" >&2; exit 6; } - else - if [[ "$QUIET" != "true" && -t 0 ]]; then - read -p "Top-level 'CLI' not importable; install project in editable mode now? (Y/n) " devans2 - if [[ -z "$devans2" || "$devans2" == "y" || "$devans2" == "Y" ]]; then - "$VENV_PY" -m pip install -e "$REPO" || { echo "Editable install failed" >&2; exit 6; } - else - echo "Warning: continuing without top-level 'CLI' importable; some entrypoints may fail." >&2 - fi - else - echo "Top-level 'CLI' not importable and cannot prompt (quiet mode); aborting." >&2 - exit 6 - fi - fi - else - echo "Top-level 'CLI' not importable and not a git checkout; continuing." >&2 - fi + if [[ -z "${site_pkg_dir:-}" || ! -d "${site_pkg_dir:-}" ]]; then + echo "ERROR: unable to determine venv site-packages directory to write .pth; aborting." >&2 + exit 6 fi - fi - echo "Continuing without editable install; 'mm' may not work as expected." >&2 - fi - else - echo "Top-level 'CLI' not found and not interactive; re-run bootstrap with --editable or run: $VENV_PY -m pip install -e ." >&2 - exit 6 - fi - fi - # Re-check after editable install - if "$VENV_PY" -c 'import importlib; importlib.import_module("CLI")' >/dev/null 2>&1; then - echo "Success: top-level 'CLI' now importable." >&2 - else - echo "ERROR: top-level 'CLI' still not importable after editable install; aborting." >&2 - exit 6 - fi + pth_file="$site_pkg_dir/medeia_repo.pth" + printf "%s\n" "$REPO" > "$pth_file" + + if "$VENV_PY" -c 'import importlib; importlib.import_module("CLI")' >/dev/null 2>&1; then + echo "OK: top-level 'CLI' is now importable (after .pth)." >&2 else - echo "Note: not a development checkout (no .git) — if you need top-level 'CLI' run: $VENV_PY -m pip install -e ." >&2 + echo "ERROR: top-level 'CLI' still not importable after writing .pth ($pth_file)." >&2 + exit 6 fi fi diff --git a/scripts/setup.py b/scripts/setup.py index 9c836e6..2d09b23 100644 --- a/scripts/setup.py +++ b/scripts/setup.py @@ -249,8 +249,8 @@ def main() -> int: out = _sub.check_output(cmd, text=True).strip().splitlines() site_dir = None for sp in out: - if sp and _Path(sp).exists(): - site_dir = _Path(sp) + if sp and Path(sp).exists(): + site_dir = Path(sp) break if site_dir is None: print("Could not determine venv site-packages directory; skipping .pth fallback")