Skip to content

refactor: replace SwiftNIO filesystem backend with system APIs#291

Closed
pepicrft wants to merge 19 commits intomainfrom
replace-swift-nio-with-swift-file-system
Closed

refactor: replace SwiftNIO filesystem backend with system APIs#291
pepicrft wants to merge 19 commits intomainfrom
replace-swift-nio-with-swift-file-system

Conversation

@pepicrft
Copy link
Copy Markdown
Contributor

@pepicrft pepicrft commented Mar 17, 2026

Summary

This PR removes the package's SwiftNIO filesystem backend and replaces it with direct system file APIs while preserving the current public API and platform support.

It also migrates the package test suite to Swift Testing and adds coverage around the behavior most likely to regress during the backend swap.

Context

We investigated adopting Coen ten Thije Boonkkamp's swift-file-system to address the file-handle-management issues in this package.

That path was not a good fit for this library today:

  • it required raising the toolchain and platform floor beyond what this package currently supports in CI
  • it changed the support story on Apple platforms in a breaking way
  • it did not justify the compatibility cost for what should be an internal implementation change

The final branch keeps the existing package surface and support matrix, but removes the SwiftNIO dependency and the old FileManager-heavy implementation underneath it.

What Changed

  • removed the SwiftNIO dependency from the package
  • replaced the FileSystem backend with POSIX and WinSDK-backed operations for directory traversal, temporary directories, touch, mkdir, move, copy, replace, recursive delete, metadata, timestamps, and symlinks
  • kept ZIP support on ZIPFoundation, but implemented archive traversal without FileManager.default.zipItem
  • updated Glob traversal to use system directory iteration instead of the previous FileManager path
  • migrated all package tests to Swift Testing
  • removed the old XCTest-only Glob helper files
  • added targeted behavior tests for:
    • moving into a missing parent directory
    • recursive directory copy
    • raw file reads
    • invalid text encoding failures
    • ZIP directory-content semantics

Alternatives Considered

The main alternative was to keep the swift-file-system adoption and raise the package floor to match it. I decided against that because it would introduce breaking support changes for a dependency swap that can be handled internally.

I also considered keeping parts of the old Foundation-based implementation, especially around ZIP operations, but that would have left the file-handle-management concerns only partially addressed.

Testing

  • swift test
  • swift build -c release

I did not run Linux or Windows builds locally.

One remaining limitation is that the larger FileSystemTests suite is still excluded on Windows, so Windows runtime confidence still relies more heavily on CI than on local execution.

@pepicrft pepicrft changed the title Replace SwiftNIO with swift-file-system refactor: replace SwiftNIO backend with system file APIs Mar 17, 2026
@pepicrft pepicrft changed the title refactor: replace SwiftNIO backend with system file APIs refactor: replace SwiftNIO filesystem backend with system APIs Mar 17, 2026
… I/O

Replace raw POSIX/WinSDK system calls with coenttb/swift-file-system,
which provides concurrency-pooled async I/O to prevent file descriptor
exhaustion under heavy load. This addresses ulimit issues hit in
tuist/tuist. Platform minimum bumped to macOS 26 / iOS 26.
URL.path() on Windows returns /C:/... which is invalid for Win32 APIs.
Strip the leading slash when a drive letter follows. Also use
URL(fileURLWithPath:) on Windows for consistent file URL construction.
Bump Docker images to swift:6.2, Windows to swift-6.2-release,
and macOS runners to macos-26 for Xcode 26 / Swift 6.2 support.
swift-file-system's Delete uses stat() which follows symlinks, causing
failures when deleting directories containing symlinks whose targets
don't exist. Implement our own lstat-based recursive delete that handles
symlinks correctly by unlinking them directly.
SetFileTime, DeleteFileW, and RemoveDirectoryW return Bool on Windows
Swift, not Int. Remove the != 0 comparisons.
@pepicrft pepicrft self-assigned this Mar 17, 2026
pepicrft and others added 3 commits March 17, 2026 17:58
macos-26 runners are not yet available. Use macos-15 with explicit
Xcode 26 beta selection instead.
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