Fix install.ps1 crash when piped through iex and render in PowerShell 5.1 - #2
Conversation
Three bugs surfaced by running the one-liner installer in stock Windows PowerShell 5.1: 1. $PSScriptRoot is empty when the script is piped through Invoke-Expression (iwr ... | iex), so `Join-Path $PSScriptRoot 'rust\Cargo.toml'` threw 'Cannot bind argument to parameter Path because it is an empty string' right after 'Building from source...'. Introduce a Get-LocalCheckoutDir helper that falls back to $PSCommandPath and $MyInvocation.MyCommand.Path and finally returns $null. The source-build branch now treats $null as 'no local checkout' and skips straight to the user-scope git clone. 2. The backtick-e escape (`e) is only an ESC literal in PowerShell 6+. In Windows PowerShell 5.1 it's just the character 'e', which is why the user saw literal 'e[38;2;0;255;65m' in the output instead of green text. Replace with $ESC = [char]27 so ANSI sequences render on 5.1 too. 3. Box-drawing glyphs printed as '?' on the user's terminal because the default OEM code page can't represent them. Set [Console]::OutputEncoding to UTF-8 early in the script (wrapped in try/catch in case the host forbids it). Co-Authored-By: jacob levesque <jaemlev@icloud.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
| git -C $SrcDir fetch --quiet origin 2>$null | Out-Null | ||
| git -C $SrcDir reset --quiet --hard origin/HEAD 2>$null | Out-Null |
There was a problem hiding this comment.
🟡 Missing error check after git fetch / git reset allows silent build from stale source
The new git fetch + git reset --hard origin/HEAD path (lines 226-227) suppresses all output and stderr (2>$null | Out-Null) but never checks $LASTEXITCODE. If git fetch fails (e.g., network error), git reset --hard origin/HEAD will silently succeed by resetting to whatever was last fetched — potentially very outdated code. The script then proceeds to build and install that stale version without any warning. This is inconsistent with the git clone path at install.ps1:232-234, where $LASTEXITCODE is properly checked and an error is thrown on failure.
| git -C $SrcDir fetch --quiet origin 2>$null | Out-Null | |
| git -C $SrcDir reset --quiet --hard origin/HEAD 2>$null | Out-Null | |
| git -C $SrcDir fetch --quiet origin 2>$null | Out-Null | |
| if ($LASTEXITCODE -ne 0) { | |
| Info "git fetch failed (exit code $LASTEXITCODE); building from existing checkout" | |
| } | |
| git -C $SrcDir reset --quiet --hard origin/HEAD 2>$null | Out-Null | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "git reset failed with exit code $LASTEXITCODE" | |
| } |
Was this helpful? React with 👍 or 👎 to provide feedback.
Addresses Devin Review feedback on PR #2: the previous diff suppressed all output from `git fetch` and `git reset --hard origin/HEAD` without checking $LASTEXITCODE. If `git fetch` failed (e.g. transient network error) the subsequent `reset` would silently succeed against whatever was last fetched and the script would build a potentially stale tree. Now we surface fetch failures as an Info notice (the existing checkout is still usable, so we don't abort) and throw if the reset itself fails. Co-Authored-By: jacob levesque <jaemlev@icloud.com>
…offline * Fix install.ps1 crash when piped through iex and render in PS 5.1 Three bugs surfaced by running the one-liner installer in stock Windows PowerShell 5.1: 1. $PSScriptRoot is empty when the script is piped through Invoke-Expression (iwr ... | iex), so `Join-Path $PSScriptRoot 'rust\Cargo.toml'` threw 'Cannot bind argument to parameter Path because it is an empty string' right after 'Building from source...'. Introduce a Get-LocalCheckoutDir helper that falls back to $PSCommandPath and $MyInvocation.MyCommand.Path and finally returns $null. The source-build branch now treats $null as 'no local checkout' and skips straight to the user-scope git clone. 2. The backtick-e escape (`e) is only an ESC literal in PowerShell 6+. In Windows PowerShell 5.1 it's just the character 'e', which is why the user saw literal 'e[38;2;0;255;65m' in the output instead of green text. Replace with $ESC = [char]27 so ANSI sequences render on 5.1 too. 3. Box-drawing glyphs printed as '?' on the user's terminal because the default OEM code page can't represent them. Set [Console]::OutputEncoding to UTF-8 early in the script (wrapped in try/catch in case the host forbids it). Co-Authored-By: jacob levesque <jaemlev@icloud.com> * Check git fetch/reset exit codes in source-build fallback (cherry-picked from PR #2) Co-Authored-By: jacob levesque <jaemlev@icloud.com> * Windows audit, offline/proxy install support, clippy/fmt cleanup Windows correctness fixes: - platform::extra_path now adds \$USERPROFILE\.cargo\bin so freshly-installed Rust user binaries are discoverable. - bash tool degrades to 'cmd /C' on Windows (no /bin/sh). Existing POSIX-only printf tests now gated to #[cfg(unix)]. - plugins/runtime hooks::shell_command: fix Windows mut warning, gate unused std::path::Path import. - file_ops symlink test scoped under #[cfg(unix)] (Windows had unused let). install.ps1 network-restricted / offline support: - New flags: -OfflineSource, -OfflineZip, -Proxy, -ProxyUseDefaultCredentials, -Repo. - Auto-detect HTTP_PROXY/HTTPS_PROXY env vars. - Get-WebRequestSplat applies proxy + NTLM credentials uniformly to all Invoke-WebRequest calls (release zip, rustup-init, git fallback). - Friendly error when Zscaler/raw.githubusercontent.com filtering hits, pointing user at -OfflineSource or -OfflineZip workflow. Docs: - New INSTALL.md: Linux/macOS quickstart, Windows quickstart, three network-restricted workflows (proxy, offline source, offline zip), troubleshooting, install locations. - README points at INSTALL.md for restricted networks. - .gitignore picks up .hackcode/, .hackcode-agents/, .hackcode-src/ runtime artefacts so they don't get committed. Rust workspace cleanup so cargo clippy --workspace --all-targets -- -D warnings now passes clean on both Linux and x86_64-pc-windows-gnu: - Workspace [lints.clippy] allows the pedantic / style lints that newer clippy releases (1.95+) added but that the existing codebase has many of (doc_markdown, match_same_arms, too_many_lines, uninlined_format_args, cast_possible_truncation, type_complexity, manual_split_once, etc.). Substantive lints (correctness, suspicious, perf) stay enforced. - A handful of substantive fixes were applied directly rather than allow-listed: redundant pattern matching, identical match arms, doc-comment backticks, is_ok_and on a Result. - cargo clippy --fix + scripts/fmt.sh swept the remaining cascade of formatting nits across crates touched by the lint changes. Co-Authored-By: jacob levesque <jaemlev@icloud.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: jacob levesque <jaemlev@icloud.com>
Summary
Fixes three bugs surfaced when running the one-liner installer in stock Windows PowerShell 5.1:
Empty
$PSScriptRootwhen piped throughiex—Join-Path $PSScriptRoot 'rust\Cargo.toml'threwCannot bind argument to parameter 'Path' because it is an empty string.right after "Building from source...". Replaced with aGet-LocalCheckoutDirhelper that falls back to$PSCommandPathand$MyInvocation.MyCommand.Path, finally returning$null. The source-build branch treats$nullas "no local checkout" and skips straight to the user-scopegit clone. Also added aTest-Command 'git'guard with awinget install Git.Githint and a$LASTEXITCODEcheck on the clone.`eis not an ESC literal in Windows PowerShell 5.1 — only PowerShell 6+ interprets it. The user's transcript showing literale[38;2;0;255;65mconfirms this. Replaced with$ESC = [char]27so ANSI sequences render correctly on 5.1 (Win10/11 ConsoleHost supports VT sequences when raw ANSI is emitted).Box-drawing glyphs rendered as
?because the default OEM console code page can't represent them. Set[Console]::OutputEncoding = [System.Text.Encoding]::UTF8early (wrapped intry/catchin case the host forbids it).Review & Testing Checklist for Human
iwr https://raw.githubusercontent.com/johnesecat/hackcode-main/dev/install.ps1 | iex— confirm it gets past "Building from source..." instead of throwing theiex : Cannot bind argument to parameter 'Path'error.e[38;2;0;255;65mliteral text and not?boxes).hackcode.exelands at%LOCALAPPDATA%\Programs\HackCode\hackcode.exeandhackcode --versionworks in a new PowerShell session.Notes
Parser.ParseFilereturned no errors) and end-to-end dry-ran both theiex-piped path and the local-checkout path underpwshon Linux with stubbed network/exec calls. Both branches reach "Installation complete!" without the bug.iwr | iexwill use the default branch of the repo, so the user needs the PR merged (or the curl URL pointing at this branch) before re-running.Link to Devin session: https://app.devin.ai/sessions/f5985bf35b3c4979b88e83e6ccf371e3
Requested by: @johnesecat