Skip to content

Commit a1335c3

Browse files
authored
Use package access level (SE-0386, available from Swift 5.9) instead of SPI for FileManagerProtocol (#878)
rdar://125785105
1 parent 6ed76cc commit a1335c3

28 files changed

+60
-69
lines changed

Sources/SwiftDocC/Infrastructure/Diagnostics/DiagnosticConsoleWriter.swift

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ public final class DiagnosticConsoleWriter: DiagnosticFormattingConsumer {
3636
self.init(stream, formattingOptions: options, baseURL: baseURL, highlight: highlight, fileManager: FileManager.default)
3737
}
3838

39-
@_spi(FileManagerProtocol)
40-
public init(
39+
package init(
4140
_ stream: TextOutputStream = LogHandle.standardError,
4241
formattingOptions options: DiagnosticFormattingOptions = [],
4342
baseURL: URL? = nil,
@@ -101,25 +100,22 @@ extension DiagnosticConsoleWriter {
101100
public static func formattedDescription(for problems: some Sequence<Problem>, options: DiagnosticFormattingOptions = []) -> String {
102101
formattedDescription(for: problems, options: options, fileManager: FileManager.default)
103102
}
104-
@_spi(FileManagerProtocol)
105-
public static func formattedDescription(for problems: some Sequence<Problem>, options: DiagnosticFormattingOptions = [], fileManager: FileManagerProtocol) -> String {
103+
package static func formattedDescription(for problems: some Sequence<Problem>, options: DiagnosticFormattingOptions = [], fileManager: FileManagerProtocol) -> String {
106104
return problems.map { formattedDescription(for: $0, options: options, fileManager: fileManager) }.joined(separator: "\n")
107105
}
108106

109107
public static func formattedDescription(for problem: Problem, options: DiagnosticFormattingOptions = []) -> String {
110108
formattedDescription(for: problem, options: options, fileManager: FileManager.default)
111109
}
112-
@_spi(FileManagerProtocol)
113-
public static func formattedDescription(for problem: Problem, options: DiagnosticFormattingOptions = [], fileManager: FileManagerProtocol = FileManager.default) -> String {
110+
package static func formattedDescription(for problem: Problem, options: DiagnosticFormattingOptions = [], fileManager: FileManagerProtocol = FileManager.default) -> String {
114111
let diagnosticFormatter = makeDiagnosticFormatter(options, baseURL: nil, highlight: TerminalHelper.isConnectedToTerminal, fileManager: fileManager)
115112
return diagnosticFormatter.formattedDescription(for: problem)
116113
}
117114

118115
public static func formattedDescription(for diagnostic: Diagnostic, options: DiagnosticFormattingOptions = []) -> String {
119116
formattedDescription(for: diagnostic, options: options, fileManager: FileManager.default)
120117
}
121-
@_spi(FileManagerProtocol)
122-
public static func formattedDescription(for diagnostic: Diagnostic, options: DiagnosticFormattingOptions = [], fileManager: FileManagerProtocol) -> String {
118+
package static func formattedDescription(for diagnostic: Diagnostic, options: DiagnosticFormattingOptions = [], fileManager: FileManagerProtocol) -> String {
123119
let diagnosticFormatter = makeDiagnosticFormatter(options, baseURL: nil, highlight: TerminalHelper.isConnectedToTerminal, fileManager: fileManager)
124120
return diagnosticFormatter.formattedDescription(for: diagnostic)
125121
}

Sources/SwiftDocC/Utility/FileManagerProtocol.swift

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ import Foundation
2222
/// Should you need a file system with a different storage, create your own
2323
/// protocol implementations to manage files in memory,
2424
/// on a network, in a database, or elsewhere.
25-
@_spi(FileManagerProtocol)
26-
public protocol FileManagerProtocol {
25+
package protocol FileManagerProtocol {
2726

2827
/// Returns the data content of a file at the given path, if it exists.
2928
func contents(atPath: String) -> Data?
@@ -90,10 +89,9 @@ public protocol FileManagerProtocol {
9089
func createFile(at location: URL, contents: Data, options writingOptions: NSData.WritingOptions?) throws
9190
}
9291

93-
@_spi(FileManagerProtocol)
9492
extension FileManagerProtocol {
9593
/// Returns a Boolean value that indicates whether a directory exists at a specified path.
96-
public func directoryExists(atPath path: String) -> Bool {
94+
package func directoryExists(atPath path: String) -> Bool {
9795
var isDirectory = ObjCBool(booleanLiteral: false)
9896
let fileExistsAtPath = fileExists(atPath: path, isDirectory: &isDirectory)
9997
return fileExistsAtPath && isDirectory.boolValue
@@ -102,19 +100,18 @@ extension FileManagerProtocol {
102100

103101
/// Add compliance to `FileManagerProtocol` to `FileManager`,
104102
/// most of the methods are already implemented in Foundation.
105-
@_spi(FileManagerProtocol)
106103
extension FileManager: FileManagerProtocol {
107104
// This method doesn't exist on `FileManager`. There is a similar looking method but it doesn't provide information about potential errors.
108-
public func contents(of url: URL) throws -> Data {
105+
package func contents(of url: URL) throws -> Data {
109106
return try Data(contentsOf: url)
110107
}
111108

112109
// This method doesn't exist on `FileManager`. There is a similar looking method but it doesn't provide information about potential errors.
113-
public func createFile(at location: URL, contents: Data) throws {
110+
package func createFile(at location: URL, contents: Data) throws {
114111
try contents.write(to: location, options: .atomic)
115112
}
116113

117-
public func createFile(at location: URL, contents: Data, options writingOptions: NSData.WritingOptions?) throws {
114+
package func createFile(at location: URL, contents: Data, options writingOptions: NSData.WritingOptions?) throws {
118115
if let writingOptions {
119116
try contents.write(to: location, options: writingOptions)
120117
} else {
@@ -123,7 +120,7 @@ extension FileManager: FileManagerProtocol {
123120
}
124121

125122
// Because we shadow 'FileManager.temporaryDirectory' in our tests, we can't also use 'temporaryDirectory' in FileManagerProtocol/
126-
public func uniqueTemporaryDirectory() -> URL {
123+
package func uniqueTemporaryDirectory() -> URL {
127124
temporaryDirectory.appendingPathComponent(ProcessInfo.processInfo.globallyUniqueString, isDirectory: true)
128125
}
129126
}

Sources/SwiftDocCTestUtilities/TestFileSystem.swift

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import Foundation
1212
import XCTest
13-
@testable @_spi(FileManagerProtocol) import SwiftDocC
13+
@testable import SwiftDocC
1414

1515
/// A Data provider and file manager that accepts pre-built documentation bundles with files on the local filesystem.
1616
///
@@ -40,14 +40,13 @@ import XCTest
4040
///
4141
/// - Note: This class is thread-safe by using a naive locking for each access to the files dictionary.
4242
/// - Warning: Use this type for unit testing.
43-
@_spi(FileManagerProtocol) // This needs to be SPI because it conforms to an SPI protocol
44-
public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProvider {
45-
public let currentDirectoryPath = "/"
43+
package class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProvider {
44+
package let currentDirectoryPath = "/"
4645

47-
public var identifier: String = UUID().uuidString
46+
package var identifier: String = UUID().uuidString
4847

4948
private var _bundles = [DocumentationBundle]()
50-
public func bundles(options: BundleDiscoveryOptions) throws -> [DocumentationBundle] {
49+
package func bundles(options: BundleDiscoveryOptions) throws -> [DocumentationBundle] {
5150
// Ignore the bundle discovery options, these test bundles are already built.
5251
return _bundles
5352
}
@@ -65,7 +64,7 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
6564
/// A data fixture to use in the `files` index to mark folders.
6665
static let folderFixtureData = "Folder".data(using: .utf8)!
6766

68-
public convenience init(folders: [Folder]) throws {
67+
package convenience init(folders: [Folder]) throws {
6968
self.init()
7069

7170
// Default system paths
@@ -117,7 +116,7 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
117116
}
118117
}
119118

120-
public func contentsOfURL(_ url: URL) throws -> Data {
119+
package func contentsOfURL(_ url: URL) throws -> Data {
121120
filesLock.lock()
122121
defer { filesLock.unlock() }
123122

@@ -127,7 +126,7 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
127126
return file
128127
}
129128

130-
public func contents(of url: URL) throws -> Data {
129+
package func contents(of url: URL) throws -> Data {
131130
try contentsOfURL(url)
132131
}
133132

@@ -166,7 +165,7 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
166165
return Array(fileList.keys)
167166
}
168167

169-
public func fileExists(atPath path: String, isDirectory: UnsafeMutablePointer<ObjCBool>?) -> Bool {
168+
package func fileExists(atPath path: String, isDirectory: UnsafeMutablePointer<ObjCBool>?) -> Bool {
170169
filesLock.lock()
171170
defer { filesLock.unlock() }
172171

@@ -179,14 +178,14 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
179178
return true
180179
}
181180

182-
public func fileExists(atPath path: String) -> Bool {
181+
package func fileExists(atPath path: String) -> Bool {
183182
filesLock.lock()
184183
defer { filesLock.unlock() }
185184

186185
return files.keys.contains(path)
187186
}
188187

189-
public func copyItem(at srcURL: URL, to dstURL: URL) throws {
188+
package func copyItem(at srcURL: URL, to dstURL: URL) throws {
190189
guard !disableWriting else { return }
191190

192191
filesLock.lock()
@@ -203,7 +202,7 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
203202
}
204203
}
205204

206-
public func moveItem(at srcURL: URL, to dstURL: URL) throws {
205+
package func moveItem(at srcURL: URL, to dstURL: URL) throws {
207206
guard !disableWriting else { return }
208207

209208
filesLock.lock()
@@ -240,7 +239,7 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
240239
files[path] = Self.folderFixtureData
241240
}
242241

243-
public func createDirectory(at url: URL, withIntermediateDirectories createIntermediates: Bool, attributes: [FileAttributeKey : Any]? = nil) throws {
242+
package func createDirectory(at url: URL, withIntermediateDirectories createIntermediates: Bool, attributes: [FileAttributeKey : Any]? = nil) throws {
244243
guard !disableWriting else { return }
245244

246245
filesLock.lock()
@@ -249,14 +248,14 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
249248
try createDirectory(atPath: url.path, withIntermediateDirectories: createIntermediates)
250249
}
251250

252-
public func contentsEqual(atPath path1: String, andPath path2: String) -> Bool {
251+
package func contentsEqual(atPath path1: String, andPath path2: String) -> Bool {
253252
filesLock.lock()
254253
defer { filesLock.unlock() }
255254

256255
return files[path1] == files[path2]
257256
}
258257

259-
public func removeItem(at: URL) throws {
258+
package func removeItem(at: URL) throws {
260259
guard !disableWriting else { return }
261260

262261
filesLock.lock()
@@ -268,7 +267,7 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
268267
}
269268
}
270269

271-
public func createFile(at url: URL, contents: Data) throws {
270+
package func createFile(at url: URL, contents: Data) throws {
272271
filesLock.lock()
273272
defer { filesLock.unlock() }
274273

@@ -279,18 +278,18 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
279278
}
280279
}
281280

282-
public func createFile(at url: URL, contents: Data, options: NSData.WritingOptions?) throws {
281+
package func createFile(at url: URL, contents: Data, options: NSData.WritingOptions?) throws {
283282
try createFile(at: url, contents: contents)
284283
}
285284

286-
public func contents(atPath: String) -> Data? {
285+
package func contents(atPath: String) -> Data? {
287286
filesLock.lock()
288287
defer { filesLock.unlock() }
289288

290289
return files[atPath]
291290
}
292291

293-
public func contentsOfDirectory(atPath path: String) throws -> [String] {
292+
package func contentsOfDirectory(atPath path: String) throws -> [String] {
294293
filesLock.lock()
295294
defer { filesLock.unlock() }
296295

@@ -309,7 +308,7 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
309308
return Array(results)
310309
}
311310

312-
public func contentsOfDirectory(at url: URL, includingPropertiesForKeys keys: [URLResourceKey]?, options mask: FileManager.DirectoryEnumerationOptions) throws -> [URL] {
311+
package func contentsOfDirectory(at url: URL, includingPropertiesForKeys keys: [URLResourceKey]?, options mask: FileManager.DirectoryEnumerationOptions) throws -> [URL] {
313312

314313
if let keys {
315314
XCTAssertTrue(keys.isEmpty, "includingPropertiesForKeys is not implemented in contentsOfDirectory in TestFileSystem")
@@ -328,7 +327,7 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
328327
return output
329328
}
330329

331-
public func uniqueTemporaryDirectory() -> URL {
330+
package func uniqueTemporaryDirectory() -> URL {
332331
URL(fileURLWithPath: "/tmp/\(ProcessInfo.processInfo.globallyUniqueString)", isDirectory: true)
333332
}
334333

@@ -345,7 +344,7 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
345344
///
346345
/// - Parameter path: The path to the sub hierarchy to dump to a string representation.
347346
/// - Returns: A stable string representation that can be checked in tests.
348-
public func dump(subHierarchyFrom path: String = "/") -> String {
347+
package func dump(subHierarchyFrom path: String = "/") -> String {
349348
filesLock.lock()
350349
defer { filesLock.unlock() }
351350

@@ -368,7 +367,7 @@ public class TestFileSystem: FileManagerProtocol, DocumentationWorkspaceDataProv
368367
}
369368

370369
// This is a convenience utility for testing, not FileManagerProtocol API
371-
public func recursiveContentsOfDirectory(atPath path: String) throws -> [String] {
370+
package func recursiveContentsOfDirectory(atPath path: String) throws -> [String] {
372371
var allSubpaths = try contentsOfDirectory(atPath: path)
373372

374373
for subpath in allSubpaths { // This is iterating over a copy

Sources/SwiftDocCUtilities/Action/Actions/Action+MoveOutput.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010

1111
import Foundation
12-
@_spi(FileManagerProtocol) import SwiftDocC
12+
import SwiftDocC
1313

1414
extension Action {
1515

Sources/SwiftDocCUtilities/Action/Actions/Convert/ConvertAction.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import Foundation
1212

1313
@_spi(ExternalLinks) // SPI to set `context.linkResolver.dependencyArchives`
14-
@_spi(FileManagerProtocol) // SPI to initialize `DiagnosticConsoleWriter` with a `FileManagerProtocol`
1514
import SwiftDocC
1615

1716
/// An action that converts a source bundle into compiled documentation.

Sources/SwiftDocCUtilities/Action/Actions/Convert/ConvertFileWritingConsumer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010

1111
import Foundation
12-
@_spi(FileManagerProtocol) import SwiftDocC
12+
import SwiftDocC
1313

1414
struct ConvertFileWritingConsumer: ConvertOutputConsumer {
1515
var targetFolder: URL

Sources/SwiftDocCUtilities/Action/Actions/Convert/CoverageDataEntry+generateSummary.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010

1111
import Foundation
12-
@_spi(FileManagerProtocol) import SwiftDocC
12+
import SwiftDocC
1313

1414
extension CoverageDataEntry {
1515
/// Outputs a short table summarizing the coverage statistics for a list of data entries in a file at the given URL.

Sources/SwiftDocCUtilities/Action/Actions/Convert/JSONEncodingRenderNodeWriter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010

1111
import Foundation
12-
@_spi(FileManagerProtocol) import SwiftDocC
12+
import SwiftDocC
1313

1414
/// An object that writes render nodes, as JSON files, into a target folder.
1515
///

Sources/SwiftDocCUtilities/Action/Actions/CoverageAction.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010

1111
import Foundation
12-
@_spi(FileManagerProtocol) import SwiftDocC
12+
import SwiftDocC
1313

1414
/// An action that creates documentation coverage info for a documentation bundle.
1515
public struct CoverageAction: Action {

Sources/SwiftDocCUtilities/Action/Actions/EmitGeneratedCurationAction.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010

1111
import Foundation
12-
@_spi(FileManagerProtocol) import SwiftDocC
12+
import SwiftDocC
1313

1414
/// An action that emits documentation extension files that reflect the auto-generated curation.
1515
struct EmitGeneratedCurationAction: Action {

0 commit comments

Comments
 (0)