Skip to content

Conversation

@o-l-a-v
Copy link
Contributor

@o-l-a-v o-l-a-v commented Oct 13, 2025

Description

Expand-7zipArchive have had problems with apps where:

This PR tries to fix all that.

Motivation and Context

Merging this might break some manifests that have workarounds to delete leftovers after $ExtractDir. Here are some I know of:

How Has This Been Tested?

Checklist:

  • I have read the Contributing Guide.
  • I have ensured that I am targeting the develop branch.
  • I have updated the documentation accordingly.
  • I have updated the tests accordingly.
  • I have added an entry in the CHANGELOG.

Summary by CodeRabbit

  • New Features

    • Improved partial-extraction workflow: when extracting a subdirectory, files are unpacked to a temporary location and moved into place to ensure reliable results across archive types.
  • Bug Fixes

    • More reliable handling of destination paths and removal of temporary files to prevent leftovers and placement errors.
    • Clearer errors and more consistent external tool invocation for decompression.
  • Documentation

    • Updated changelog documenting decompression and extraction improvements.

@coderabbitai
Copy link

coderabbitai bot commented Oct 13, 2025

Walkthrough

Updated changelog and refactored decompression handlers in lib/decompress.ps1: archive type detection, consistent external-command invocation, trimmed/normalized destinations, extract-to-temp when ExtractDir is set, then move/cleanup; uniform Remove-Item -Path usage and log cleanup adjustments.

Changes

Cohort / File(s) Summary
Changelog entry
CHANGELOG.md
Adds entry noting that Expand-7zipArchive and Expand-ZipArchive expand into a temp directory when ExtractDir is provided.
Core decompression refactor
lib/decompress.ps1
- Centralized changes across archive handlers: Expand-7zipArchive, Expand-ZipArchive, Expand-MsiArchive, Expand-InnoArchive, Expand-DarkArchive, Expand-ZstdArchive.
- Detects tar archives (IsTar) and adjusts listing/extraction flows.
- Trim/normalize DestinationPath; when ExtractDir provided, extract to a temp path under $env:TEMP then move ExtractDir contents to original destination and remove temp.
- Use Get-Command -Name '7z' for 7z lookup; construct log paths with Split-Path -Path / friendly_path messages.
- Standardize external calls to Invoke-ExternalCommand -FilePath -ArgumentList and status checks (-not $Status).
- Refine post-extract cleanup: remove temp dirs, remove log only if it is a leaf, and consistently use Remove-Item -Path; adjust archive-part removal via Get-ChildItem -Path.
- Minor comment/casing/formatting tweaks for consistency.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Caller
  participant Decompress as lib/decompress.ps1
  participant External as 7z/tar/unzip/msiexec
  participant FS as FileSystem

  Caller->>Decompress: Expand-*(archive, DestinationPath, ExtractDir?)
  Decompress->>Decompress: Trim/normalize DestinationPath\nDetect archive type (IsTar?)
  alt ExtractDir provided
    Decompress->>FS: Create tempDestination under $env:TEMP
    alt Non-tar
      Decompress->>External: Invoke extraction (FilePath + ArgumentList, include -ir!ExtractDir\*)
      External-->>Decompress: Exit status
      Decompress->>FS: Move tempDestination\ExtractDir -> Original DestinationPath
    else Tar
      Decompress->>External: List/extract tar (FilePath + ArgumentList)
      External-->>Decompress: Exit status
      Decompress->>FS: Arrange/move tar contents -> DestinationPath
    end
    Decompress->>FS: Remove tempDestination and cleanup logs (only if leaf)
  else No ExtractDir
    Decompress->>External: Invoke extraction -> DestinationPath
    External-->>Decompress: Exit status
  end
  Decompress->>FS: Optional remove original archive parts (Get-ChildItem -Path / Remove-Item -Path)
  Decompress-->>Caller: Return status/result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

A hop, a zip, a tarball trip—
I nibble paths where temp nests slip.
I tuck ExtractDir in a cozy place,
then hop it home with gentle grace.
Logs and crumbs? I sweep the space. 🐰📦

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning In addition to fixing Expand-7zipArchive, the changes also apply the temporary extraction pattern to Expand-ZipArchive, Expand-MsiArchive, Expand-InnoArchive, Expand-DarkArchive, and Expand-ZstdArchive, which are not covered by the linked issue #6515 focused solely on 7z extraction behavior. Limit the scope of this pull request to only the Expand-7zipArchive changes required by issue #6515 or include additional linked issues that authorize similar modifications for the other archive functions.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues Check ✅ Passed The pull request implements extracting 7z archives to a temporary directory and then moving the specified ExtractDir contents back to the target path, directly addressing the nested‐folder removal issue described in issue #6515. This approach ensures that the top‐level folder is correctly removed regardless of ExtractDir depth, satisfying the linked issue’s requirements.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Title Check ✅ Passed The title clearly references the issue number and the specific Expand-7zipArchive bug it fixes, directly tying to the main change in this pull request. It identifies the problem scope and developer intent in a single sentence. Although it includes some extra wording like “Idea 1” and nested quotes, it still summarizes the central fix for deeper $ExtractDir depths.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@o-l-a-v o-l-a-v changed the title Expand zip and 7z with ExtractDir: Extract to temp Expand zip and 7z with ExtractDir: Extract to temp before movedir Oct 13, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 20a178b and 5d39120.

📒 Files selected for processing (2)
  • CHANGELOG.md (1 hunks)
  • lib/decompress.ps1 (4 hunks)
🔇 Additional comments (4)
lib/decompress.ps1 (4)

97-106: TEMP extraction for ExtractDir looks good; verify spaces in ExtractDir.

7‑Zip’s -ir! filter can be sensitive to spaces. Our arg is one token, which should be fine. Please verify with an ExtractDir containing spaces.


115-118: Invocation/logging improvements LGTM.

Switch to -FilePath/-ArgumentList and friendly_path -path is clear and consistent.


130-135: Non-tar cleanup LGTM; tar path covered by earlier fix.

Moving from TEMP to destination and removing TEMP dir looks correct for non-tar flows.


287-303: Zip: TEMP extraction for ExtractDir LGTM.

Casting to [string], using TEMP GUID, moving back, and cleanup are correct.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 20a178b and 4deb0df.

📒 Files selected for processing (2)
  • CHANGELOG.md (1 hunks)
  • lib/decompress.ps1 (4 hunks)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
lib/decompress.ps1 (2)

95-95: Broaden tar detection to include tzst/tlz variants

Current regex misses .tzst/.tar.zst and .tlz. Consider:

-$IsTar = ((strip_ext -fname $Path) -match '\.tar$') -or ($Path -match '\.t[abgpx]z2?$')
+$IsTar = ((strip_ext -fname $Path) -match '\.tar$') -or
+         ($Path -match '\.(tgz|tbz2?|txz|tlz|tzst)$') -or
+         ($Path -match '\.t(ar\.)?(gz|bz2?|xz|lz|zst)$')

This improves robustness across common compressed-tar extensions.


98-103: Nit: Prefer ToString() for GUID and consistent path join

No functional issue, but this is more idiomatic and explicit:

-$DestinationPathTemp = [System.IO.Path]::Combine($env:TEMP, [guid]::NewGuid().'Guid')
+$DestinationPathTemp = [System.IO.Path]::Combine($env:TEMP, ([guid]::NewGuid().ToString()))
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 20a178b and 4deb0df.

📒 Files selected for processing (2)
  • CHANGELOG.md (1 hunks)
  • lib/decompress.ps1 (4 hunks)
⏰ 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). (1)
  • GitHub Check: WindowsPowerShell
🔇 Additional comments (2)
CHANGELOG.md (1)

18-18: Changelog entry looks good

Accurately describes the new temp-extraction behavior for 7z/zip with ExtractDir.

lib/decompress.ps1 (1)

287-306: Zip temp-extraction flow LGTM

Trims trailing slashes, extracts to TEMP when ExtractDir is set, then moves and cleans up. Matches objectives and avoids prior empty-dir pitfalls.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
CHANGELOG.md (1)

18-18: Clarify behavior, reference #6093, and add a breaking note.

Spell out "extract to temp first, then move," include the feature request link, and note potential manifest impact.

- - **decompress:** Expand to temp directory if `$ExtractDir` is specified with `Expand-7zipArchive` and `Expand-ZipArchive`, to make it more robust ([#6515](https://github.com/ScoopInstaller/Scoop/issues/6515))
+ - **decompress:** Extract to a temporary directory first when `$ExtractDir` is specified for `Expand-7zipArchive` and `Expand-ZipArchive`, then move into `$ExtractDir` to avoid path-collision/cleanup issues ([#6515](https://github.com/ScoopInstaller/Scoop/issues/6515), [#6093](https://github.com/ScoopInstaller/Scoop/issues/6093))
+   - BREAKING: Changes extraction semantics when `extract_dir` is used; manifests relying on post-extraction cleanup workarounds may need updates.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4deb0df and 5b8b248.

📒 Files selected for processing (1)
  • CHANGELOG.md (1 hunks)

@o-l-a-v o-l-a-v marked this pull request as draft October 13, 2025 17:07
@o-l-a-v o-l-a-v changed the title Expand zip and 7z with ExtractDir: Extract to temp before movedir Fix #6515 "Expand-7zipArchive won't remove top folder if $ExtractDir depth exceeds 2" - Idea 1 Oct 13, 2025
@z-Fng
Copy link
Member

z-Fng commented Oct 13, 2025

Merging this might break some manifests that have workarounds to delete leftovers after $ExtractDir. Here are some I know of:

This isn't specifically meant to remove leftovers ($dir\msi\.rsrc) -- deleting $DestinationPath ($dir\msi) is a common operation.

"Expand-7zipArchive \"$dir\\$fname\" \"$dir\\msi\" -ExtractDir '.rsrc\\1033\\PAYLOAD' -Removal",
"Remove-Item \"$dir\\msi\", \"$dir\\extracted\", \"$dir\\install.log\" -Force -Recurse"

As far as I'm aware, there aren't any related workarounds to delete leftovers after $ExtractDir.

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