Skip to content

Allow to copy files and symlinks while overwriting the destination#3508

Merged
glbrntt merged 15 commits intoapple:mainfrom
stepan-ulyanin:add-overwriting-to-niofs
Feb 18, 2026
Merged

Allow to copy files and symlinks while overwriting the destination#3508
glbrntt merged 15 commits intoapple:mainfrom
stepan-ulyanin:add-overwriting-to-niofs

Conversation

@stepan-ulyanin
Copy link
Copy Markdown
Contributor

@stepan-ulyanin stepan-ulyanin commented Feb 11, 2026

Adds capability to NIOFS to copy regular files and symlink, allowing to overwrite the destination.

Motivation:

Per #3403 and #3470 we want to add replaceExisting: bool to FileSystem.copyItem.

Modifications:

  1. Adds replaceExisting: bool parameter to FileSystemProtocol.copyItem.
  2. Adds replaceExisting: bool parameter to FileSystem.copyItem and implementation for regular files and symbolic links.
  3. Adds tests.

Copy link
Copy Markdown
Contributor

@glbrntt glbrntt left a comment

Choose a reason for hiding this comment

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

This broadly looks good!

Copy link
Copy Markdown
Contributor

@glbrntt glbrntt left a comment

Choose a reason for hiding this comment

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

Couple of small things to resolve, otherwise this is looking great.

Comment on lines -1333 to +1519
let openDestinationResult = self._openFile(
forWritingAt: destinationPath,
options: options
).mapError {
FileSystemError(
message: "Can't copy '\(sourcePath)' as '\(destinationPath)' couldn't be opened.",
wrapping: $0
)
}

let destination: WriteFileHandle
switch openDestinationResult {
switch openDestination(destinationPath, options) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It looks like you've dropped the error mapping here.

Copy link
Copy Markdown
Contributor Author

@stepan-ulyanin stepan-ulyanin Feb 13, 2026

Choose a reason for hiding this comment

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

The error mapping from the original case is now happening inside the openDestination closure at https://github.com/stepan-ulyanin/swift-nio/blob/cf6030dbfe644d4ab5fef98250a1859ee312747d/Sources/NIOFS/FileSystem.swift#L1321-L1329 for copying without overwriting.

I pushed this logic out to a closure because when we copy with overwriting we use the file descriptor handler (https://github.com/stepan-ulyanin/swift-nio/blob/cf6030dbfe644d4ab5fef98250a1859ee312747d/Sources/NIOFS/FileSystem.swift#L1385-L1415) to do the atomic rename relative to the descriptor. The rest of the logic in _copyFileContents is identical between the replacing and non-replacing copies.

Copy link
Copy Markdown
Contributor

@glbrntt glbrntt left a comment

Choose a reason for hiding this comment

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

Thank you!

@glbrntt glbrntt added the semver/none No version bump required. label Feb 18, 2026
@glbrntt glbrntt enabled auto-merge (squash) February 18, 2026 08:35
@glbrntt glbrntt merged commit be8fdc1 into apple:main Feb 18, 2026
55 checks passed
glbrntt pushed a commit that referenced this pull request Mar 9, 2026
Adds the changes from #3508 to
the `_NIOFileSystem`.
### Motivation:

We have added capability to overwrite regular files and symbolic links
to `NIOFS` `FileSystem.copyItem` in
#3508. Now we want to port the
same logic to `_NIOFileSystem`.

### Modifications:

- Adds a new `FileSystemProtocol.copyItem` requirement with
`replaceExisting: bool` parameter along with a default implementation.
- Adds an implementation of the new `FileSystemProtocol.copyItem`
requirement to `_NIOFileSystem`'s `FileSystem` struct for regular files
and symbolic links.

### Notes

It seems that the tests for `FileSystem` are only in `NIOFS` - so no
tests are added in this PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

semver/none No version bump required.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants