fix: make install scripts usable immediately without terminal restart#433
fix: make install scripts usable immediately without terminal restart#433
Conversation
PowerShell: update session $env:PATH after setting persistent user PATH so 'synthorg' works immediately. Handles both first install and re-runs where persistent PATH already has the directory but the session doesn't. Bash: warn when custom INSTALL_DIR is not in PATH and print the exact export command needed (default /usr/local/bin is typically already in PATH).
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the user experience for Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughSummary by CodeRabbit
WalkthroughPowerShell and Bash installer scripts were updated to improve PATH handling and user guidance: PowerShell now normalizes InstallDir, performs exact-match checks, updates user PATH and the current process PATH without restart messaging; Bash adds a post-install warning with export instructions if INSTALL_DIR is absent from PATH. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
✨ Simplify code
📝 Coding Plan
Comment |
There was a problem hiding this comment.
Code Review
This pull request improves the installation scripts for PowerShell and Bash to make the synthorg CLI usable immediately after installation without a terminal restart. The changes are well-aligned with this goal. The PowerShell script is updated to modify the current session's PATH, and the Bash script now warns users if the installation directory isn't in their PATH. I've added a couple of suggestions to make the PATH variable checks in both scripts more robust against edge cases, such as paths with trailing slashes or substring conflicts.
cli/scripts/install.ps1
Outdated
| if ($env:PATH -notlike "*$InstallDir*") { | ||
| $env:PATH = "$env:PATH;$InstallDir" | ||
| } |
There was a problem hiding this comment.
The -notlike check for the directory's existence in PATH is not fully robust. It can return a false positive if $InstallDir is a substring of another directory in PATH. For instance, if PATH includes C:\Program Files\synthorg-tools and $InstallDir is C:\Program Files\synthorg, the check would incorrectly assume the path is already present. A more reliable method is to split the PATH string by its separator and check for an exact match in the resulting array of paths. Note that the same potential issue exists on line 82 for the $UserPath check.
if (($env:PATH -split ';') -notcontains $InstallDir) {
$env:PATH = "$env:PATH;$InstallDir"
}
cli/scripts/install.sh
Outdated
|
|
||
| # Warn if INSTALL_DIR is not in PATH. | ||
| case ":${PATH}:" in | ||
| *":${INSTALL_DIR}:"*) ;; |
There was a problem hiding this comment.
The check for INSTALL_DIR in PATH might fail if INSTALL_DIR has a trailing slash (e.g., INSTALL_DIR=/tmp/foo/) but PATH contains the path without it (e.g., /tmp/foo). It's good practice to normalize the path by removing any trailing slash before the check. You can do this directly within the case statement pattern using shell parameter expansion.
| *":${INSTALL_DIR}:"*) ;; | |
| *":${INSTALL_DIR%/}:"*) ;; |
Greptile SummaryThis PR fixes two usability issues in the CLI install scripts: the PowerShell script now updates the current session's Key changes:
Confidence Score: 4/5
Important Files Changed
Prompt To Fix All With AIThis is a comment left during a code review.
Path: cli/scripts/install.sh
Line: 117-118
Comment:
**PATH check only normalises INSTALL_DIR's trailing slash, not PATH entries**
`${INSTALL_DIR%/}` strips a trailing slash from `INSTALL_DIR` before building the pattern, but individual entries in `$PATH` are not normalised. If the user's `PATH` contains the same directory _with_ a trailing slash (e.g. `/usr/local/bin/`), the pattern `*":/usr/local/bin:"*` won't match `:/usr/local/bin/:`, and a spurious warning will be printed even though the binary is perfectly reachable.
A simple guard that covers this common case:
```suggestion
case ":${PATH}:" in
*":${INSTALL_DIR%/}:"* | *":${INSTALL_DIR%/}/:"*) ;;
```
This matches both the normalised form and the same path with one trailing slash present in `$PATH`.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: cli/scripts/install.sh
Line: 116-128
Comment:
**PATH check reflects the installer subprocess's PATH, not the user's interactive shell**
When the script is run via `curl … | bash`, the spawned bash process inherits `PATH` from whatever invoked `curl` (e.g. a cron job, a CI runner, a minimal Docker container), not necessarily from the user's interactive login shell. This means:
- A false positive is possible: the warning fires even though the directory _is_ in the user's interactive `~/.profile`-sourced `PATH`.
- A false negative is possible: no warning fires because the parent process happened to have that directory in its `PATH`, even though the user's interactive shell does not.
This is an inherent limitation of piped installers and is hard to work around completely, but it may be worth adding a brief caveat to the warning message such as `"(checked against the current process PATH)"` so users aren't confused when `which synthorg` works in a new terminal despite the warning having fired.
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: eaf1d74 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cli/scripts/install.ps1`:
- Around line 81-87: Replace the wildcard substring checks against PATH with
exact, normalized entry membership checks: split $UserPath and $env:PATH on ';',
trim entries and optionally normalize/case-insensitize them, then test
membership of $InstallDir using -contains (or a case-insensitive comparison)
before calling [Environment]::SetEnvironmentVariable or mutating $env:PATH;
update the checks that currently use "-notlike "*$InstallDir*"" to use the
split-and-contains approach for both $UserPath and $env:PATH to avoid
false-positive matches like "C:\Tools2" when $InstallDir is "C:\Tools".
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 60d195dd-7b38-4048-9e88-7f1acd707344
📒 Files selected for processing (2)
cli/scripts/install.ps1cli/scripts/install.sh
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: CLI Test (windows-latest)
- GitHub Check: Greptile Review
- GitHub Check: Analyze (python)
🧰 Additional context used
🪛 PSScriptAnalyzer (1.24.0)
cli/scripts/install.ps1
[warning] 84-84: File 'install.ps1' uses Write-Host. Avoid using Write-Host because it might not work in all hosts, does not work when there is no host, and (prior to PS 5.0) cannot be suppressed, captured, or redirected. Instead, use Write-Output, Write-Verbose, or Write-Information.
(PSAvoidUsingWriteHost)
[warning] Missing BOM encoding for non-ASCII encoded file 'install.ps1'
(PSUseBOMForUnicodeEncodedFile)
🔇 Additional comments (1)
cli/scripts/install.sh (1)
116-128: PATH warning UX is clear and actionable.This provides the exact command users need and clearly explains persistence, which aligns with the install-flow objective.
- PowerShell: use exact PATH entry matching (-split + -notcontains)
instead of substring wildcard (-notlike) to avoid false positives
- Bash: normalize trailing slash in PATH check (${INSTALL_DIR%/})
- Bash: send warning output to stderr so it isn't swallowed by
stdout capture (e.g. OUTPUT=$(curl ... | bash))
- Bash: broaden shell profile hint to include ~/.bash_profile and
~/.profile for login-shell users (macOS, SSH)
| case ":${PATH}:" in | ||
| *":${INSTALL_DIR%/}:"*) ;; |
There was a problem hiding this comment.
PATH check only normalises INSTALL_DIR's trailing slash, not PATH entries
${INSTALL_DIR%/} strips a trailing slash from INSTALL_DIR before building the pattern, but individual entries in $PATH are not normalised. If the user's PATH contains the same directory with a trailing slash (e.g. /usr/local/bin/), the pattern *":/usr/local/bin:"* won't match :/usr/local/bin/:, and a spurious warning will be printed even though the binary is perfectly reachable.
A simple guard that covers this common case:
| case ":${PATH}:" in | |
| *":${INSTALL_DIR%/}:"*) ;; | |
| case ":${PATH}:" in | |
| *":${INSTALL_DIR%/}:"* | *":${INSTALL_DIR%/}/:"*) ;; |
This matches both the normalised form and the same path with one trailing slash present in $PATH.
Prompt To Fix With AI
This is a comment left during a code review.
Path: cli/scripts/install.sh
Line: 117-118
Comment:
**PATH check only normalises INSTALL_DIR's trailing slash, not PATH entries**
`${INSTALL_DIR%/}` strips a trailing slash from `INSTALL_DIR` before building the pattern, but individual entries in `$PATH` are not normalised. If the user's `PATH` contains the same directory _with_ a trailing slash (e.g. `/usr/local/bin/`), the pattern `*":/usr/local/bin:"*` won't match `:/usr/local/bin/:`, and a spurious warning will be printed even though the binary is perfectly reachable.
A simple guard that covers this common case:
```suggestion
case ":${PATH}:" in
*":${INSTALL_DIR%/}:"* | *":${INSTALL_DIR%/}/:"*) ;;
```
This matches both the normalised form and the same path with one trailing slash present in `$PATH`.
How can I resolve this? If you propose a fix, please make it concise.| # Warn if INSTALL_DIR is not in PATH (normalize trailing slash). | ||
| case ":${PATH}:" in | ||
| *":${INSTALL_DIR%/}:"*) ;; | ||
| *) | ||
| echo "Warning: ${INSTALL_DIR} is not in your PATH." >&2 | ||
| echo "Add it by running:" >&2 | ||
| echo "" >&2 | ||
| echo " export PATH=\"${INSTALL_DIR}:\$PATH\"" >&2 | ||
| echo "" >&2 | ||
| echo "To make it permanent, add that line to your shell profile (~/.bashrc, ~/.bash_profile, ~/.profile, ~/.zshrc, etc.)." >&2 | ||
| echo "" >&2 | ||
| ;; | ||
| esac |
There was a problem hiding this comment.
PATH check reflects the installer subprocess's PATH, not the user's interactive shell
When the script is run via curl … | bash, the spawned bash process inherits PATH from whatever invoked curl (e.g. a cron job, a CI runner, a minimal Docker container), not necessarily from the user's interactive login shell. This means:
- A false positive is possible: the warning fires even though the directory is in the user's interactive
~/.profile-sourcedPATH. - A false negative is possible: no warning fires because the parent process happened to have that directory in its
PATH, even though the user's interactive shell does not.
This is an inherent limitation of piped installers and is hard to work around completely, but it may be worth adding a brief caveat to the warning message such as "(checked against the current process PATH)" so users aren't confused when which synthorg works in a new terminal despite the warning having fired.
Prompt To Fix With AI
This is a comment left during a code review.
Path: cli/scripts/install.sh
Line: 116-128
Comment:
**PATH check reflects the installer subprocess's PATH, not the user's interactive shell**
When the script is run via `curl … | bash`, the spawned bash process inherits `PATH` from whatever invoked `curl` (e.g. a cron job, a CI runner, a minimal Docker container), not necessarily from the user's interactive login shell. This means:
- A false positive is possible: the warning fires even though the directory _is_ in the user's interactive `~/.profile`-sourced `PATH`.
- A false negative is possible: no warning fires because the parent process happened to have that directory in its `PATH`, even though the user's interactive shell does not.
This is an inherent limitation of piped installers and is hard to work around completely, but it may be worth adding a brief caveat to the warning message such as `"(checked against the current process PATH)"` so users aren't confused when `which synthorg` works in a new terminal despite the warning having fired.
How can I resolve this? If you propose a fix, please make it concise.🤖 I have created a release *beep* *boop* --- ## [0.2.4](v0.2.3...v0.2.4) (2026-03-15) ### Bug Fixes * attach cosign signatures and provenance bundle to release assets ([#438](#438)) ([f191a4d](f191a4d)) * create git tag explicitly for draft releases ([#432](#432)) ([1f5120e](1f5120e)) * docker healthcheck, CI optimization, and container hardening ([#436](#436)) ([4d32bca](4d32bca)) * ensure security headers on all HTTP responses ([#437](#437)) ([837f2fc](837f2fc)) * make install scripts usable immediately without terminal restart ([#433](#433)) ([b45533c](b45533c)) * migrate pids_limit to deploy.resources.limits.pids ([#439](#439)) ([66b94fd](66b94fd)) ### Refactoring * redesign release notes layout ([#434](#434)) ([239aaf7](239aaf7)) ### Maintenance * **site:** replace hero CTA with license link and scroll arrow ([#440](#440)) ([56af41c](56af41c)) * **web:** adopt @vue/tsconfig preset ([#435](#435)) ([7d4b214](7d4b214)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
🤖 I have created a release *beep* *boop* --- ## [0.2.4](v0.2.3...v0.2.4) (2026-03-15) ### Bug Fixes * attach cosign signatures and provenance bundle to release assets ([#438](#438)) ([f191a4d](f191a4d)) * create git tag explicitly for draft releases ([#432](#432)) ([1f5120e](1f5120e)) * docker healthcheck, CI optimization, and container hardening ([#436](#436)) ([4d32bca](4d32bca)) * ensure security headers on all HTTP responses ([#437](#437)) ([837f2fc](837f2fc)) * make install scripts usable immediately without terminal restart ([#433](#433)) ([b45533c](b45533c)) * migrate pids_limit to deploy.resources.limits.pids ([#439](#439)) ([66b94fd](66b94fd)) * use cosign --bundle flag for checksums signing ([#443](#443)) ([19735b9](19735b9)) ### Refactoring * redesign release notes layout ([#434](#434)) ([239aaf7](239aaf7)) ### Maintenance * **main:** release 0.2.4 ([#431](#431)) ([63b03c4](63b03c4)) * remove stale v0.2.4 changelog section from failed release ([#446](#446)) ([769de10](769de10)) * reset version to 0.2.3 for re-release ([#444](#444)) ([8579993](8579993)) * **site:** replace hero CTA with license link and scroll arrow ([#440](#440)) ([56af41c](56af41c)) * **web:** adopt @vue/tsconfig preset ([#435](#435)) ([7d4b214](7d4b214)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Summary
install.ps1): update session$env:PATHindependently of the persistent user PATH check, sosynthorgworks immediately after install — both on first install and re-runs where the persistent PATH already has it but the session doesn'tinstall.sh): warn when customINSTALL_DIRis not inPATHand print the exactexportcommand needed (default/usr/local/binis typically already in PATH, so most users won't see the warning)Problem
synthorg initfails with "not recognized" because the script only set the registry-level user PATH without updating the current session. Re-running the script also didn't help — the persistent PATH check passed (already added from first run), skipping the entire block silently.INSTALL_DIRoutside ofPATH, the script gave no indication that the binary wouldn't be found.Test plan
irm .../install.ps1 | iexin a fresh PowerShell session →synthorg versionworks immediately without restartINSTALL_DIR=/tmp/synthorg-test curl ... | bash→ warning printed with correctexportcommandINSTALL_DIR(default/usr/local/bin) → no warning shownReview coverage
Quick mode — automated checks only (no substantive code changes, shell scripts only)
🤖 Generated with Claude Code