Skip to content

fix(aqua): strip aqua asset formats from AssetWithoutExt#10104

Draft
risu729 wants to merge 12 commits into
jdx:mainfrom
risu729:fix/aqua-windows-compressed-bins
Draft

fix(aqua): strip aqua asset formats from AssetWithoutExt#10104
risu729 wants to merge 12 commits into
jdx:mainfrom
risu729:fix/aqua-windows-compressed-bins

Conversation

@risu729

@risu729 risu729 commented May 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • render {{.AssetWithoutExt}} with aqua's asset-format detector instead of a shorter hard-coded suffix strip list
  • share that detector with detect_format via AQUA_ASSET_FORMATS / remove_ext_from_asset
  • keep Windows e2e coverage for gzipped versioned binaries and zstd-compressed executables

Depends on #10241 for archive extraction API changes (extract_archive / decompress_file, ArchiveFormat::from_ext). This PR only fixes template suffix stripping; compressed Windows installs rely on #10241 routing .zst assets through decompress_file to the registry bin path.

Context

This addresses the remaining AssetWithoutExt compressed-asset behavior from GitHub Discussions #10057 / #10064.

The reporter in #10064 confirmed aqua:evilmartians/lefthook is fixed in v2026.6.0. That release includes #10167, which fixed the Windows extension/version-dot path needed for the .gz lefthook install. This PR is still needed because v2026.6.0 did not change AquaFile::template_ctx to strip all aqua archive/compression suffixes from {{.AssetWithoutExt}}: it strips .gz, but not .zst.

This deliberately does not use the version-aware executable extension detector added by #10167. AssetWithoutExt needs aqua archive/compression format semantics, not generic path-extension detection.

Suffixes

Before this PR, AssetWithoutExt stripped only a short hard-coded list. This PR uses the full aqua asset-format set (including .zst, .tar.br, .dmg, etc.).

The openai/codex aqua package renders codex-x86_64-pc-windows-msvc.exe.zst and uses {{.AssetWithoutExt}} as the file source. Without this PR, mise looks for the .zst path after extraction instead of codex-x86_64-pc-windows-msvc.exe.

Tests

  • cargo test -p aqua-registry test_remove_ext_from_asset_uses_aqua_asset_formats
  • cargo test -p aqua-registry test_aqua_file_src_asset_without_ext_strips_zst
  • Windows: e2e-win/backend/aqua_bin_path.Tests.ps1

@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 refactors asset format detection and extension stripping in the aqua-registry crate, and updates the Windows extension completion logic in the aqua backend to ignore version numbers when detecting existing extensions. This prevents issues like duplicate extensions on files containing version dots. Feedback on these changes highlights opportunities to optimize string allocations in asset_without_ext, improve robustness in path_ext_ignoring_version by operating only on the filename rather than the entire path, and remove the redundant aqua_file_src helper function.

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

greptile-apps Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the AssetWithoutExt aqua template variable to strip all aqua archive/compression suffixes (e.g. .zst, .tar.br, .dmg) instead of a short hard-coded list. It also renames TarFormatArchiveFormat, splits untar into extract_archive and decompress_file, and adds Windows e2e coverage for gzip and zstd-compressed executables.

  • Core fix: template_ctx now uses remove_ext_from_asset / AQUA_ASSET_FORMATS so AssetWithoutExt for openai/codex (.exe.zst) resolves to the correct bare executable path.
  • API refactor: TarFormat::from_ext (returning Self) becomes ArchiveFormat::from_ext (returning Option<Self>); callers are updated uniformly; format = "raw" in the aqua extraction branch now copies the binary instead of erroring.
  • Unimplemented formats (tar.br, rar, etc.) are enumerated in AQUA_UNIMPLEMENTED_EXTRACTION_FORMATS and bail with a clear message.

Confidence Score: 5/5

Safe to merge — the change is well-scoped, all extraction paths are covered by the new dispatch logic, and new tests directly exercise the previously broken zst strip case.

The core fix (replacing the hard-coded suffix chain with AQUA_ASSET_FORMATS iteration) is straightforward and verified by unit tests. The ArchiveFormat rename is mechanical and consistent across all callers. The new format=="raw" branch correctly handles raw-format packages that the old code would have errored on. No pre-existing invariants are broken.

No files require special attention.

Important Files Changed

Filename Overview
crates/aqua-registry/src/types.rs Core fix: introduces AQUA_ASSET_FORMATS, remove_ext_from_asset, and asset_without_ext; replaces template_ctx's hard-coded strip chain; detect_format simplified to delegate to remove_ext_from_asset; well-tested.
src/file.rs TarFormat renamed to ArchiveFormat with Option-returning from_ext; new decompress_file and extract_archive APIs added; untar restricted to tar formats; tbz alias added to TarBz2; tests updated and new tests for the new APIs.
src/backend/aqua.rs Extraction dispatch unified via ArchiveFormat enum matching; format=="raw" branch added to correctly copy raw binaries; SLSA check updated to use Option-returning from_ext with descriptive error.
src/backend/http.rs TarFormat → ArchiveFormat rename; extract_compressed_binary now calls decompress_file; extract_archive replaces untar; logic unchanged.
e2e-win/backend/aqua_bin_path.Tests.ps1 Adds two Windows e2e tests: gzip-versioned lefthook binary and zstd-compressed codex executable via aqua backend.

Reviews (16): Last reviewed commit: "fix(aqua-registry): document unimplement..." | Re-trigger Greptile

Comment thread src/backend/aqua.rs Outdated
@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch 2 times, most recently from a47734e to eef1558 Compare May 27, 2026 20:43
Comment thread src/backend/aqua.rs Outdated
@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch 4 times, most recently from 29619af to d375c28 Compare May 31, 2026 18:04
@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1df74e06-6a06-4eb0-acc0-354aece84389

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR refactors asset format and archive extension handling in aqua-registry by introducing shared helper functions that centralize format detection and normalize known archive shorthand formats, then refactoring existing callers to use these helpers. It includes unit tests validating the new behavior and Windows E2E tests for binary installation.

Changes

Asset Format and Extension Handling Refactoring

Layer / File(s) Summary
Asset format and extension handling abstraction
crates/aqua-registry/src/types.rs
Introduces shared constants and helper functions (AQUA_ASSET_FORMATS, remove_ext_from_asset, asset_without_ext) that centralize removal of known archive suffixes, normalize shorthand formats (e.g., tgztar.gz, txztar.xz, tbz/tbz2tar.bz2), and fall back to "raw". Refactors AquaPackage::detect_format and AquaFile::template_ctx to use the new shared logic instead of inline suffix matching.
Format handling validation
crates/aqua-registry/src/types.rs, e2e-win/backend/aqua_bin_path.Tests.ps1
Adds Rust unit tests validating format detection and extension stripping across known Aqua archive formats including .zst, and adds Windows E2E tests verifying the aqua backend correctly installs gzipped and zstd-compressed Windows binaries.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • jdx/mise#10167: Both PRs change aqua-registry's extension/format derivation in crates/aqua-registry/src/types.rs—this PR refactors archive/asset extension stripping (detect_format, AssetWithoutExt), while the related PR mirrors aqua Windows extension semantics by reworking extension completion and format computation from "asset without appended ext" logic.

Poem

A rabbit hops through formats wide,
From tgz to tar.gz with pride,
Extensions stripped with helper's care,
Windows binaries install fair,
Archive magic—helpers declare! 🐰📦

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% 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
Title check ✅ Passed The title 'fix(aqua): strip aqua asset formats from AssetWithoutExt' accurately and concisely describes the main change: refactoring the asset format stripping logic to use aqua's centralized asset-format detector instead of a hardcoded list.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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

This comment was marked as outdated.

@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch from 972b5ef to ca30edf Compare June 4, 2026 20:55
@risu729 risu729 changed the title fix(aqua): handle compressed Windows binary names fix(aqua): strip aqua asset formats from AssetWithoutExt Jun 5, 2026
@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch from ca30edf to f37e519 Compare June 5, 2026 18:25
@risu729 risu729 marked this pull request as ready for review June 5, 2026 18:44

@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: 2

🤖 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 1428-1448: The test
test_remove_ext_from_asset_uses_aqua_asset_formats is missing assertions for the
shorthand tar-based suffixes; update that test to add assertions calling
remove_ext_from_asset for filenames ending with .tbr, .tlz4, and .tsz and assert
they normalize to ("name", "tar.br"), ("name", "tar.lz4"), and ("name",
"tar.zst") respectively (e.g., "tool.tbr" -> ("tool","tar.br"), "tool.tlz4" ->
("tool","tar.lz4"), "tool.tsz" -> ("tool","tar.zst")); keep the test name and
placement and follow the same assert_eq! style as the other cases so the
normalization behavior is covered.
- Around line 891-898: normalize_asset_format currently maps
"tgz","txz","tbz","tbz2" but misses other tar-based shorthands present in
AQUA_ASSET_FORMATS; update the normalize_asset_format function to also map "tbr"
-> "tar.br", "tlz4" -> "tar.lz4", and "tsz" -> "tar.sz" so downstream checks
like format.starts_with("tar") (used in install logic) correctly route these
archives to the untar handler.
🪄 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: 7afc5978-0a73-4902-85d7-6cb6c06db3f0

📥 Commits

Reviewing files that changed from the base of the PR and between ebf4795 and f37e519.

📒 Files selected for processing (2)
  • crates/aqua-registry/src/types.rs
  • e2e-win/backend/aqua_bin_path.Tests.ps1

Comment thread crates/aqua-registry/src/types.rs Outdated
Comment on lines +891 to +898
fn normalize_asset_format(format: &'static str) -> &'static str {
match format {
"tgz" => "tar.gz",
"txz" => "tar.xz",
"tbz2" | "tbz" => "tar.bz2",
_ => format,
}
}

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 | 🔴 Critical | ⚡ Quick win

Missing normalizations for tar-based shorthand formats.

The function normalizes tgz, txz, tbz, and tbz2 but does not normalize tbr, tlz4, or tsz to their expanded forms (tar.br, tar.lz4, tar.sz). Since these shorthand formats are explicitly included in AQUA_ASSET_FORMATS (line 869), files with these extensions will be detected but not normalized.

This will cause runtime failures in the installer: the aqua backend's install logic checks format.starts_with("tar") to route tar-based archives to the untar handler, but unnormalized formats like "tbr" won't match and will fall through to bail!("unsupported format: {}", format).

🔧 Proposed fix to normalize all tar-based shorthands
 fn normalize_asset_format(format: &'static str) -> &'static str {
     match format {
         "tgz" => "tar.gz",
         "txz" => "tar.xz",
         "tbz2" | "tbz" => "tar.bz2",
+        "tbr" => "tar.br",
+        "tlz4" => "tar.lz4",
+        "tsz" => "tar.sz",
         _ => format,
     }
 }

Based on learnings from context snippet 1 (src/backend/aqua.rs:2242-2353), which shows the installer branches on format.starts_with("tar") for tar extraction.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn normalize_asset_format(format: &'static str) -> &'static str {
match format {
"tgz" => "tar.gz",
"txz" => "tar.xz",
"tbz2" | "tbz" => "tar.bz2",
_ => format,
}
}
fn normalize_asset_format(format: &'static str) -> &'static str {
match format {
"tgz" => "tar.gz",
"txz" => "tar.xz",
"tbz2" | "tbz" => "tar.bz2",
"tbr" => "tar.br",
"tlz4" => "tar.lz4",
"tsz" => "tar.sz",
_ => format,
}
}
🤖 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 891 - 898,
normalize_asset_format currently maps "tgz","txz","tbz","tbz2" but misses other
tar-based shorthands present in AQUA_ASSET_FORMATS; update the
normalize_asset_format function to also map "tbr" -> "tar.br", "tlz4" ->
"tar.lz4", and "tsz" -> "tar.sz" so downstream checks like
format.starts_with("tar") (used in install logic) correctly route these archives
to the untar handler.

Comment on lines +1428 to +1448
#[test]
fn test_remove_ext_from_asset_uses_aqua_asset_formats() {
assert_eq!(
remove_ext_from_asset("tfcmt_linux_amd64.tar.gz"),
("tfcmt_linux_amd64", "tar.gz")
);
assert_eq!(
remove_ext_from_asset("tfcmt_linux_amd64.tgz"),
("tfcmt_linux_amd64", "tar.gz")
);
assert_eq!(remove_ext_from_asset("tool.tar.br"), ("tool", "tar.br"));
assert_eq!(
remove_ext_from_asset("codex-x86_64-pc-windows-msvc.exe.zst"),
("codex-x86_64-pc-windows-msvc.exe", "zst")
);
assert_eq!(remove_ext_from_asset("tfcmt.js"), ("tfcmt.js", "raw"));
assert_eq!(
remove_ext_from_asset("tfcmt_windows_amd64.exe"),
("tfcmt_windows_amd64.exe", "raw")
);
}

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 | 🟡 Minor | ⚡ Quick win

Add test coverage for shorthand format normalization.

The test verifies that remove_ext_from_asset strips known extensions and handles the common .tgz"tar.gz" normalization, but does not cover the newly supported tar-based shorthands (.tbr, .tlz4, .tsz). Adding assertions for these formats will prevent regressions if the normalization logic is updated.

🧪 Suggested test additions
     assert_eq!(
         remove_ext_from_asset("tfcmt_linux_amd64.tgz"),
         ("tfcmt_linux_amd64", "tar.gz")
     );
+    assert_eq!(
+        remove_ext_from_asset("tool.tbr"),
+        ("tool", "tar.br")
+    );
+    assert_eq!(
+        remove_ext_from_asset("tool.tlz4"),
+        ("tool", "tar.lz4")
+    );
+    assert_eq!(
+        remove_ext_from_asset("tool.tsz"),
+        ("tool", "tar.sz")
+    );
     assert_eq!(remove_ext_from_asset("tool.tar.br"), ("tool", "tar.br"));
🤖 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 1428 - 1448, The test
test_remove_ext_from_asset_uses_aqua_asset_formats is missing assertions for the
shorthand tar-based suffixes; update that test to add assertions calling
remove_ext_from_asset for filenames ending with .tbr, .tlz4, and .tsz and assert
they normalize to ("name", "tar.br"), ("name", "tar.lz4"), and ("name",
"tar.zst") respectively (e.g., "tool.tbr" -> ("tool","tar.br"), "tool.tlz4" ->
("tool","tar.lz4"), "tool.tsz" -> ("tool","tar.zst")); keep the test name and
placement and follow the same assert_eq! style as the other cases so the
normalization behavior is covered.

@risu729 risu729 marked this pull request as draft June 5, 2026 18:52
@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown

This PR currently has merge conflicts. If this continues for 7 days, it will be closed automatically.

This is warning day 1 of 7.

Please update the PR when you have a chance. Feel free to reopen or create a new PR if it is closed and you'd like to continue working on it.

This comment was generated by an automated workflow.

@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch from f37e519 to 1470420 Compare June 6, 2026 01:47
@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch from 1470420 to 44e4dbb Compare June 6, 2026 02:14
@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch from 6163968 to 93cda74 Compare June 6, 2026 02:22
TarFormat::from_ext handles tgz/tbz/txz aliases at extraction time.
@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch from 93cda74 to ccda558 Compare June 6, 2026 02:27
@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch from ccda558 to fcc0062 Compare June 6, 2026 02:30
Call TarFormat::from_ext and unarchive directly from the aqua backend.
@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch from fcc0062 to 9a1dc3b Compare June 6, 2026 02:33
@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch from 9a1dc3b to 8b206a2 Compare June 6, 2026 15:36
- rename TarFormat to ArchiveFormat; from_ext returns Option
- replace unarchive/ArchiveOptions with extract_archive/ExtractOptions
- route aqua compressed assets through decompress_file directly
@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch from 8b206a2 to a9e6b11 Compare June 7, 2026 03:40
@risu729 risu729 force-pushed the fix/aqua-windows-compressed-bins branch from a9e6b11 to 4dcbca2 Compare June 7, 2026 03:48
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

This PR currently has failing checks. If this continues for 7 days, it will be closed automatically.

This is warning day 1 of 7.

Please update the PR when you have a chance. Feel free to reopen or create a new PR if it is closed and you'd like to continue working on it.

This comment was generated by an automated workflow.

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

This PR currently has failing checks. If this continues for 7 days, it will be closed automatically.

This is warning day 2 of 7.

Please update the PR when you have a chance. Feel free to reopen or create a new PR if it is closed and you'd like to continue working on it.

This comment was generated by an automated workflow.

@github-actions

Copy link
Copy Markdown

This PR currently has failing checks. If this continues for 7 days, it will be closed automatically.

This is warning day 3 of 7.

Please update the PR when you have a chance. Feel free to reopen or create a new PR if it is closed and you'd like to continue working on it.

This comment was generated by an automated workflow.

@github-actions

Copy link
Copy Markdown

This PR currently has failing checks. If this continues for 7 days, it will be closed automatically.

This is warning day 4 of 7.

Please update the PR when you have a chance. Feel free to reopen or create a new PR if it is closed and you'd like to continue working on it.

This comment was generated by an automated workflow.

@github-actions

Copy link
Copy Markdown

This PR currently has failing checks. If this continues for 7 days, it will be closed automatically.

This is warning day 5 of 7.

Please update the PR when you have a chance. Feel free to reopen or create a new PR if it is closed and you'd like to continue working on it.

This comment was generated by an automated workflow.

@github-actions

Copy link
Copy Markdown

This PR currently has failing checks and merge conflicts. If this continues for 7 days, it will be closed automatically.

This is warning day 6 of 7.

Please update the PR when you have a chance. Feel free to reopen or create a new PR if it is closed and you'd like to continue working on it.

This comment was generated by an automated workflow.

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.

1 participant