From 63f064a96387f2de0cbca0a6f70619d1666ec0ed Mon Sep 17 00:00:00 2001 From: Mike Odnis Date: Sun, 19 Apr 2026 02:25:11 -0400 Subject: [PATCH 1/2] fix(installer): nix-PATH hint, completions error surfacing, dotnet-sdk/landing banners MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User feedback from a live install surfaced three friction points: 1. **\`nix: command not found\` in new terminals after install.** Determinate wires the system profile, but the curl|sh parent process can't mutate the caller's env. When the "Get started" footer told the user to \`cd ... && nix develop\` in the SAME terminal that launched curl|sh, they hit the missing-PATH error because only our script's subshell had nix sourced. Track whether we installed Nix this run (\$NIX_JUST_INSTALLED / in PS \$script:NixJustInstalled) and emit a prominent note before "Get started" telling the user to either open a new terminal or source the daemon profile script explicitly. Includes a fish-specific hint. 2. **Bash completions failed silently** with \`Failed to generate bash completions — skip\` and no reason. The redirect was \`2>/dev/null\`. Now we capture stderr to a tempfile and echo the first line into the warning when generation fails; also special-case empty-output to tell the user the binary likely predates the \`completions\` subcommand (resq-cli-v0.2.7+ has it). PowerShell variant already captured \$_. 3. **\`print_repo_info\` had no \`dotnet-sdk\` or \`landing\` case.** Users of those repos got no "What's included" banner. Added both (dotnet-sdk: .NET 9 SDK + Protobuf; landing: Bun + Next.js 15 + Tailwind). PowerShell Show-RepoInfo mirrored. --- install.ps1 | 32 ++++++++++++++++++++++++++++++++ install.sh | 44 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/install.ps1 b/install.ps1 index ed468f8..c39f8ba 100644 --- a/install.ps1 +++ b/install.ps1 @@ -186,6 +186,11 @@ function Connect-GitHub { } function Install-Nix { + # Track whether we installed Nix this run so Main can warn the user + # afterwards that `nix` won't be on PATH in new terminals until they + # restart the shell (env mutations from the installer don't propagate + # back to the parent process that curl|pwsh'd this script). + $script:NixJustInstalled = $false if (-not (Test-Command 'nix')) { if ($IsNativeWindows) { Write-Info 'Nix is not natively supported on Windows.' @@ -201,6 +206,7 @@ function Install-Nix { Write-Info 'Installing Nix via Determinate Systems installer...' bash -c "curl --proto '=https' --tlsv1.2 -sSf -L '$NixInstallUrl' | sh -s -- install" + $script:NixJustInstalled = $true # Source nix in current shell if (Test-Path '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh') { @@ -499,6 +505,22 @@ function Show-RepoInfo { Write-Host ' make anchor-build, make anchor-test' Write-Host '' } + 'dotnet-sdk' { + Write-Host '' + Write-Host ' What''s included:' -ForegroundColor White + Write-Host '' + Write-Host ' .NET 9 SDK, Protobuf toolchain' + Write-Host ' dotnet build -c Release, dotnet test -c Release' + Write-Host '' + } + 'landing' { + Write-Host '' + Write-Host ' What''s included:' -ForegroundColor White + Write-Host '' + Write-Host ' Bun, Next.js 15, Tailwind CSS, TypeScript' + Write-Host ' bun dev, bun run build' + Write-Host '' + } 'pypi' { Write-Host '' Write-Host ' What''s included:' -ForegroundColor White @@ -565,6 +587,16 @@ function Main { Write-Host ' Ready!' -ForegroundColor Green Write-Host '' + + if ($script:NixJustInstalled) { + Write-Host ' Note:' -ForegroundColor Yellow -NoNewline + Write-Host ' Nix was just installed. For `nix` to be on PATH, either:' + Write-Host ' - open a new terminal, or' + Write-Host ' - run: . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' + Write-Host ' (fish users: set -x PATH /nix/var/nix/profiles/default/bin $PATH)' + Write-Host '' + } + Write-Host ' Get started:' -ForegroundColor White Write-Host '' Write-Host " cd $($script:TargetDir)" diff --git a/install.sh b/install.sh index 4da87b7..65f09a4 100755 --- a/install.sh +++ b/install.sh @@ -218,6 +218,11 @@ authenticate_gh() { } install_nix() { + # Track whether Determinate installed Nix this session so we can remind the + # user to start a fresh shell (or source the profile) for `nix` to be on + # PATH in their interactive terminal — env mutations inside `curl | sh` + # don't propagate to the parent process. + NIX_JUST_INSTALLED=0 if ! has nix; then if ! confirm "Install Nix package manager?"; then warn "Skipping Nix install — some repos require Nix for their dev environment." @@ -225,8 +230,9 @@ install_nix() { fi info "Installing Nix via Determinate Systems installer..." curl --proto '=https' --tlsv1.2 -sSf -L "$NIX_INSTALL_URL" | sh -s -- install + NIX_JUST_INSTALLED=1 - # Source nix in current shell + # Source nix in current shell (this script's process only; see note above). # shellcheck disable=SC1091 if [ -f /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh ]; then . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh @@ -459,13 +465,23 @@ install_resq_completions() { esac mkdir -p "$_compl_dir" - if "$_bin_path" completions "$_shell_name" > "$_compl_file" 2>/dev/null; then + # Capture stderr on failure so the user sees the real reason. Older resq + # binaries (before v0.2.7) don't know about `completions`; newer ones do. + _compl_err="$("$_bin_path" completions "$_shell_name" 2> /tmp/resq-compl-err.$$ > "$_compl_file" && echo ok || echo fail)" + if [ "$_compl_err" = "ok" ] && [ -s "$_compl_file" ]; then + rm -f /tmp/resq-compl-err.$$ ok "Installed $_shell_name completions to $_compl_file" if [ "$_shell_name" = "zsh" ]; then info " zsh: add to ~/.zshrc if not already: fpath+=(\"$_compl_dir\"); autoload -Uz compinit && compinit" fi else - warn "Failed to generate $_shell_name completions — skip" + _err_msg="$(head -n 1 /tmp/resq-compl-err.$$ 2>/dev/null)" + rm -f "$_compl_file" /tmp/resq-compl-err.$$ + if [ -n "$_err_msg" ]; then + warn "Failed to generate $_shell_name completions: $_err_msg" + else + warn "Failed to generate $_shell_name completions (empty output — the installed resq may predate the 'completions' subcommand; retry once a newer release is out)" + fi fi } @@ -476,6 +492,16 @@ print_repo_info() { printf " Solana CLI, Anchor framework, Rust toolchain\n" >&2 printf " make anchor-build, make anchor-test\n\n" >&2 ;; + dotnet-sdk) + printf "\n ${BOLD}What's included:${RESET}\n\n" >&2 + printf " .NET 9 SDK, Protobuf toolchain\n" >&2 + printf " dotnet build -c Release, dotnet test -c Release\n\n" >&2 + ;; + landing) + printf "\n ${BOLD}What's included:${RESET}\n\n" >&2 + printf " Bun, Next.js 15, Tailwind CSS, TypeScript\n" >&2 + printf " bun dev, bun run build\n\n" >&2 + ;; pypi) printf "\n ${BOLD}What's included:${RESET}\n\n" >&2 printf " Python 3.11-3.13, uv, ruff, mypy\n" >&2 @@ -524,6 +550,18 @@ main() { print_repo_info printf "${BOLD}${GREEN} Ready!${RESET}\n\n" >&2 + + # If Determinate installed Nix this run, the user's interactive shell + # (which spawned `curl | sh`) hasn't sourced the profile yet. Flag this + # prominently before the "Get started" list so they don't hit + # `nix: command not found` when they follow the instructions. + if [ "${NIX_JUST_INSTALLED:-0}" = "1" ]; then + printf " ${BOLD}${YELLOW}Note:${RESET} Nix was just installed. For \`nix\` to be on PATH, either:\n" >&2 + printf " - open a new terminal, or\n" >&2 + printf " - run: . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh\n" >&2 + printf " (fish users: set -x PATH /nix/var/nix/profiles/default/bin \$PATH)\n\n" >&2 + fi + printf " ${BOLD}Get started:${RESET}\n\n" >&2 printf " cd %s\n" "$TARGET_DIR" >&2 if [ -f "$TARGET_DIR/flake.nix" ]; then From eaa5ee1f30ac34e02825937f8e1219624b473ccb Mon Sep 17 00:00:00 2001 From: Mike Odnis Date: Sun, 19 Apr 2026 03:19:28 -0400 Subject: [PATCH 2/2] fix(installer): use mktemp for completions-stderr tempfile Applies gemini's review comments on PR #19 (lines 472 and 479). Swap /tmp/resq-compl-err.$$ for mktemp so TMPDIR is honoured and we can't collide with a stale file from a different user on a shared host. Same variable threads through both the success and failure branches for cleanup and stderr-read. --- install.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/install.sh b/install.sh index f519cbe..ce7b6b5 100755 --- a/install.sh +++ b/install.sh @@ -469,16 +469,19 @@ install_resq_completions() { mkdir -p "$_compl_dir" # Capture stderr on failure so the user sees the real reason. Older resq # binaries (before v0.2.7) don't know about `completions`; newer ones do. - _compl_err="$("$_bin_path" completions "$_shell_name" 2> /tmp/resq-compl-err.$$ > "$_compl_file" && echo ok || echo fail)" + # Using mktemp (not /tmp/...$$) so TMPDIR is honoured and we can't collide + # with a stale file owned by another user on a shared host. + _err_tmp="$(mktemp)" + _compl_err="$("$_bin_path" completions "$_shell_name" 2> "$_err_tmp" > "$_compl_file" && echo ok || echo fail)" if [ "$_compl_err" = "ok" ] && [ -s "$_compl_file" ]; then - rm -f /tmp/resq-compl-err.$$ + rm -f "$_err_tmp" ok "Installed $_shell_name completions to $_compl_file" if [ "$_shell_name" = "zsh" ]; then info " zsh: add to ~/.zshrc if not already: fpath+=(\"$_compl_dir\"); autoload -Uz compinit && compinit" fi else - _err_msg="$(head -n 1 /tmp/resq-compl-err.$$ 2>/dev/null)" - rm -f "$_compl_file" /tmp/resq-compl-err.$$ + _err_msg="$(head -n 1 "$_err_tmp" 2>/dev/null)" + rm -f "$_compl_file" "$_err_tmp" if [ -n "$_err_msg" ]; then warn "Failed to generate $_shell_name completions: $_err_msg" else