From e93cb40103ec6f652b371f2219daba867cebe23c Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 10 May 2023 15:10:21 +0100 Subject: [PATCH] Add `public enum FileSystemAttribute` --- Sources/TSCBasic/FileSystem.swift | 15 +++++++++++---- Tests/TSCBasicTests/FileSystemTests.swift | 9 ++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Sources/TSCBasic/FileSystem.swift b/Sources/TSCBasic/FileSystem.swift index cf3c4feb..be38fc19 100644 --- a/Sources/TSCBasic/FileSystem.swift +++ b/Sources/TSCBasic/FileSystem.swift @@ -137,6 +137,13 @@ public enum FileMode: Sendable { } } +/// Extended file system attributes that can applied to a given file path. See also ``FileSystem/hasAttribute(_:_:)``. +public enum FileSystemAttribute: String { + #if canImport(Darwin) + case quarantine = "com.apple.quarantine" + #endif +} + // FIXME: Design an asynchronous story? // /// Abstracted access to file system operations. @@ -171,7 +178,7 @@ public protocol FileSystem: Sendable { /// Returns `true` if a given path has an attribute with a given name applied when file system supports this /// attribute. Returns `false` if such attribute is not applied or it isn't supported. - func hasAttribute(name: String, _ path: AbsolutePath) -> Bool + func hasAttribute(_ name: FileSystemAttribute, _ path: AbsolutePath) -> Bool // FIXME: Actual file system interfaces will allow more efficient access to // more data than just the name here. @@ -306,7 +313,7 @@ public extension FileSystem { throw FileSystemError(.unsupported, path) } - func hasAttribute(name: String, _ path: AbsolutePath) -> Bool { false } + func hasAttribute(_ name: FileSystemAttribute, _ path: AbsolutePath) -> Bool { false } } /// Concrete FileSystem implementation which communicates with the local file system. @@ -355,9 +362,9 @@ private struct LocalFileSystem: FileSystem { return FileInfo(attrs) } - func hasAttribute(name: String, _ path: AbsolutePath) -> Bool { + func hasAttribute(_ name: FileSystemAttribute, _ path: AbsolutePath) -> Bool { #if canImport(Darwin) - let bufLength = getxattr(path.pathString, name, nil, 0, 0, 0) + let bufLength = getxattr(path.pathString, name.rawValue, nil, 0, 0, 0) return bufLength > 0 #else diff --git a/Tests/TSCBasicTests/FileSystemTests.swift b/Tests/TSCBasicTests/FileSystemTests.swift index a4d45cc6..29430b91 100644 --- a/Tests/TSCBasicTests/FileSystemTests.swift +++ b/Tests/TSCBasicTests/FileSystemTests.swift @@ -864,12 +864,11 @@ class FileSystemTests: XCTestCase { func testHasAttribute() throws { try withTemporaryDirectory(removeTreeOnDeinit: true) { tempDir in let filePath = tempDir.appending(component: "quarantined") - let attributeName = "com.apple.quarantine" try localFileSystem.writeFileContents(filePath, bytes: "") - try Process.checkNonZeroExit(args: "xattr", "-w", attributeName, "foo", filePath.pathString) - XCTAssertTrue(localFileSystem.hasAttribute(name: attributeName, filePath)) - try Process.checkNonZeroExit(args: "xattr", "-d", attributeName, filePath.pathString) - XCTAssertFalse(localFileSystem.hasAttribute(name: attributeName, filePath)) + try Process.checkNonZeroExit(args: "xattr", "-w", FileSystemAttribute.quarantine.rawValue, "foo", filePath.pathString) + XCTAssertTrue(localFileSystem.hasAttribute(.quarantine, filePath)) + try Process.checkNonZeroExit(args: "xattr", "-d", FileSystemAttribute.quarantine.rawValue, filePath.pathString) + XCTAssertFalse(localFileSystem.hasAttribute(.quarantine, filePath)) } } #endif