diff --git a/install.ps1 b/install.ps1 index b54b5de..7aeed2b 100644 --- a/install.ps1 +++ b/install.ps1 @@ -3,6 +3,9 @@ # Remote: # irm https://raven.evermind.ai/install.ps1 | iex # +# A piped run always installs the published release wheel, even from inside a +# clone. Set RAVEN_LOCAL_SRC= to force an editable install of a checkout. +# # Goal: a clean Windows machine ends up able to run `raven` / `raven tui` # without admin rights. The script is idempotent: it reuses existing tools when # available and only fills the gaps: @@ -223,10 +226,28 @@ function Resolve-RavenConstraints([string]$WheelUrl) { return $dest } +function Test-RavenSource([string]$Dir) { + if (-not $Dir) { return $false } + $pyproject = Join-Path $Dir "pyproject.toml" + return (Test-Path $pyproject) -and (Select-String -Path $pyproject -Pattern '^name = "raven"' -Quiet) +} + function Install-Raven([string]$UvPath, [string]$NodePath) { - $scriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { (Get-Location).Path } - $pyproject = Join-Path $scriptDir "pyproject.toml" - if ((Test-Path $pyproject) -and (Select-String -Path $pyproject -Pattern '^name = "raven"' -Quiet)) { + # $PSScriptRoot is set only when this script runs as a file. Piped through + # `irm ... | iex` it is empty, and falling back to the current directory + # turns a one-line install started from inside a clone into a silent + # editable install of that working tree. So local mode requires + # $PSScriptRoot; RAVEN_LOCAL_SRC is the explicit opt-in for a piped run. + $scriptDir = $null + if ($env:RAVEN_LOCAL_SRC) { + $resolved = Resolve-Path -LiteralPath $env:RAVEN_LOCAL_SRC -ErrorAction SilentlyContinue + if (-not $resolved) { Fail "RAVEN_LOCAL_SRC is not a directory: $($env:RAVEN_LOCAL_SRC)" } + $scriptDir = $resolved.Path + if (-not (Test-RavenSource $scriptDir)) { Fail "RAVEN_LOCAL_SRC is not a Raven source checkout: $scriptDir" } + } elseif ($PSScriptRoot -and (Test-RavenSource $PSScriptRoot)) { + $scriptDir = $PSScriptRoot + } + if ($scriptDir) { Write-Info "Detected local Raven source checkout; installing editable: $scriptDir" $entry = Join-Path $scriptDir "ui-tui\dist\entry.js" if (-not (Test-Path $entry)) { diff --git a/install.sh b/install.sh index 048ec4b..0f3bd5c 100755 --- a/install.sh +++ b/install.sh @@ -4,6 +4,9 @@ # Remote (website): curl -fsSL https://raven.evermind.ai/install.sh | sh # Local (dev clone): git clone ... && cd raven && ./install.sh # +# A piped run always installs the published release wheel, even from inside a +# clone. Set RAVEN_LOCAL_SRC= to force an editable install of a checkout. +# # Goal: a clean machine ends up able to run `raven` / `raven tui` from any # directory with no manual steps. The script is idempotent -- it detects what # is already present and only fills the gaps: @@ -146,11 +149,32 @@ ensure_node() { } # --- 3. install raven ------------------------------------------------------ +# True when $1 holds a raven source checkout (its own pyproject, not a dep's). +is_raven_source() { + [ -f "$1/pyproject.toml" ] && grep -q '^name = "raven"' "$1/pyproject.toml" 2>/dev/null +} + install_raven() { # Local mode: run from a raven source checkout -> editable install of the - # working tree (what a developer wants). Otherwise install from git. - script_dir="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" - if [ -f "$script_dir/pyproject.toml" ] && grep -q '^name = "raven"' "$script_dir/pyproject.toml" 2>/dev/null; then + # working tree (what a developer wants). Otherwise install the release wheel. + # + # "$0" names a real file only when this script runs as a file + # (./install.sh). Piped through `curl ... | sh` the script arrives on stdin, + # "$0" is "sh" and dirname "$0" is "." -- taking that as the source dir turns + # a one-line install started from inside a clone into a silent editable + # install of that working tree, whatever it happens to contain. So local mode + # requires "$0" to be a file; RAVEN_LOCAL_SRC is the explicit opt-in for a + # piped run. + script_dir="" + if [ -n "${RAVEN_LOCAL_SRC:-}" ]; then + script_dir="$(CDPATH= cd -- "$RAVEN_LOCAL_SRC" 2>/dev/null && pwd || true)" + [ -n "$script_dir" ] || die "RAVEN_LOCAL_SRC is not a directory: $RAVEN_LOCAL_SRC" + is_raven_source "$script_dir" || die "RAVEN_LOCAL_SRC is not a raven source checkout: $script_dir" + elif [ -f "$0" ]; then + script_dir="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" + is_raven_source "$script_dir" || script_dir="" + fi + if [ -n "$script_dir" ]; then info "Local raven source detected; editable install: $script_dir" # The TUI bundle must exist before first run. In a dev checkout it isn't # committed, so build it now if Node is available.