Skip to content

Moving extraction options back#1239

Merged
adamhathcock merged 3 commits intomasterfrom
adam/extractionoptions-are-back
Mar 3, 2026
Merged

Moving extraction options back#1239
adamhathcock merged 3 commits intomasterfrom
adam/extractionoptions-are-back

Conversation

@adamhathcock
Copy link
Owner

@adamhathcock adamhathcock commented Mar 2, 2026

Put back ExtractionOptions. Was always dubious I could get rid of them anyway: #1228

This pull request introduces a significant improvement to the extraction API by separating open-time and extract-time behaviors, clarifying usage of ReaderOptions and introducing ExtractionOptions for extraction-specific settings. The documentation and codebase have been updated for consistency, and method signatures now explicitly accept extraction options, providing users with more granular control over extraction behavior.

API and Extraction Behavior Refactoring

  • Introduced ExtractionOptions as a distinct type for extract-time settings (such as overwrite, path handling, timestamps, and attributes), and updated method signatures throughout the codebase to accept ExtractionOptions? instead of ReaderOptions? for extraction operations. This change affects methods like WriteToDirectory and WriteToFile in IArchiveEntryExtensions, IArchiveExtensions, and IAsyncArchiveExtensions, ensuring clearer separation of concerns between archive opening and extraction behavior. [1] [2] [3] [4] [5] [6] [7]

  • Updated all relevant documentation (API.md, USAGE.md, PERFORMANCE.md, ARCHITECTURE.md) to reflect the new extraction options paradigm, clarifying when to use ReaderOptions (for open-time settings like password and encoding) versus ExtractionOptions (for extract-time settings like overwrite and path preservation). Examples and option matrices were revised for accuracy and clarity. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]

Default Option Changes and Consistency

  • Changed the default option for archive opening from ReaderOptions.ForOwnedFile to ReaderOptions.ForFilePath throughout the codebase, ensuring consistent and more intuitive behavior for users opening archives via file paths. [1] [2] [3] [4]

Minor Improvements and Fixes

  • Updated method calls to use named parameters for cancellationToken in async extraction examples for clarity and consistency in documentation. [1] [2] [3] [4] [5] [6]

  • Updated interface and documentation comments to reflect the separation of open-time and extract-time options, improving maintainability and reducing confusion.

These changes make the extraction API more robust, intuitive, and easier to use, while also improving documentation and code clarity.

@adamhathcock adamhathcock marked this pull request as ready for review March 3, 2026 10:41
Copilot AI review requested due to automatic review settings March 3, 2026 10:41
@kilo-code-bot
Copy link
Contributor

kilo-code-bot bot commented Mar 3, 2026

Code Review Summary

Status: 7 Issues Already Identified | Recommendation: Address existing comments before merge

Overview

Severity Count
CRITICAL 0
WARNING 5
SUGGESTION 2

Details

The PR introduces significant API changes separating ReaderOptions (open-time behavior) from ExtractionOptions (extract-time behavior). This is a well-intentioned architectural improvement, but introduces several breaking changes:

Already Documented Issues (7 total):

  1. WARNING - Parameter ordering breaking change: Multiple WriteToDirectory* methods insert ExtractionOptions? options before existing parameters (progress, cancellationToken), breaking existing callers using positional arguments.

    • Files: IAsyncReaderExtensions.cs:19, IArchiveExtensions.cs:23, IAsyncArchiveExtensions.cs:28
  2. WARNING - Per-entry allocation: options ??= new ExtractionOptions() in ExtractionMethods.cs:31 creates a new instance for every extracted entry, causing unnecessary allocations.

    • Consider caching or passing options through the call chain.
  3. SUGGESTION - Documentation: docs/USAGE.md uses ReaderOptions.ForOwnedFile() as if it were a method, but it's a property returning a preset instance. Should be ReaderOptions.ForFilePath.

  4. WARNING - ArchiveFactory breaking change: ArchiveFactory.WriteToDirectory now takes ExtractionOptions? but removes the ability to pass ReaderOptions for extraction behavior, requiring callers to update their code.

Architecture Assessment

The separation of concerns is sound:

  • ReaderOptions: password, encoding, stream ownership, compression providers
  • ExtractionOptions: overwrite, extract full path, preserve file time/attributes, symbolic links

The implementation correctly:

  • Creates new ExtractionOptions class
  • Removes extraction properties from ReaderOptions
  • Updates IReaderOptions to no longer inherit from IExtractionOptions
  • Adds presets: SafeExtract, FlatExtract, PreserveMetadata

Files Reviewed (19 files)

  • docs/API.md - Documentation updates
  • docs/ARCHITECTURE.md - Architecture docs
  • docs/PERFORMANCE.md - Performance doc updates
  • docs/USAGE.md - Usage documentation
  • src/SharpCompress/Archives/ArchiveFactory.cs - Factory changes
  • src/SharpCompress/Archives/ArchiveFactory.Async.cs - Async factory
  • src/SharpCompress/Archives/IArchiveExtensions.cs - Archive extension methods
  • src/SharpCompress/Archives/IAsyncArchiveExtensions.cs - Async archive extensions
  • src/SharpCompress/Archives/IArchiveEntryExtensions.cs - Entry extension methods
  • src/SharpCompress/Common/ExtractionMethods.cs - Core extraction logic
  • src/SharpCompress/Common/ExtractionMethods.Async.cs - Async extraction
  • src/SharpCompress/Common/ExtractionOptions.cs - New options class
  • src/SharpCompress/Common/IEntry.Extensions.cs - Entry extensions
  • src/SharpCompress/Common/Options/IReaderOptions.cs - Interface changes
  • src/SharpCompress/Readers/IAsyncReaderExtensions.cs - Async reader extensions
  • src/SharpCompress/Readers/IReaderExtensions.cs - Reader extensions
  • src/SharpCompress/Readers/ReaderFactory.cs - Reader factory
  • src/SharpCompress/Readers/ReaderFactory.Async.cs - Async reader factory
  • src/SharpCompress/Readers/ReaderOptions.cs - Reader options
  • tests/SharpCompress.Test/ExtractionTests.cs - Test updates
  • tests/SharpCompress.Test/OptionsUsabilityTests.cs - Test updates

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR reintroduces ExtractionOptions and updates SharpCompress extraction APIs/docs to separate open-time settings (ReaderOptions) from extract-time behavior (ExtractionOptions), addressing confusion introduced in recent releases.

Changes:

  • Added new ExtractionOptions type and routed extract-time decisions (overwrite, path handling, timestamps, symlinks) through it.
  • Updated extraction extension methods (sync/async) across readers/archives to accept ExtractionOptions? options = null.
  • Updated tests and documentation to reflect the new extraction option flow and presets.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/SharpCompress.Test/Zip/ZipArchiveAsyncTests.cs Updates call site to pass progress by name after signature change.
tests/SharpCompress.Test/WriterTests.cs Updates async extraction call to use named cancellationToken.
tests/SharpCompress.Test/ReaderTests.cs Updates async extraction call to use named cancellationToken.
tests/SharpCompress.Test/OptionsUsabilityTests.cs Moves preset expectations from ReaderOptions to ExtractionOptions.
tests/SharpCompress.Test/GZip/AsyncTests.cs Updates async extraction call to use named cancellationToken.
tests/SharpCompress.Test/ExtractionTests.cs Passes explicit ExtractionOptions into extraction tests for new API.
src/SharpCompress/Readers/ReaderOptionsExtensions.cs Removes extraction-related fluent helpers from ReaderOptions.
src/SharpCompress/Readers/ReaderOptions.cs Removes extraction-related properties/presets from ReaderOptions.
src/SharpCompress/Readers/IReaderExtensions.cs Adds ExtractionOptions? to sync reader extraction helpers.
src/SharpCompress/Readers/IAsyncReaderExtensions.cs Adds ExtractionOptions? to async reader extraction helpers.
src/SharpCompress/Common/Options/IReaderOptions.cs Removes IExtractionOptions from IReaderOptions inheritance.
src/SharpCompress/Common/IEntry.Extensions.cs Preserves timestamps/attributes based on ExtractionOptions instead of entry options.
src/SharpCompress/Common/ExtractionOptions.cs Introduces new ExtractionOptions record with presets + symlink handler.
src/SharpCompress/Common/ExtractionMethods.cs Routes sync extraction decisions through ExtractionOptions.
src/SharpCompress/Common/ExtractionMethods.Async.cs Routes async extraction decisions through ExtractionOptions.
src/SharpCompress/Archives/IAsyncArchiveExtensions.cs Adds ExtractionOptions? to async archive WriteToDirectoryAsync flow.
src/SharpCompress/Archives/IArchiveExtensions.cs Adds ExtractionOptions? to sync archive WriteToDirectory flow.
src/SharpCompress/Archives/IArchiveEntryExtensions.cs Adds ExtractionOptions? to entry extract helpers.
src/SharpCompress/Archives/IArchive.cs Updates docs to clarify ReaderOptions are open-time only.
src/SharpCompress/Archives/ArchiveFactory.cs Updates convenience WriteToDirectory API to use ExtractionOptions.
docs/USAGE.md Updates examples to pass ExtractionOptions at extract time.
docs/PERFORMANCE.md Updates examples for named cancellation token usage.
docs/ARCHITECTURE.md Documents ExtractionOptions as a distinct extract-time type.
docs/API.md Updates presets/options matrix and extraction examples for the new model.
Comments suppressed due to low confidence (1)

src/SharpCompress/Readers/ReaderOptionsExtensions.cs:100

  • The fluent ReaderOptions helpers for extraction behavior (WithOverwrite, WithExtractFullPath, etc.) were removed, but there isn't an equivalent fluent helper surface for ExtractionOptions (e.g., ExtractionOptionsExtensions.WithOverwrite(...)). If the project intends to keep the fluent pattern for options, consider adding corresponding With* extension methods for ExtractionOptions to replace the removed API.
    /// <summary>
    /// Creates a copy with the specified rewindable buffer size.
    /// </summary>
    public static ReaderOptions WithRewindableBufferSize(
        this ReaderOptions options,
        int? rewindableBufferSize
    ) => options with { RewindableBufferSize = rewindableBufferSize };

    /// <summary>
    /// Creates a copy with the specified compression provider registry.
    /// </summary>
    /// <exception cref="ArgumentNullException">Thrown if <paramref name="providers"/> is null.</exception>
    public static ReaderOptions WithProviders(
        this ReaderOptions options,
        CompressionProviderRegistry providers
    )
    {
        _ = providers ?? throw new ArgumentNullException(nameof(providers));
        return options with { Providers = providers };
    }

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

Copilot AI review requested due to automatic review settings March 3, 2026 12:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 9 comments.


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

@adamhathcock adamhathcock changed the title First pass of moving extraction options back Moving extraction options back Mar 3, 2026
@adamhathcock adamhathcock merged commit 3abf0dc into master Mar 3, 2026
10 checks passed
@adamhathcock adamhathcock deleted the adam/extractionoptions-are-back branch March 3, 2026 16:19
shazzaam7 added a commit to shazzaam7/xenia-manager that referenced this pull request Mar 12, 2026
- `Tomlyn` required switching from `Toml.ToModel()` to
`TomlSerializer.Deserialze<TomlTable>()`
- `SharpCompress` removed `ReaderOptions`, which have been replaced with
`ExtractionOptions`
([Reference](adamhathcock/sharpcompress#1239))
shazzaam7 added a commit to shazzaam7/xenia-manager that referenced this pull request Mar 12, 2026
- `Tomlyn` required switching from `Toml.ToModel()` to
`TomlSerializer.Deserialze<TomlTable>()`
- `SharpCompress` removed `ReaderOptions`, which have been replaced with
`ExtractionOptions`
([Reference](adamhathcock/sharpcompress#1239))
shazzaam7 added a commit to shazzaam7/xenia-manager that referenced this pull request Mar 16, 2026
- `Tomlyn` required switching from `Toml.ToModel()` to
`TomlSerializer.Deserialze<TomlTable>()`
- `SharpCompress` removed `ReaderOptions`, which have been replaced with
`ExtractionOptions`
([Reference](adamhathcock/sharpcompress#1239))
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