diff --git a/Package.swift b/Package.swift index f7f36a4..cefb79d 100644 --- a/Package.swift +++ b/Package.swift @@ -135,6 +135,37 @@ let package = Package( ] ) +// Use https://www.swift.org/swift-evolution/ to see details of the upcoming/experimental features +let upcomingFeatureSwiftSettings: [SwiftSetting] = [ + "ConciseMagicFile", // SE-0274 + "ForwardTrailingClosures", // SE-0286 + "ExistentialAny", // SE-0335 + "BareSlashRegexLiterals", // SE-0354 + "ImportObjcForwardDeclarations", // SE-0384 + "DeprecateApplicationMain", // SE-0383 + "DisableOutwardActorInference", // SE-0401 + "IsolatedDefaultValues", // SE-0411 + "GlobalConcurrency" // SE-0412 +].map { + .enableUpcomingFeature($0) +} + +let experimentalFeatureSwiftSettings: [SwiftSetting] = [ + "AccessLevelOnImport", // SE-0409 + "StrictConcurrency" // SE-0412 +].map { + .enableExperimentalFeature($0) +} + +package.targets.forEach { target in + guard target.name != "XCStringsToolPlugin" else { + return // Plugins don't support setting `swiftSettings` + } + + let swiftSettings = target.swiftSettings ?? [] + target.swiftSettings = swiftSettings + upcomingFeatureSwiftSettings + experimentalFeatureSwiftSettings +} + // https://swiftpackageindex.com/swiftpackageindex/spimanifest/0.19.0/documentation/spimanifest/validation // On CI, we want to validate the manifest, but nobody else needs that. if ProcessInfo.processInfo.environment.keys.contains("VALIDATE_SPI_MANIFEST") { diff --git a/Sources/StringCatalog/Types/StringExtractionState.swift b/Sources/StringCatalog/Types/StringExtractionState.swift index a69840d..a4b0f60 100644 --- a/Sources/StringCatalog/Types/StringExtractionState.swift +++ b/Sources/StringCatalog/Types/StringExtractionState.swift @@ -1,6 +1,6 @@ import Foundation -public struct StringExtractionState: Codable, Hashable, RawRepresentable, ExpressibleByStringLiteral { +public struct StringExtractionState: Codable, Hashable, RawRepresentable, ExpressibleByStringLiteral, Sendable { public let rawValue: String public init(rawValue: String) { diff --git a/Sources/StringCatalog/Types/StringLanguage.swift b/Sources/StringCatalog/Types/StringLanguage.swift index 06b6f18..a00b0ef 100644 --- a/Sources/StringCatalog/Types/StringLanguage.swift +++ b/Sources/StringCatalog/Types/StringLanguage.swift @@ -1,6 +1,6 @@ import Foundation -public struct StringLanguage: Codable, Hashable, RawRepresentable, ExpressibleByStringLiteral, CodingKeyRepresentable { +public struct StringLanguage: Codable, Hashable, RawRepresentable, ExpressibleByStringLiteral, CodingKeyRepresentable, Sendable { public let rawValue: String public init(rawValue: String) { diff --git a/Sources/StringCatalog/Types/StringUnitState.swift b/Sources/StringCatalog/Types/StringUnitState.swift index decbf8d..931b8e8 100644 --- a/Sources/StringCatalog/Types/StringUnitState.swift +++ b/Sources/StringCatalog/Types/StringUnitState.swift @@ -1,6 +1,6 @@ import Foundation -public struct StringUnitState: Codable, Hashable, RawRepresentable, ExpressibleByStringLiteral { +public struct StringUnitState: Codable, Hashable, RawRepresentable, ExpressibleByStringLiteral, Sendable { public let rawValue: String public init(rawValue: String) { diff --git a/Sources/StringCatalog/Types/StringVariations.swift b/Sources/StringCatalog/Types/StringVariations.swift index a1c95b5..e3434d3 100644 --- a/Sources/StringCatalog/Types/StringVariations.swift +++ b/Sources/StringCatalog/Types/StringVariations.swift @@ -11,7 +11,7 @@ public struct StringVariations: Codable { } extension StringVariations { - public struct DeviceKey: Codable, Hashable, RawRepresentable, ExpressibleByStringLiteral, CodingKeyRepresentable { + public struct DeviceKey: Codable, Hashable, RawRepresentable, ExpressibleByStringLiteral, CodingKeyRepresentable, Sendable { public let rawValue: String public init(rawValue: String) { @@ -32,7 +32,7 @@ extension StringVariations { public static let other = Self(rawValue: "other") } - public struct PluralKey: Codable, Hashable, RawRepresentable, ExpressibleByStringLiteral, CodingKeyRepresentable { + public struct PluralKey: Codable, Hashable, RawRepresentable, ExpressibleByStringLiteral, CodingKeyRepresentable, Sendable { public let rawValue: String public init(rawValue: String) { diff --git a/Sources/StringExtractor/ExtractionError.swift b/Sources/StringExtractor/ExtractionError.swift index 0611851..034b52c 100644 --- a/Sources/StringExtractor/ExtractionError.swift +++ b/Sources/StringExtractor/ExtractionError.swift @@ -1,7 +1,7 @@ import Foundation public enum ExtractionError: Error { - public struct Context { + public struct Context: Sendable { /// The key of the localization being parsed public let key: String diff --git a/Sources/xcstrings-tool/XCStringsTool.swift b/Sources/xcstrings-tool/XCStringsTool.swift index 2299f89..a89f16b 100644 --- a/Sources/xcstrings-tool/XCStringsTool.swift +++ b/Sources/xcstrings-tool/XCStringsTool.swift @@ -3,7 +3,7 @@ import XCStringsToolConstants @main struct XCStringsTool: ParsableCommand { - static var configuration = CommandConfiguration( + static let configuration = CommandConfiguration( commandName: "xcstrings-tool", abstract: "Generates Swift code from String Catalogs (.xcstrings files)", version: version, diff --git a/Tests/XCStringsToolTests/FixtureTestCase.swift b/Tests/XCStringsToolTests/FixtureTestCase.swift index 12a2cf6..8ca5659 100644 --- a/Tests/XCStringsToolTests/FixtureTestCase.swift +++ b/Tests/XCStringsToolTests/FixtureTestCase.swift @@ -11,7 +11,7 @@ class FixtureTestCase: XCTestCase { fixtures = try XCTUnwrap(bundle.urls(forResourcesWithExtension: "xcstrings", subdirectory: "__Fixtures__")) } - func eachFixture(_ test: (URL) throws -> Void) throws { + @MainActor func eachFixture(_ test: (URL) throws -> Void) throws { for fileURL in fixtures { try XCTContext.runActivity(named: fileURL.lastPathComponent) { activity in do { diff --git a/Tests/XCStringsToolTests/GenerateTests.swift b/Tests/XCStringsToolTests/GenerateTests.swift index 35cce08..70d7f4d 100644 --- a/Tests/XCStringsToolTests/GenerateTests.swift +++ b/Tests/XCStringsToolTests/GenerateTests.swift @@ -4,7 +4,7 @@ import SnapshotTesting import XCTest final class GenerateTests: FixtureTestCase { - func testGenerate() throws { + @MainActor func testGenerate() throws { try eachFixture { inputURL in if !inputURL.lastPathComponent.hasPrefix("!") { try snapshot(for: inputURL) @@ -79,7 +79,7 @@ private extension GenerateTests { func assertError( for inputURL: URL, localizedDescription expected: String, - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line ) { XCTAssertThrowsError(try run(for: inputURL), file: file, line: line) { error in @@ -106,6 +106,7 @@ private extension GenerateTests { // Cleanup any temporary output addTeardownBlock { + let fileManager = FileManager.default // Needed because `FileManager` is not `Sendable` if fileManager.fileExists(atPath: outputURL.path()) { try? fileManager.removeItem(at: outputURL) } @@ -137,5 +138,7 @@ extension URL { extension Snapshotting where Value == String, Format == String { /// A snapshot strategy for comparing Swift Source Code based on equality. - public static let sourceCode = Snapshotting(pathExtension: "swift", diffing: .lines) + public static var sourceCode: Snapshotting { + Snapshotting(pathExtension: "swift", diffing: .lines) + } }