Skip to content

Some API clean up from GPT 5.4#1243

Merged
adamhathcock merged 10 commits into
masterfrom
adam/api-clean-up
Mar 10, 2026
Merged

Some API clean up from GPT 5.4#1243
adamhathcock merged 10 commits into
masterfrom
adam/api-clean-up

Conversation

@adamhathcock
Copy link
Copy Markdown
Owner

This pull request refactors and improves the archive factory and related classes to be more consistent, modern, and type-safe. The main changes include standardizing parameter naming, replacing IEnumerable with IReadOnlyList for multi-file and multi-stream APIs, introducing async archive detection, and improving options handling. Several interface and type names are also corrected for clarity.

Key changes:

API Consistency and Type Safety

  • Changed method parameters from IEnumerable<FileInfo>/IEnumerable<Stream> to IReadOnlyList<FileInfo>/IReadOnlyList<Stream> in ArchiveFactory, GZipArchive, RarArchive, and related interfaces to ensure immutability and direct access by index. [1] [2] [3] [4] [5] [6] [7]
  • Updated interface and implementation names from IWriteableArchiveFactory to IWritableArchiveFactory for correct spelling and clarity. [1] [2] [3]

Parameter Naming and Option Handling

  • Standardized parameter names from path to filePath across all relevant methods for clarity and consistency. [1] [2] [3] [4] [5] [6]
  • Updated default ReaderOptions usage to use ReaderOptions.ForFilePath or ReaderOptions.ForExternalStream as appropriate, improving option handling and reducing unnecessary allocations. [1] [2] [3] [4] [5] [6]

Async and Utility Enhancements

  • Added new async methods for archive detection: IsArchiveAsync(string filePath, ...) and IsArchiveAsync(Stream, ...) to allow asynchronous archive type checking.
  • Made FindFactoryAsync<T>(FileInfo, ...) and FindFactoryAsync<T>(Stream, ...) public and added optional cancellation tokens for consistency with other async APIs. [1] [2]

Bug Fixes

  • Fixed a bug in AddAllFromDirectory and AddAllFromDirectoryAsync where FileInfo was incorrectly constructed with the directory path instead of the file path. [1] [2]

Minor Improvements

  • Added missing using directives for System.Threading and System.Threading.Tasks in ArchiveFactory.cs.

These changes make the archive APIs more robust, easier to use, and consistent across both sync and async scenarios.

Copilot AI review requested due to automatic review settings March 6, 2026 14:26
Comment thread src/SharpCompress/Archives/ArchiveFactory.Async.cs
Comment thread src/SharpCompress/Archives/ArchiveFactory.cs
Comment thread src/SharpCompress/Archives/ArchiveFactory.cs
Comment thread src/SharpCompress/Readers/IReader.cs
Comment thread src/SharpCompress/Readers/IAsyncReader.cs
Comment thread src/SharpCompress/Writers/IWriter.cs
Copy link
Copy Markdown
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 performs a broad API cleanup and consistency pass across the SharpCompress library. It standardizes naming conventions, improves type safety, adds async archive detection APIs, and fixes writer factory stream ownership behavior.

Changes:

  • Renames properties (ArchiveTypeType, WriterTypeType), parameters (pathfilePath), and interface (IWriteableArchiveFactoryIWritableArchiveFactory); changes multi-archive API signatures from IEnumerable<T> to IReadOnlyList<T> and async writer return types from IAsyncWriter to ValueTask<IAsyncWriter>.
  • Adds new IsArchiveAsync and promotes FindFactoryAsync to public API on ArchiveFactory, with corresponding tests in the new ArchiveFactoryTests.cs.
  • Standardizes ReaderOptions defaults to use ForFilePath/ForExternalStream presets and fixes writer factories to set LeaveStreamOpen = false when opening from FileInfo.

Reviewed changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/SharpCompress/Archives/ArchiveFactory.cs Add IsArchiveAsync methods, rename pathfilePath, IEnumerableIReadOnlyList
src/SharpCompress/Archives/ArchiveFactory.Async.cs Make FindFactoryAsync public, rename params, IEnumerableIReadOnlyList
src/SharpCompress/Archives/IWriteableArchiveFactory.cs Rename interface to IWritableArchiveFactory, fix XML doc
src/SharpCompress/Archives/IMultiArchiveOpenable.cs IEnumerableIReadOnlyList for multi-archive params
src/SharpCompress/Archives/IArchiveOpenable.cs Rename pathfilePath
src/SharpCompress/Archives/IWritableArchiveExtensions.cs Bug: changes new FileInfo(path) to new FileInfo(filePath) — regression
src/SharpCompress/Archives/IWritableAsyncArchiveExtensions.cs Bug: same regression as sync version
src/SharpCompress/Archives/Zip/ZipArchive.Factory.cs IEnumerableIReadOnlyList, use ReaderOptions.ForExternalStream
src/SharpCompress/Archives/Tar/TarArchive.Factory.cs IEnumerableIReadOnlyList, use presets, rename params
src/SharpCompress/Archives/SevenZip/SevenZipArchive.Factory.cs IEnumerableIReadOnlyList, use presets, rename params
src/SharpCompress/Archives/Rar/RarArchive.Factory.cs IEnumerableIReadOnlyList, use presets, rename params
src/SharpCompress/Archives/GZip/GZipArchive.Factory.cs IEnumerableIReadOnlyList, use presets, rename params
src/SharpCompress/Readers/IReader.cs ArchiveTypeType
src/SharpCompress/Readers/IAsyncReader.cs ArchiveTypeType
src/SharpCompress/Readers/AbstractReader.cs ArchiveTypeType
src/SharpCompress/Readers/IReaderOpenable.cs Rename pathfilePath
src/SharpCompress/Readers/IReaderFactory.cs Add default for cancellationToken param
src/SharpCompress/Readers/*/Factory.cs Rename params, add ReaderOptions.ForFilePath defaults
src/SharpCompress/Writers/IWriter.cs WriterTypeType
src/SharpCompress/Writers/AbstractWriter.cs WriterTypeType
src/SharpCompress/Writers/IWriterOpenable.cs Change return type to ValueTask<IAsyncWriter>, add CancellationToken
src/SharpCompress/Writers/*/Factory.cs Update async return types, add LeaveStreamOpen = false for FileInfo overloads
src/SharpCompress/Factories/ZipFactory.cs IWriteableArchiveFactoryIWritableArchiveFactory
src/SharpCompress/Factories/TarFactory.cs Same rename
src/SharpCompress/Factories/GZipFactory.cs Same rename
tests/SharpCompress.Test/ArchiveFactoryTests.cs New tests for FindFactoryAsync and IsArchiveAsync
tests/SharpCompress.Test/ArchiveTests.cs Add .ToArray() for IReadOnlyList compatibility
tests/SharpCompress.Test/Rar/*.cs Update for .ToArray() and Type rename
tests/SharpCompress.Test/Tar/*.cs Update for Type rename
tests/SharpCompress.Test/Lzw/*.cs Update for Type rename

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

Comment thread src/SharpCompress/Archives/IWritableArchiveExtensions.cs
Comment thread src/SharpCompress/Archives/IWritableAsyncArchiveExtensions.cs
Comment thread src/SharpCompress/Archives/ArchiveFactory.Async.cs
Comment thread src/SharpCompress/Archives/IWritableArchiveFactory.cs
@kilo-code-bot
Copy link
Copy Markdown
Contributor

kilo-code-bot Bot commented Mar 6, 2026

Code Review Summary

Status: 9 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 9
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
src/SharpCompress/Archives/ArchiveFactory.Async.cs 56 Breaking API change - Changing from IEnumerable<FileInfo> to IReadOnlyList<FileInfo> breaks existing callers
src/SharpCompress/Archives/ArchiveFactory.cs 52 Breaking API change - Changing from IEnumerable<FileInfo> to IReadOnlyList<FileInfo>
src/SharpCompress/Archives/ArchiveFactory.cs 75 Breaking API change - Changing from IEnumerable<Stream> to IReadOnlyList<Stream>
src/SharpCompress/Readers/IReader.cs 9 Breaking API change - Renaming ArchiveType to Type breaks existing code
src/SharpCompress/Readers/IAsyncReader.cs 11 Breaking API change - Renaming ArchiveType to Type
src/SharpCompress/Writers/IWriter.cs 11 Breaking API change - Renaming WriterType to Type
src/SharpCompress/Archives/IWritableArchiveExtensions.cs 25 Bug: This change introduces a regression. The original code used new FileInfo(path) (the enumerated file), but this PR changes it to new FileInfo(filePath) (the directory). This will cause all files to be read from the directory path instead of the actual file paths.
src/SharpCompress/Archives/IWritableAsyncArchiveExtensions.cs 27 Bug: Same regression as in the sync version. The original code used new FileInfo(path) but was changed to new FileInfo(filePath).
src/SharpCompress/Archives/ArchiveFactory.Async.cs 127 This method is being promoted from private to public. This is a minor API expansion but worth noting.
Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
src/SharpCompress/Archives/IWritableArchiveFactory.cs 16 The interface was renamed from IWriteableArchiveFactory to IWritableArchiveFactory - breaking change
Files Reviewed (47 files)
  • src/SharpCompress/Archives/ArchiveFactory.Async.cs - 3 issues
  • src/SharpCompress/Archives/ArchiveFactory.cs - 2 issues
  • src/SharpCompress/Archives/IWritableArchiveExtensions.cs - 1 issue (bug)
  • src/SharpCompress/Archives/IWritableAsyncArchiveExtensions.cs - 1 issue (bug)
  • src/SharpCompress/Archives/IWritableArchiveFactory.cs - 1 issue
  • src/SharpCompress/Readers/IReader.cs - 1 issue
  • src/SharpCompress/Readers/IAsyncReader.cs - 1 issue
  • src/SharpCompress/Writers/IWriter.cs - 1 issue
  • Plus 40+ additional files with minor changes (parameter renames, new methods, test updates)

Key Concerns

1. Regression Bugs (CRITICAL severity impact)

The AddAllFromDirectory and AddAllFromDirectoryAsync methods now incorrectly use the directory path (filePath) instead of the actual file path (path) when creating FileInfo objects. This will cause all file operations to fail or read from the wrong location.

Fix required: Revert lines 25 and 27 to use new FileInfo(path) instead of new FileInfo(filePath).

2. Breaking API Changes

This PR introduces multiple breaking API changes:

  • Parameter type changes from IEnumerable<T> to IReadOnlyList<T>
  • Property renames (ArchiveTypeType, WriterTypeType)
  • Interface rename (IWriteableArchiveFactoryIWritableArchiveFactory)

These should be documented in the changelog with migration guidance.

3. New Public API

The FindFactoryAsync<T> methods are now public. Ensure proper documentation and consider if this expands the public API surface appropriately.


Recommendation: Address the regression bugs before merging, as they will cause runtime failures. The breaking API changes should be acceptable if properly documented.

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 6, 2026

@adamhathcock I've opened a new pull request, #1244, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI review requested due to automatic review settings March 6, 2026 15:39
Copy link
Copy Markdown
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 46 out of 46 changed files in this pull request and generated 1 comment.


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

Comment thread src/SharpCompress/Archives/ArchiveFactory.Async.cs
@adamhathcock adamhathcock merged commit b54c420 into master Mar 10, 2026
10 checks passed
@adamhathcock adamhathcock deleted the adam/api-clean-up branch March 10, 2026 16:45
tonycknight pushed a commit to tonycknight/discorss that referenced this pull request Jun 1, 2026
Updated [SharpCompress](https://github.com/adamhathcock/sharpcompress)
from 0.48.1 to 0.49.1.

<details>
<summary>Release notes</summary>

_Sourced from [SharpCompress's
releases](https://github.com/adamhathcock/sharpcompress/releases)._

## 0.49.1

## What's Changed
* Close writable entry streams during async archive disposal by
@​Copilot in adamhathcock/sharpcompress#1338
* Restore `WriteToDirectoryAsync` progress callbacks for solid 7z
archives by @​Copilot in
adamhathcock/sharpcompress#1340
* Try to fix global.json to avoid churn in locks by @​adamhathcock in
adamhathcock/sharpcompress#1341
* Fix tar archive enumeration after fully reading entry streams by
@​adamhathcock in
adamhathcock/sharpcompress#1342


**Full Changelog**:
adamhathcock/sharpcompress@0.49.0...0.49.1

## 0.49.0

This should contain a lot of write async fixes and some breaking API
changes that fix previous broke `net48` usage

## What's Changed
* Rename IWriteableArchiveFactory.cs to IWritableArchiveFactory.cs by
@​Copilot in adamhathcock/sharpcompress#1244
* Some API clean up from GPT 5.4 by @​adamhathcock in
adamhathcock/sharpcompress#1243
* Release to master by @​adamhathcock in
adamhathcock/sharpcompress#1267
* Fix three BLAKE2sp correctness bugs and eliminate allocations in hot
path by @​coderb in
adamhathcock/sharpcompress#1266
* Corrected async examples. by @​dlemstra in
adamhathcock/sharpcompress#1277
* Fix setting invalid access time fails extraction by @​aromaa in
adamhathcock/sharpcompress#1279
* Fix incorrect code examples in docs for sync/async usage by @​Copilot
in adamhathcock/sharpcompress#1280
* Replace APPNOTE.TXT contents with reference link note by @​puk06 in
adamhathcock/sharpcompress#1286
* Release to Master by @​adamhathcock in
adamhathcock/sharpcompress#1274
* update docs for tar gap analysis and XZ usage by @​adamhathcock in
adamhathcock/sharpcompress#1288
* Add a PooledMemoryStream to avoid allocating by @​adamhathcock in
adamhathcock/sharpcompress#1275
* fix: Change LeaveStreamOpen default from true to false by @​puk06 in
adamhathcock/sharpcompress#1293
* Fix usage of ReaderOptions and pre-defined values by @​adamhathcock in
adamhathcock/sharpcompress#1295
* Enforce seekable, readable and writable on streams by @​adamhathcock
in adamhathcock/sharpcompress#1297
* Add ArchiveInformation record for consolidated archive detection and
capability inspection by @​Copilot in
adamhathcock/sharpcompress#1299
* merge release to master by @​adamhathcock in
adamhathcock/sharpcompress#1314
* Some clean up and test clean up by @​adamhathcock in
adamhathcock/sharpcompress#1321
* Finish Write Async by @​adamhathcock in
adamhathcock/sharpcompress#1323
* More complete Tar implementation: USTAR, PAX, etc. by @​adamhathcock
in adamhathcock/sharpcompress#1289
* Add Polysharp and adjustments that do not break legacy frameworks by
@​adamhathcock in
adamhathcock/sharpcompress#1330
* Fix null `IVolume.FileName` for single-volume file-based archives by
@​Copilot in adamhathcock/sharpcompress#1333
* Add skills by @​adamhathcock in
adamhathcock/sharpcompress#1332
* add AOT smoke and missing tests by @​adamhathcock in
adamhathcock/sharpcompress#1334

## New Contributors
* @​dlemstra made their first contribution in
adamhathcock/sharpcompress#1277
* @​aromaa made their first contribution in
adamhathcock/sharpcompress#1279
* @​puk06 made their first contribution in
adamhathcock/sharpcompress#1286

**Full Changelog**:
adamhathcock/sharpcompress@0.48.1...0.49.0

## 0.49.0-beta.140

## What's Changed
* Add Polysharp and adjustments that do not break legacy frameworks by
@​adamhathcock in
adamhathcock/sharpcompress#1330


**Full Changelog**:
adamhathcock/sharpcompress@0.49.0-beta.136...0.49.0-beta.140

## 0.49.0-beta.136

## What's Changed
* Rename IWriteableArchiveFactory.cs to IWritableArchiveFactory.cs by
@​Copilot in adamhathcock/sharpcompress#1244
* Some API clean up from GPT 5.4 by @​adamhathcock in
adamhathcock/sharpcompress#1243
* Release to master by @​adamhathcock in
adamhathcock/sharpcompress#1267
* Fix three BLAKE2sp correctness bugs and eliminate allocations in hot
path by @​coderb in
adamhathcock/sharpcompress#1266
* Corrected async examples. by @​dlemstra in
adamhathcock/sharpcompress#1277
* Fix setting invalid access time fails extraction by @​aromaa in
adamhathcock/sharpcompress#1279
* Fix incorrect code examples in docs for sync/async usage by @​Copilot
in adamhathcock/sharpcompress#1280
* Replace APPNOTE.TXT contents with reference link note by @​puk06 in
adamhathcock/sharpcompress#1286
* Release to Master by @​adamhathcock in
adamhathcock/sharpcompress#1274
* update docs for tar gap analysis and XZ usage by @​adamhathcock in
adamhathcock/sharpcompress#1288
* Add a PooledMemoryStream to avoid allocating by @​adamhathcock in
adamhathcock/sharpcompress#1275
* fix: Change LeaveStreamOpen default from true to false by @​puk06 in
adamhathcock/sharpcompress#1293
* Fix usage of ReaderOptions and pre-defined values by @​adamhathcock in
adamhathcock/sharpcompress#1295
* Enforce seekable, readable and writable on streams by @​adamhathcock
in adamhathcock/sharpcompress#1297
* Add ArchiveInformation record for consolidated archive detection and
capability inspection by @​Copilot in
adamhathcock/sharpcompress#1299
* merge release to master by @​adamhathcock in
adamhathcock/sharpcompress#1314
* Some clean up and test clean up by @​adamhathcock in
adamhathcock/sharpcompress#1321
* Finish Write Async by @​adamhathcock in
adamhathcock/sharpcompress#1323
* More complete Tar implementation: USTAR, PAX, etc. by @​adamhathcock
in adamhathcock/sharpcompress#1289

## New Contributors
* @​dlemstra made their first contribution in
adamhathcock/sharpcompress#1277
* @​aromaa made their first contribution in
adamhathcock/sharpcompress#1279
* @​puk06 made their first contribution in
adamhathcock/sharpcompress#1286

**Full Changelog**:
adamhathcock/sharpcompress@0.48.1...0.49.0-beta1

Commits viewable in [compare
view](adamhathcock/sharpcompress@0.48.1...0.49.1).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=SharpCompress&package-manager=nuget&previous-version=0.48.1&new-version=0.49.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This was referenced Jun 1, 2026
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.

3 participants