Skip to content

♻️ Consolidate OwnerOptions and same_owner into PermissionStrategy#2582

Merged
ChanTsune merged 2 commits into
mainfrom
cli/refactor/permissions
Jan 7, 2026
Merged

♻️ Consolidate OwnerOptions and same_owner into PermissionStrategy#2582
ChanTsune merged 2 commits into
mainfrom
cli/refactor/permissions

Conversation

@ChanTsune
Copy link
Copy Markdown
Owner

@ChanTsune ChanTsune commented Jan 6, 2026

Refactor permission/ownership handling to follow the TimestampStrategy pattern, creating a single source of truth for all permission-related configuration.

Changes:

  • Add OwnerSource enum with NoRestore and FromSource variants
  • Change PermissionStrategy from Never/Always to Never/Preserve{owner}
  • Add PermissionStrategyResolver with context-specific resolution:
    • resolve_for_creation(): always FromSource (ownership stored)
    • resolve_for_extraction(): respects same_owner flag
  • Remove OwnerOptions struct and owner_options from CreateOptions
  • Update all command modules to use the new resolver pattern

This consolidation eliminates the scattered ownership concerns (OwnerOptions struct, same_owner boolean, PermissionStrategy enum) into a unified architecture where ownership handling is embedded within PermissionStrategy.

Summary by CodeRabbit

  • Refactor

    • Centralized permission and ownership handling across create, extract, append, and update for consistent resolver-driven behavior.
  • Bug Fixes

    • Improved ownership preservation and override resolution to ensure correct uid/gid and user/group application during archive operations.
  • New Features

    • Added a cross-platform chmod helper to unify file permission operations.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 6, 2026

📝 Walkthrough

Walkthrough

Introduce a resolver-based permission/ownership flow: add PermissionStrategyResolver and OwnerSource, remove OwnerOptions and related fields, update call sites to resolve uname/gname/uid/gid early, adjust CreateOptions and PathnameEditor::new signature, and add a crate-local chmod helper.

Changes

Cohort / File(s) Summary
Core permission types & API
cli/src/command/core.rs, cli/src/command/core/permission.rs
Add permission module with OwnerSource and PermissionStrategy enums; introduce PermissionStrategyResolver { … } and .resolve(); re-export types and remove legacy PermissionStrategy::from_flags.
Create / CreationContext
cli/src/command/create.rs, cli/src/command/create_*.rs*
Remove owner_options from CreationContext and CreateOptions; build KeepOptions using PermissionStrategyResolver and .resolve(); update PathnameEditor::new calls to pass an added boolean third argument.
Append command
cli/src/command/append.rs
Replace PermissionStrategy::from_flags usage with PermissionStrategyResolver { … }.resolve(); remove OwnerOptions construction; adjust CreateOptions initialization to omit owner fields and update PathnameEditor::new call.
Update command
cli/src/command/update.rs
Swap PermissionStrategy for PermissionStrategyResolver + .resolve(); drop OwnerOptions usage; update CreateOptions initialization accordingly.
Extract / ownership restoration
cli/src/command/extract.rs
Replace OwnerOptions with OwnerSource; add resolve_owner helper; change restore_metadata/restore_permissions signatures and call sites to use OwnerSource and resolver-driven semantics.
Stdio / CLI wiring
cli/src/command/stdio.rs
Early resolution of uname/gname and uid/gid via resolve_name_id; thread resolved values into PermissionStrategyResolver for create/extract/append/update; remove resolve_owner_options and owner_options plumbing.
Filesystem helper
cli/src/utils/fs.rs
Add pub(crate) fn chmod<P: AsRef<Path>>(path: P, mode: u16) -> io::Result<()> delegating to platform-specific implementations.

("create_.rs" denotes related helper files in the create flow updated similarly.)

Sequence Diagram

sequenceDiagram
    participant CLI as CLI Args
    participant NameResolver as resolve_name_id
    participant Resolver as PermissionStrategyResolver
    participant Strategy as PermissionStrategy
    participant Command as Command (create/extract/append/update)

    Note right of CLI: flags (keep/no_keep, same_owner, uname/gname, uid/gid, numeric_owner)
    CLI->>NameResolver: resolve uname/gname and uid/gid
    NameResolver-->>CLI: (uname, gname, uid, gid)
    CLI->>Resolver: construct with flags + resolved names/ids
    activate Resolver
    Resolver->>Strategy: .resolve()
    deactivate Resolver
    Strategy-->>Command: PermissionStrategy (+ OwnerSource)
    alt Preserve with OwnerSource
        Command->>Command: apply metadata/ownership from OwnerSource
    else Never
        Command->>Command: skip ownership restoration
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

break

Poem

🐰 I hopped through flags and names so dear,
Resolved the uid and gname with cheer,
A tiny resolver stitched owner seams,
Options trimmed like springtime dreams,
The archive hums while carrots cheer.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main refactoring: consolidating OwnerOptions and same_owner into PermissionStrategy, which aligns with the overall objectives and the substantial changes across multiple files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

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
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @ChanTsune, 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 significantly refactors the way file permissions and ownership are managed within the system. By introducing a unified PermissionStrategy and a dedicated PermissionStrategyResolver, it centralizes previously scattered logic, making the codebase more maintainable and easier to understand. The change eliminates the separate OwnerOptions struct, embedding ownership concerns directly into the permission strategy, which leads to a cleaner and more consistent API for handling file metadata.

Highlights

  • Unified Permission Handling: The pull request consolidates permission and ownership logic into a single, unified PermissionStrategy enum, mirroring the existing TimestampStrategy pattern for consistency and clarity.
  • New OwnerSource Enum: A new OwnerSource enum has been introduced with NoRestore and FromSource variants to explicitly define how ownership information should be handled during file operations (creation or extraction).
  • Refactored PermissionStrategy: The PermissionStrategy enum has been updated from simple Never/Always variants to Never/Preserve { owner: OwnerSource }, allowing for more granular control over ownership preservation.
  • Introduction of PermissionStrategyResolver: A PermissionStrategyResolver struct has been added to encapsulate the CLI-specific logic for resolving permission options into the appropriate PermissionStrategy, simplifying its usage across different command modules.
  • Removal of OwnerOptions: The OwnerOptions struct and its associated logic have been removed, as its concerns are now integrated directly into the new PermissionStrategy and OwnerSource enums, reducing redundancy.
  • Command Module Updates: All relevant command modules (append, create, extract, stdio, update) have been updated to utilize the new PermissionStrategyResolver and the refactored permission handling, ensuring consistent behavior.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions github-actions Bot added the cli This issue is about cli application label Jan 6, 2026
Copy link
Copy Markdown
Contributor

@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 (2)
cli/src/command/core.rs (2)

704-712: Consider replacing unreachable!() with a debug assertion or explicit error.

During creation, NoRestore should never occur since same_owner: true is always passed. However, unreachable!() will panic at runtime if this invariant is violated. Consider using debug_assert! with a fallback, or returning an error for better resilience against future refactoring.

🔎 Alternative approach
-            OwnerSource::NoRestore => unreachable!("NoRestore is not used during creation"),
+            OwnerSource::NoRestore => {
+                debug_assert!(false, "NoRestore is not used during creation");
+                // Fallback: use filesystem metadata
+                (None, None, None, None)
+            }

745-753: Same concern about unreachable!() in Windows path.

The Windows permission handling has the same unreachable!() for NoRestore. Applying the same resilience pattern here would be beneficial.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 080cb67 and 5484362.

📒 Files selected for processing (7)
  • cli/src/command/append.rs
  • cli/src/command/core.rs
  • cli/src/command/core/permission.rs
  • cli/src/command/create.rs
  • cli/src/command/extract.rs
  • cli/src/command/stdio.rs
  • cli/src/command/update.rs
🧰 Additional context used
🧬 Code graph analysis (3)
cli/src/command/extract.rs (4)
cli/src/utils/os/unix/fs/owner.rs (3)
  • from_uid (8-16)
  • name (30-32)
  • name (70-72)
lib/src/entry/meta.rs (2)
  • uname (210-212)
  • gname (240-242)
cli/src/utils/fs.rs (1)
  • lchown (49-67)
cli/src/utils/os/windows/fs.rs (3)
  • lchown (25-36)
  • lchown (68-68)
  • lchown (69-69)
cli/src/command/stdio.rs (1)
lib/src/entry/meta.rs (2)
  • uname (210-212)
  • gname (240-242)
cli/src/command/create.rs (1)
cli/src/command/core.rs (3)
  • collect_items_from_paths (365-379)
  • create_entry (609-650)
  • entry_option (652-672)
⏰ 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). (11)
  • GitHub Check: tier1 (windows-11-arm, stable)
  • GitHub Check: tier1 (macos-latest, stable)
  • GitHub Check: tier1 (ubuntu-22.04-arm, nightly)
  • GitHub Check: tier1 (windows-latest, stable)
  • GitHub Check: Test WebAssembly (nightly-2025-12-09, wasm32-unknown-unknown)
  • GitHub Check: Test WebAssembly (nightly-2025-12-09, wasm32-wasip2)
  • GitHub Check: tier1 (windows-11-arm, nightly)
  • GitHub Check: tier1 (macos-latest, beta)
  • GitHub Check: tier1 (windows-latest, beta)
  • GitHub Check: tier1 (windows-11-arm, beta)
  • GitHub Check: tier1 (windows-11-arm, stable)
🔇 Additional comments (14)
cli/src/command/core/permission.rs (1)

1-25: Well-structured permission types.

The new OwnerSource and PermissionStrategy enums cleanly model the dual-mode semantics for creation vs. extraction. The documentation comments clearly explain how each variant behaves in different contexts.

cli/src/command/core.rs (2)

166-173: KeepOptions no longer Copy due to String fields.

The removal of Copy from KeepOptions is correct since PermissionStrategy::Preserve now contains OwnerSource::FromSource with Option<String> fields. This is a necessary breaking change for callers that relied on implicit copying.


251-279: PermissionStrategyResolver logic is correct.

The resolver correctly handles the priority: no_keep_permission → Never, keep_permission → Preserve with owner handling based on same_owner. The numeric_owner flag appropriately sets empty strings for uname/gname to suppress name storage.

cli/src/command/append.rs (1)

388-402: Correct resolver usage for append operation.

The PermissionStrategyResolver is properly configured with same_owner: true for append operations, which is the expected behavior since ownership is always stored during creation. The ownership override fields (uname, gname, uid, gid, numeric_owner) are correctly passed through.

cli/src/command/create.rs (2)

474-488: Consistent resolver pattern in create command.

The PermissionStrategyResolver usage follows the same pattern as append.rs, with same_owner: true for creation operations. The comment appropriately documents that this field is ignored during creation.


524-529: Simplified CreationContext without owner_options.

The removal of owner_options from CreationContext is a clean simplification. Ownership handling is now fully encapsulated in PermissionStrategy via the resolver.

cli/src/command/update.rs (1)

397-411: Update command follows same resolver pattern.

The update command correctly uses same_owner: true since it creates new entries when updating the archive. Consistent with the other creation-oriented commands.

cli/src/command/stdio.rs (3)

637-662: Proper ownership resolution for stdio create.

The resolve_name_id helper correctly handles the precedence: --owner/--group spec takes precedence over individual --uname/--uid and --gname/--gid flags. The resolver is then correctly configured with same_owner: true for creation.


745-755: Correct extraction behavior with same_owner flag.

For extraction, same_owner: !args.no_same_owner correctly inverts the --no-same-owner flag to determine ownership restoration behavior. This aligns with tar-compatible CLI semantics.


994-1003: Clean helper for NameIdPair resolution.

The resolve_name_id function provides a clean abstraction for handling the precedence between the combined --owner/--group spec and individual name/id flags.

cli/src/command/extract.rs (4)

417-431: Correct extraction permission strategy.

The PermissionStrategyResolver for extraction correctly uses same_owner: !args.no_same_owner, which respects the user's choice between --same-owner and --no-same-owner flags.


972-998: Well-designed ownership resolution with clear priority.

The resolve_owner function correctly implements the priority order documented in the comments:

  1. Override uid/gid if specified
  2. Override uname/gname if specified
  3. Archive's uname/gname with fallback to uid/gid

This matches the expected tar-compatible behavior.


1001-1048: Correct conditional ownership restoration.

The restore_permissions function correctly:

  1. Only calls lchown when OwnerSource::FromSource (i.e., when --same-owner is effective)
  2. Always restores mode permissions via chmod regardless of ownership setting

This separation ensures that file modes are preserved even when ownership restoration is skipped.


881-885: Pattern match correctly gates permission restoration.

The PermissionStrategy::Preserve pattern match ensures permissions are only restored when the strategy is enabled, and the owner reference is correctly extracted for use in restore_permissions.

Copy link
Copy Markdown
Contributor

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

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 the handling of file ownership and permissions by replacing the OwnerOptions struct with a new PermissionStrategyResolver struct and OwnerSource enum. The PermissionStrategy enum was updated to include ownership details, leading to widespread changes across CLI commands (append, create, extract, stdio, update) to utilize this new resolution mechanism. The CreateOptions and OutputOption structs, along with metadata application and restoration functions, were updated to remove direct OwnerOptions usage. Review comments pointed out a misleading comment for same_owner in creation contexts, suggesting it should explicitly state that same_owner: true is mandatory to prevent panics, and recommended refactoring the restore_permissions function to centralize duplicated ownership restoration logic between Unix and Windows platform-specific code for improved maintainability.

Comment thread cli/src/command/create.rs Outdated
Comment thread cli/src/command/extract.rs Outdated
@ChanTsune ChanTsune force-pushed the cli/refactor/permissions branch from b942572 to 7f26760 Compare January 6, 2026 13:41
Refactor permission/ownership handling to follow the TimestampStrategy
pattern, creating a single source of truth for all permission-related
configuration.

Changes:
- Add OwnerSource enum with NoRestore and FromSource variants
- Change PermissionStrategy from Never/Always to Never/Preserve{owner}
- Add PermissionStrategyResolver with context-specific resolution:
  - resolve_for_creation(): always FromSource (ownership stored)
  - resolve_for_extraction(): respects same_owner flag
- Remove OwnerOptions struct and owner_options from CreateOptions
- Update all command modules to use the new resolver pattern

This consolidation eliminates the scattered ownership concerns
(OwnerOptions struct, same_owner boolean, PermissionStrategy enum)
into a unified architecture where ownership handling is embedded
within PermissionStrategy.
- Add chmod wrapper in utils/fs.rs following lchown pattern
- Consolidate duplicate Unix/Windows chmod calls in extract.rs
@ChanTsune ChanTsune force-pushed the cli/refactor/permissions branch from 7f26760 to 849cb43 Compare January 7, 2026 01:49
Copy link
Copy Markdown
Contributor

@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

🤖 Fix all issues with AI agents
In @cli/src/command/core.rs:
- Line 738: The match arm using OwnerSource::NoRestore currently calls
unreachable!() which can panic at runtime because resolve() may produce
NoRestore when same_owner: false; instead, handle this case explicitly by
returning an Err variant (or Propagate a Creation-specific error) from the
surrounding function rather than panicking: locate the match on OwnerSource in
functions that call resolve() (e.g., where OwnerSource::NoRestore is matched)
and replace unreachable!("NoRestore is not used during creation") with a
controlled error return (e.g., return Err(Error::InvalidOwnerState("NoRestore in
creation context")) or map it into the existing Result error type), or introduce
a context-specific resolve method that never yields NoRestore and use that where
creation is expected.
🧹 Nitpick comments (1)
cli/src/command/core.rs (1)

731-794: Reduce duplication in owner override extraction.

The logic for extracting owner overrides from OwnerSource is duplicated between the Unix block (lines 737-745) and Windows block (lines 778-786). Consider extracting this into a helper function.

Refactoring suggestion
+fn extract_owner_overrides(owner: &OwnerSource) -> (Option<u32>, Option<u32>, Option<&str>, Option<&str>) {
+    match owner {
+        OwnerSource::NoRestore => unreachable!("NoRestore is not used during creation"),
+        OwnerSource::FromSource { uid, gid, uname, gname } => {
+            (*uid, *gid, uname.as_deref(), gname.as_deref())
+        }
+    }
+}
+
 #[cfg(unix)]
 if let PermissionStrategy::Preserve { ref owner } = keep_options.permission_strategy {
     use crate::utils::fs::{Group, User};
     use std::os::unix::fs::{MetadataExt, PermissionsExt};

     let mode = meta.permissions().mode() as u16;
-    // Extract owner overrides from OwnerSource
-    let (o_uid, o_gid, o_uname, o_gname) = match owner {
-        OwnerSource::NoRestore => unreachable!("NoRestore is not used during creation"),
-        OwnerSource::FromSource { uid, gid, uname, gname } => {
-            (*uid, *gid, uname.as_deref(), gname.as_deref())
-        }
-    };
+    let (o_uid, o_gid, o_uname, o_gname) = extract_owner_overrides(owner);
     // ... rest of the code
 }
 
 #[cfg(windows)]
 if let PermissionStrategy::Preserve { ref owner } = keep_options.permission_strategy {
     // ... setup code ...
-    let (o_uid, o_gid, o_uname, o_gname) = match owner {
-        OwnerSource::NoRestore => unreachable!("NoRestore is not used during creation"),
-        OwnerSource::FromSource { uid, gid, uname, gname } => {
-            (*uid, *gid, uname.clone(), gname.clone())
-        }
-    };
+    let (o_uid, o_gid, o_uname, o_gname) = extract_owner_overrides(owner);
+    let o_uname = o_uname.map(String::from);
+    let o_gname = o_gname.map(String::from);
     // ... rest of the code
 }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f26760 and 849cb43.

📒 Files selected for processing (8)
  • cli/src/command/append.rs
  • cli/src/command/core.rs
  • cli/src/command/core/permission.rs
  • cli/src/command/create.rs
  • cli/src/command/extract.rs
  • cli/src/command/stdio.rs
  • cli/src/command/update.rs
  • cli/src/utils/fs.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • cli/src/command/core/permission.rs
  • cli/src/utils/fs.rs
  • cli/src/command/stdio.rs
🧰 Additional context used
🧬 Code graph analysis (2)
cli/src/command/append.rs (1)
cli/src/command/core.rs (2)
  • create_entry (642-683)
  • entry_option (685-705)
cli/src/command/create.rs (1)
cli/src/command/core.rs (3)
  • collect_items_from_paths (398-412)
  • create_entry (642-683)
  • entry_option (685-705)
⏰ 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). (20)
  • GitHub Check: build-local-artifacts (x86_64-unknown-linux-gnu)
  • GitHub Check: rust_check_doc
  • GitHub Check: Test WebAssembly (nightly-2025-12-09, wasm32-wasip1)
  • GitHub Check: tier1 (windows-latest, nightly)
  • GitHub Check: tier1 (windows-11-arm, stable)
  • GitHub Check: tier1 (ubuntu-22.04-arm, beta)
  • GitHub Check: tier1 (windows-latest, beta)
  • GitHub Check: tier1 (ubuntu-22.04-arm, nightly)
  • GitHub Check: tier1 (ubuntu-latest, stable)
  • GitHub Check: tier1 (windows-latest, stable)
  • GitHub Check: tier1 (ubuntu-latest, beta)
  • GitHub Check: Test WebAssembly (stable, wasm32-unknown-emscripten)
  • GitHub Check: msrv (ubuntu-latest, libpna)
  • GitHub Check: Test WebAssembly (nightly-2025-12-09, wasm32-unknown-emscripten)
  • GitHub Check: msrv (ubuntu-latest, portable-network-archive)
  • GitHub Check: Test WebAssembly (stable, wasm32-wasip2)
  • GitHub Check: Test WebAssembly (beta, wasm32-unknown-unknown)
  • GitHub Check: Test WebAssembly (beta, wasm32-wasip1)
  • GitHub Check: Test WebAssembly (stable, wasm32-wasip1)
  • GitHub Check: Test WebAssembly (beta, wasm32-unknown-emscripten)
🔇 Additional comments (6)
cli/src/command/append.rs (1)

388-398: LGTM! Permission resolver correctly configured for creation context.

The PermissionStrategyResolver is properly initialized with same_owner: true, which is required for the creation/append flow. The comment clarifies this requirement, and all ownership override fields (uname, gname, uid, gid, numeric_owner) are correctly threaded through.

cli/src/command/update.rs (1)

397-407: LGTM! Consistent with creation context requirements.

The resolver configuration mirrors the append command correctly, with same_owner: true as required for creation contexts.

cli/src/command/create.rs (1)

475-485: LGTM! Past review feedback addressed.

The comment now correctly clarifies that same_owner must be true for creation, addressing the previous review concern about misleading documentation.

cli/src/command/extract.rs (3)

417-427: LGTM! Extraction context correctly handles same_owner flag.

Unlike the creation commands, the extraction path correctly uses same_owner: !args.no_same_owner, respecting the user's choice about whether to restore ownership. This is the appropriate behavior for extraction contexts.


1015-1041: LGTM! Clear ownership resolution logic.

The resolve_owner function implements a clear priority hierarchy:

  1. Override uid/gid if specified
  2. Override uname/gname if specified, searching by name
  3. Archive's uname/gname with fallback to archive's uid/gid

This makes the resolution logic explicit and maintainable.


1044-1072: LGTM! Past review feedback addressed.

The DRY concern from the previous review has been addressed. The ownership restoration logic is now unified (lines 1048-1062) with a single call to chmod at line 1064, eliminating the previous duplication between Unix and Windows blocks.

Comment thread cli/src/command/core.rs
Comment thread cli/src/command/core.rs
@ChanTsune ChanTsune merged commit 3852030 into main Jan 7, 2026
100 checks passed
@ChanTsune ChanTsune deleted the cli/refactor/permissions branch January 7, 2026 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli This issue is about cli application

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant