Skip to content

fix: use sort -V for globals version comparison to prevent redundant installs - #1383

Merged
shunkakinoki merged 1 commit into
mainfrom
fix/globals-version-comparison
Apr 6, 2026
Merged

fix: use sort -V for globals version comparison to prevent redundant installs#1383
shunkakinoki merged 1 commit into
mainfrom
fix/globals-version-comparison

Conversation

@shunkakinoki

@shunkakinoki shunkakinoki commented Apr 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • Both uv and npm globals install scripts used exact version match (=) to skip already-installed packages
  • Packages with newer-than-required versions (e.g. ruff 0.15.9 installed vs >=0.15.8 required) were reinstalled every run
  • Replaced with sort -V based >= comparison so newer installed versions correctly skip
  • Added version comparison tests for both scripts

Test plan

  • shellspec spec/uv_globals_spec.sh - 25 examples, 0 failures
  • shellspec spec/npm_globals_spec.sh - 31 examples, 0 failures
  • New tests verify sort -V behavior for newer, equal, and older versions

Summary by cubic

Prevent redundant installs of global tools by switching version checks in the uv and npm globals installers to a sort -V >= comparison. Newer or equal installed versions now skip; added shellspec tests for newer/equal/older cases.

Written for commit 22b843a. Summary will update on new commits.

Copilot AI review requested due to automatic review settings April 6, 2026 01:29
@mesa-dot-dev

mesa-dot-dev Bot commented Apr 6, 2026

Copy link
Copy Markdown

You do not have enough credits to review this pull request. Please purchase more credits to continue.

@shunkakinoki
shunkakinoki merged commit e4b18da into main Apr 6, 2026
26 of 27 checks passed
@shunkakinoki
shunkakinoki deleted the fix/globals-version-comparison branch April 6, 2026 01:29
@coderabbitai

coderabbitai Bot commented Apr 6, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a62d17a6-d310-41a2-9bc7-fe0eaad79859

📥 Commits

Reviewing files that changed from the base of the PR and between 4da9e66 and 22b843a.

📒 Files selected for processing (4)
  • home-manager/modules/npm-globals/install-npm-globals.sh
  • home-manager/modules/uv-globals/install-uv-globals.sh
  • spec/npm_globals_spec.sh
  • spec/uv_globals_spec.sh

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.


📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced version comparison logic for npm and uv global packages by implementing semantic version comparison instead of exact string matching, ensuring installed versions are properly evaluated against minimum version requirements and preventing unnecessary reinstalls.
  • Tests

    • Added test coverage validating semantic version comparison behavior across npm and uv global package installation.

Walkthrough

This PR updates version comparison logic in npm and uv global package installers from exact string matching to semantic version comparison using sort -V. Installation is now skipped only when the installed version meets or exceeds the required minimum. Corresponding test cases validate the new version-ordering behavior across both installers.

Changes

Cohort / File(s) Summary
npm-globals installer
home-manager/modules/npm-globals/install-npm-globals.sh
Modified version-check logic to compute min_ver via semantic comparison (sort -V) instead of requiring exact equality. Skips installation only if min_ver equals the wanted version (installed satisfies minimum). Falls back to previous behavior when wanted_ver is empty.
uv-globals installer
home-manager/modules/uv-globals/install-uv-globals.sh
Changed skip-install condition from exact string match to semantic version comparison. Now uses sort -V to determine if req_version is the minimum; skips installation only when the installed version is at or above the required minimum.
Test coverage
spec/npm_globals_spec.sh, spec/uv_globals_spec.sh
Added test cases validating semantic version comparison behavior: verifies sort -V usage, confirms installation is skipped when installed version is newer or equal to required, and confirms installation is triggered when installed version is older than required.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • #1378: Directly modifies the same installer scripts (install-uv-globals.sh and install-npm-globals.sh) with skip-if-already-installed logic and related tests.
  • #1380: Updates npm-globals installer's skip-if-already-installed logic to use semantic version comparison with minimum-version checks and test coverage.
  • #1368: Modifies the uv-globals installer script's tool parsing and installation logic in the same file.

Poem

🐰 Hop hop! The versions align with sort -V,
No more strict matches—now semantic's the key!
Installed meets required, skip the install spree,
These tests seal the logic, as clear as can be! ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/globals-version-comparison

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the version comparison logic in the npm and uv global installation scripts to use sort -V, ensuring that existing installations are skipped if the current version is greater than or equal to the required version. New test cases were added to verify these scenarios. The review feedback suggests optimizing the comparison using sort -VC to improve conciseness and avoid potential regex pitfalls with version strings.

Comment on lines +60 to +66
if [ -n "$installed_ver" ] && [ -n "$wanted_ver" ]; then
min_ver=$(printf '%s\n%s\n' "$wanted_ver" "$installed_ver" | sort -V | head -n1)
if [ "$min_ver" = "$wanted_ver" ]; then
echo "$dep@$installed_ver already installed, skipping"
continue
fi
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The version comparison logic can be simplified by using sort -VC, which checks if the input is already sorted according to version rules. This avoids the need for a subshell assignment and head, making the code more concise.

Note: Since sort -V is a GNU extension, please ensure that coreutils is explicitly included in the PATH within the home.activation block in default.nix. This prevents potential failures on systems where the default sort does not support the -V flag (e.g., macOS).

Suggested change
if [ -n "$installed_ver" ] && [ -n "$wanted_ver" ]; then
min_ver=$(printf '%s\n%s\n' "$wanted_ver" "$installed_ver" | sort -V | head -n1)
if [ "$min_ver" = "$wanted_ver" ]; then
echo "$dep@$installed_ver already installed, skipping"
continue
fi
fi
if [ -n "$installed_ver" ] && [ -n "$wanted_ver" ] && \
printf '%s\n%s\n' "$wanted_ver" "$installed_ver" | sort -VC; then
echo "$dep@$installed_ver already installed, skipping"
continue
fi
References
  1. Maintain consistency with established patterns for writing scripts that are extracted from Nix expressions.

Comment on lines +53 to 58
if [ -n "$installed_version" ] && [ -n "$req_version" ]; then
if printf '%s\n%s\n' "$req_version" "$installed_version" | sort -V | head -n1 | grep -qx "$req_version"; then
echo "$name $installed_version already installed, skipping"
continue
fi
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The use of grep -qx for version comparison is redundant and potentially problematic, as the . characters in version strings are interpreted as regex wildcards. Using sort -VC is a more robust and efficient way to verify that the installed version meets the requirement.

Note: Since sort -V is a GNU extension, please ensure that coreutils is explicitly included in the PATH within the home.activation block in default.nix. This prevents potential failures on systems where the default sort does not support the -V flag (e.g., macOS).

Suggested change
if [ -n "$installed_version" ] && [ -n "$req_version" ]; then
if printf '%s\n%s\n' "$req_version" "$installed_version" | sort -V | head -n1 | grep -qx "$req_version"; then
echo "$name $installed_version already installed, skipping"
continue
fi
fi
if [ -n "$installed_version" ] && [ -n "$req_version" ] && \
printf '%s\n%s\n' "$req_version" "$installed_version" | sort -VC; then
echo "$name $installed_version already installed, skipping"
continue
fi
References
  1. Maintain consistency with established patterns for writing scripts that are extracted from Nix expressions.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR updates the uv and npm global install scripts to skip installs when the currently installed version is newer than the required/wanted version, and adds tests around the new sort -V version comparison behavior.

Changes:

  • Replace exact-version equality checks with sort -V-based >= comparisons in uv/npm global install scripts
  • Add ShellSpec examples asserting presence and behavior of sort -V-based version ordering

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
spec/uv_globals_spec.sh Adds ShellSpec examples around sort -V version ordering and script implementation check
spec/npm_globals_spec.sh Adds ShellSpec examples around sort -V version ordering and script implementation check
home-manager/modules/uv-globals/install-uv-globals.sh Switches skip-logic to treat installed versions newer than required as satisfied via sort -V
home-manager/modules/npm-globals/install-npm-globals.sh Switches skip-logic to treat installed versions newer than wanted as satisfied via sort -V

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +53 to +57
if [ -n "$installed_version" ] && [ -n "$req_version" ]; then
if printf '%s\n%s\n' "$req_version" "$installed_version" | sort -V | head -n1 | grep -qx "$req_version"; then
echo "$name $installed_version already installed, skipping"
continue
fi

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sort -V is a GNU extension and is not available with BSD sort (e.g., default macOS). If this script is expected to run on Darwin, this will fail at runtime. Consider pinning to a known GNU sort (e.g., via an explicit coreutils path in the Nix/home-manager context) or adding a fallback version-compare implementation when sort -V is unsupported.

Copilot uses AI. Check for mistakes.
Comment on lines +60 to +66
if [ -n "$installed_ver" ] && [ -n "$wanted_ver" ]; then
min_ver=$(printf '%s\n%s\n' "$wanted_ver" "$installed_ver" | sort -V | head -n1)
if [ "$min_ver" = "$wanted_ver" ]; then
echo "$dep@$installed_ver already installed, skipping"
continue
fi
fi

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same portability concern here: sort -V is not POSIX and will fail on platforms with BSD sort (notably macOS). If cross-platform execution is required, use a guaranteed GNU sort (or a repo-controlled tool) or implement a fallback comparator when sort -V isn’t supported.

Copilot uses AI. Check for mistakes.
Comment thread spec/uv_globals_spec.sh
Comment on lines +118 to +132
# Simulate: installed=0.15.9, required=0.15.8 -> should skip
When run bash -c "printf '0.15.8\n0.15.9\n' | sort -V | head -n1"
The output should eq '0.15.8'
End

It 'skips when installed version equals required'
# Simulate: installed=0.86.2, required=0.86.2 -> should skip
When run bash -c "printf '0.86.2\n0.86.2\n' | sort -V | head -n1"
The output should eq '0.86.2'
End

It 'detects when installed version is older than required'
# Simulate: installed=2.6.9, required=2.7.0 -> min is 2.6.9, not 2.7.0
When run bash -c "printf '2.7.0\n2.6.9\n' | sort -V | head -n1"
The output should eq '2.6.9'

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These examples validate sort -V behavior in isolation, but they don’t exercise the script’s actual skip/update branching (they would still pass even if the script’s condition is incorrect, as long as sort -V exists). Consider adding tests that run the install script with a mocked/controlled INSTALLED + required version input and assert it prints already installed, skipping for newer/equal installed versions and performs the update path for older versions.

Suggested change
# Simulate: installed=0.15.9, required=0.15.8 -> should skip
When run bash -c "printf '0.15.8\n0.15.9\n' | sort -V | head -n1"
The output should eq '0.15.8'
End
It 'skips when installed version equals required'
# Simulate: installed=0.86.2, required=0.86.2 -> should skip
When run bash -c "printf '0.86.2\n0.86.2\n' | sort -V | head -n1"
The output should eq '0.86.2'
End
It 'detects when installed version is older than required'
# Simulate: installed=2.6.9, required=2.7.0 -> min is 2.6.9, not 2.7.0
When run bash -c "printf '2.7.0\n2.6.9\n' | sort -V | head -n1"
The output should eq '2.6.9'
# Simulate the install script branch: installed=0.15.9, required=0.15.8 -> should skip
When run bash -c '
INSTALLED=0.15.9
REQUIRED=0.15.8
if [ "$INSTALLED" != "$REQUIRED" ] && [ "$(printf "%s\n%s\n" "$REQUIRED" "$INSTALLED" | sort -V | head -n1)" = "$INSTALLED" ]; then
echo "uv tool install"
else
echo "already installed, skipping"
fi
'
The output should eq 'already installed, skipping'
End
It 'skips when installed version equals required'
# Simulate the install script branch: installed=0.86.2, required=0.86.2 -> should skip
When run bash -c '
INSTALLED=0.86.2
REQUIRED=0.86.2
if [ "$INSTALLED" != "$REQUIRED" ] && [ "$(printf "%s\n%s\n" "$REQUIRED" "$INSTALLED" | sort -V | head -n1)" = "$INSTALLED" ]; then
echo "uv tool install"
else
echo "already installed, skipping"
fi
'
The output should eq 'already installed, skipping'
End
It 'updates when installed version is older than required'
# Simulate the install script branch: installed=2.6.9, required=2.7.0 -> should update
When run bash -c '
INSTALLED=2.6.9
REQUIRED=2.7.0
if [ "$INSTALLED" != "$REQUIRED" ] && [ "$(printf "%s\n%s\n" "$REQUIRED" "$INSTALLED" | sort -V | head -n1)" = "$INSTALLED" ]; then
echo "uv tool install"
else
echo "already installed, skipping"
fi
'
The output should eq 'uv tool install'

Copilot uses AI. Check for mistakes.
@mesa-dot-dev

mesa-dot-dev Bot commented Apr 6, 2026

Copy link
Copy Markdown

Mesa Description

TL;DR

Fixed redundant global package installations by changing version comparison in uv and npm install scripts to use sort -V for a proper "greater than or equal to" check, and added version comparison tests.

What changed?

  • Modified uv and npm global install scripts to use sort -V for version comparison.
  • This prevents re-installation of global packages when a newer or equal version is already installed.
  • Added new tests for both uv_globals_spec.sh and npm_globals_spec.sh to validate the sort -V behavior for newer, equal, and older versions.

Description generated by Mesa. Update settings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants