Skip to content

fix(aqua): mirror aqua windows extension semantics#10167

Merged
jdx merged 3 commits into
jdx:mainfrom
risu729:codex-20260531-172732-ad2d98
Jun 2, 2026
Merged

fix(aqua): mirror aqua windows extension semantics#10167
jdx merged 3 commits into
jdx:mainfrom
risu729:codex-20260531-172732-ad2d98

Conversation

@risu729

@risu729 risu729 commented May 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • model aqua complete_windows_ext as tri-state instead of a defaulted boolean
  • support registry windows_ext and append_ext when rendering aqua assets, URLs, and Windows install links
  • treat .exe and .jar assets as already complete, preserve existing extensions when format is omitted, and keep version dots from suppressing Windows completion
  • centralize the version-aware extension rules in the aqua-registry crate so the backend delegates aqua semantics instead of duplicating them

Aqua behavior checked

Current aqua source and upstream history checked:

  • Source: aqua's windowsExt, completeWindowsExtToAsset, and completeWindowsExtToFileSrc, osfile.Ext, and appendExt.
  • append_ext defaults to true. Aqua appends the configured format to rendered asset/URL strings when the string does not already look like an archive/compressed asset and format is neither empty nor raw; append_ext: false disables that behavior.
  • complete_windows_ext is tri-state. Explicit true completes Windows asset/URL/file source names, explicit false leaves them alone, and an omitted value completes by default except for github_content and github_archive packages.
  • windows_ext controls the suffix used by Windows completion. Aqua defaults to .exe, but defaults to .sh for github_content and github_archive; registry entries can override it, such as .bat.
  • .exe is hardcoded upstream as the Windows executable suffix. It started with aqua's Windows support work in aquaproj/aqua#858 for assets and aquaproj/aqua#874 for URLs/files, both under the broader Windows support request aquaproj/aqua#850.
  • .jar is also hardcoded upstream as already complete. aquaproj/aqua#4719 changed completeWindowsExtToAsset from only skipping .exe to skipping .exe or .jar, with the commit note "skip appending .exe on Windows" for JARs.
  • When format is omitted, aqua does not blindly append a Windows extension. aquaproj/aqua#874 added the URL fallback that completes only when filepath.Ext(s) == "", and aquaproj/aqua#1853 added the omitted-{{.Format}} asset flow. The linked feature request aquaproj/aqua#1774 says the goal is simpler config when formats change. mise mirrors the current aqua implementation by checking the version-stripped filename extension first: existing extensions like .ps1 are preserved while version dots like tool.1.0.0 do not suppress completion.

mise support

  • AquaPackage now preserves complete_windows_ext: Option<bool>, windows_ext, and append_ext from registry YAML and version overrides.
  • Asset and URL rendering now applies aqua-compatible append_ext before Windows completion.
  • Windows completion uses aqua's defaults, custom windows_ext, .jar preservation, github_content/github_archive defaults, and version-stripped extension detection.
  • Install-time file source/destination completion now uses the same package-level extension settings instead of hard-coded .exe.
  • The aqua-registry crate now owns the version-aware extension detector plus install file source/destination completion helpers; the backend only adapts those string rules to PathBuf file names.

Foundry / cosign note

Foundry's aqua-registry entry already declares both GitHub Artifact Attestations and a cosign Sigstore bundle at {{.AssetWithoutExt}}.sigstore.json. mise already checks cosign bundles through the existing aqua cosign verification path; this PR is about rendering the asset names and AssetWithoutExt inputs consistently with aqua.

Related mise reports

Tests

  • cargo test -p aqua-registry
  • cargo test -p mise windows_ext

Summary by CodeRabbit

  • New Features

    • Configurable Windows file extension handling with improved package-type-based defaults.
  • Improvements

    • Enhanced file extension detection for Windows systems; better handling of version strings in filenames.
    • Registry compilation cache updated to version 2; cached entries will be regenerated on next use.

@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 introduces support for custom Windows extensions, conditional extension appending, and improved Windows extension completion logic, along with corresponding unit tests. The review feedback highlights three important opportunities to prevent bugs when parsing file extensions from paths containing version numbers. Specifically, the reviewer recommends updating complete_windows_dst_ext to avoid treating trailing version components (like .0) as file extensions, and modifying both os_file_ext_is_empty and path_ext_is_empty to perform version string replacements only on the filename component rather than the entire path or URL, preventing unintended side effects and path corruption.

Comment thread src/backend/aqua.rs Outdated
Comment thread crates/aqua-registry/src/types.rs
Comment thread src/backend/aqua.rs Outdated
@greptile-apps

greptile-apps Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR refines aqua Windows extension handling to faithfully mirror upstream aqua semantics: complete_windows_ext becomes a tri-state Option<bool>, windows_ext and append_ext fields are added to AquaPackage, and a new file_ext.rs module provides version-aware extension detection (stripping version tokens before deciding whether a filename already carries a real extension).

  • append_ext is applied before Windows completion so format extensions like .tar.gz are considered when deciding whether .exe is needed; asset_strs now always includes both the fully-processed candidate and a raw fallback, maintaining ordering so the finished name is tried first.
  • Backend complete_windows_ext/complete_windows_dst_ext helpers are gutted of hard-coded .exe and delegate entirely to the new package-level complete_windows_ext_to_file_src/complete_windows_ext_to_file_dst, unifying string-level and path-level logic under the same version-stripping rules.
  • Cache version bumped to v2 to invalidate stale compiled registries.

Confidence Score: 5/5

Safe to merge — the change is well-tested and additive; all existing tests are adapted and a comprehensive new suite verifies the new paths.

The implementation consistently mirrors documented upstream aqua behavior. append_str_ext correctly handles windows_ext values with or without a leading dot, file_ext_is_empty is shared between the string and path code paths eliminating the previous divergence, and asset_strs preserves insertion-ordered priority so the fully-processed candidate is always tried before the raw fallback. No correctness issues were found.

No files require special attention.

Important Files Changed

Filename Overview
crates/aqua-registry/src/file_ext.rs New module centralizing version-aware extension detection; boundary logic is correctly UTF-8 aware and the is_likely_file_extension heuristic correctly excludes digit-only segments and separator chars
crates/aqua-registry/src/types.rs Migrates complete_windows_ext to Option<bool>, adds windows_ext and append_ext fields, implements append_ext/complete_windows_ext_to_asset/complete_windows_ext_to_file_src/complete_windows_ext_to_file_dst, and reworks asset_strs to include both finished and raw candidates; logic faithfully mirrors aqua upstream
src/backend/aqua.rs Backend complete_windows_ext and complete_windows_dst_ext helpers now delegate to the package-level methods instead of hard-coding .exe; the path-level functions correctly extract the filename component before delegating
crates/aqua-registry/src/cache.rs Cache version bumped from v1 to v2 to invalidate compiled registry caches after struct changes

Reviews (5): Last reviewed commit: "fix(aqua): bump compiled registry cache ..." | Re-trigger Greptile

Comment thread crates/aqua-registry/src/types.rs
Comment thread crates/aqua-registry/src/types.rs
@risu729 risu729 force-pushed the codex-20260531-172732-ad2d98 branch from b270194 to d97f215 Compare May 31, 2026 09:31
@risu729 risu729 changed the title fix(aqua): support windows extension semantics fix(aqua): mirror aqua windows extension semantics May 31, 2026
@risu729 risu729 force-pushed the codex-20260531-172732-ad2d98 branch from d97f215 to 5dcea01 Compare May 31, 2026 17:58
@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR refactors Windows extension handling in the aqua registry and backend from fixed boolean configuration to optional, package-driven behavior. A new file extension utility module extracts "real" extensions while respecting version substrings. The AquaPackage type now supports optional Windows extension settings with type-based defaults, and backend helpers use this configuration to intelligently complete filenames. The cache version is bumped to invalidate old entries.

Changes

Windows Extension Handling Refactor

Layer / File(s) Summary
File Extension Extraction Utilities
crates/aqua-registry/src/file_ext.rs, crates/aqua-registry/src/lib.rs
New file_ext module provides append_str_ext, file_ext, and file_ext_is_empty to extract genuine file extensions while stripping version substrings using boundary-aware matching and validation. Rejects numeric or separator-containing patterns.
AquaPackage Configuration Refactoring
crates/aqua-registry/src/types.rs
Updated complete_windows_ext and append_ext fields to Option<bool> with None defaults, added public methods windows_ext() and complete_windows_ext_enabled() with package-type-based defaults, refactored asset/URL generation to separate extension appending from finishing, and updated override merging to conditionally apply settings.
Backend Windows Extension Completion
src/backend/aqua.rs
Replaced boolean-based helpers with package-driven complete_windows_ext and complete_windows_dst_ext that use AquaPackage configuration and inspect resolved filename extensions. Updated install(), srcs_for_platform(), and file_link_for_version() to use new helpers, expanded test coverage for version-qualified and custom extension cases.
Registry Cache Version Bump
crates/aqua-registry/src/cache.rs
Incremented compiled cache version from v1 to v2 to invalidate previous cache entries.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

A rabbit hops through Windows paths,
No version strings obscure the facts,
Extensions gleam, now truly real—
With .jar and .bat in the deal! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 63.16% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(aqua): mirror aqua windows extension semantics' clearly and specifically summarizes the main change: aligning aqua windows extension handling with upstream aqua behavior and semantics.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@risu729 risu729 force-pushed the codex-20260531-172732-ad2d98 branch from 5dcea01 to ef0691a Compare May 31, 2026 18:01
@risu729

This comment was marked as outdated.

@risu729 risu729 marked this pull request as ready for review June 2, 2026 09:33

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/aqua-registry/src/types.rs`:
- Around line 615-628: In complete_windows_ext_to_asset, when handling the raw
format (the branch if self.format == "raw"), avoid unconditionally calling
complete_windows_ext(s) because that can double-append a custom Windows
extension (e.g., tool.bat -> tool.bat.bat); instead, first check whether the
rendered name already has a file extension (reuse os_file_ext_is_empty(s, v))
and only call complete_windows_ext(s) if os_file_ext_is_empty(s, v) returns
true; update the raw branch to mirror the non-raw logic that guards
complete_windows_ext behind os_file_ext_is_empty.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 54bc7e95-28cb-499f-b72e-312a323219ce

📥 Commits

Reviewing files that changed from the base of the PR and between 310e325 and 0b2e2a7.

📒 Files selected for processing (5)
  • crates/aqua-registry/src/cache.rs
  • crates/aqua-registry/src/file_ext.rs
  • crates/aqua-registry/src/lib.rs
  • crates/aqua-registry/src/types.rs
  • src/backend/aqua.rs

Comment on lines +615 to +628
fn complete_windows_ext_to_asset(&self, s: &str, v: &str, os: &str) -> Result<String> {
if os != "windows" || s.ends_with(".exe") || s.ends_with(".jar") {
return Ok(s.to_string());
}
if self.format == "raw" {
return Ok(self.complete_windows_ext(s));
}
if !self.format.is_empty() {
return Ok(s.to_string());
}
if self.os_file_ext_is_empty(s, v) {
return Ok(self.complete_windows_ext(s));
}
Ok(s.to_string())

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't double-append custom Windows extensions for raw assets/URLs.

When format == "raw", this branch appends windows_ext() without first checking whether the rendered name already has a real extension. A package that sets windows_ext: ".bat" and already renders tool.bat will become tool.bat.bat, which breaks Windows asset/url resolution.

Proposed fix
     fn complete_windows_ext_to_asset(&self, s: &str, v: &str, os: &str) -> Result<String> {
         if os != "windows" || s.ends_with(".exe") || s.ends_with(".jar") {
             return Ok(s.to_string());
         }
         if self.format == "raw" {
-            return Ok(self.complete_windows_ext(s));
+            return Ok(if self.os_file_ext_is_empty(s, v) {
+                self.complete_windows_ext(s)
+            } else {
+                s.to_string()
+            });
         }
         if !self.format.is_empty() {
             return Ok(s.to_string());
         }
         if self.os_file_ext_is_empty(s, v) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/aqua-registry/src/types.rs` around lines 615 - 628, In
complete_windows_ext_to_asset, when handling the raw format (the branch if
self.format == "raw"), avoid unconditionally calling complete_windows_ext(s)
because that can double-append a custom Windows extension (e.g., tool.bat ->
tool.bat.bat); instead, first check whether the rendered name already has a file
extension (reuse os_file_ext_is_empty(s, v)) and only call
complete_windows_ext(s) if os_file_ext_is_empty(s, v) returns true; update the
raw branch to mirror the non-raw logic that guards complete_windows_ext behind
os_file_ext_is_empty.

@jdx jdx merged commit 08df5ea into jdx:main Jun 2, 2026
33 checks passed
@risu729 risu729 deleted the codex-20260531-172732-ad2d98 branch June 2, 2026 23:27
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