diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 0000000..459782b --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,88 @@ +name: Pull Request + +on: + pull_request: + branches: [ main ] + workflow_dispatch: + +env: + SCHEME: "TranslationCatalog" + +jobs: + Lint: + runs-on: macos-26 + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Lint + run: swiftformat --lint . --reporter github-actions-log + + Swift: + strategy: + fail-fast: false + matrix: + os: [ + macos-26, + ubuntu-latest, + ] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Cache + uses: actions/cache@v5 + with: + path: | + .build + ~/Library/Developer/Xcode/DerivedData/ModuleCache.noindex + ~/Library/Caches/org.swift.swiftpm + ~/Library/org.swift.swiftpm + key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.swift', '**/Package.resolved') }} + restore-keys: | + ${{ runner.os }}-spm- + - name: Package Resolution + run: swift package resolve + - name: Build + run: swift build + - name: Test + run: swift test + + Xcode: + strategy: + fail-fast: false + matrix: + platform: [ + "macOS", + "iOS", + "tvOS", + "watchOS", + "visionOS", + "macOS,variant=Mac Catalyst", + ] + runs-on: macos-26 + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Cache + uses: actions/cache@v5 + with: + path: | + .build + ~/Library/Developer/Xcode/DerivedData/ModuleCache.noindex + ~/Library/Caches/org.swift.swiftpm + ~/Library/org.swift.swiftpm + key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.swift', '**/Package.resolved') }} + restore-keys: | + ${{ runner.os }}-spm- + - name: Package Resolution + run: set -o pipefail && xcodebuild -resolvePackageDependencies | xcbeautify + - name: Build + env: + DESTINATION: "generic/platform=${{ matrix.platform }}" + shell: bash + run: | + xcodebuild \ + -scheme "$SCHEME" \ + -destination "$DESTINATION" \ + build \ + | xcbeautify diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml deleted file mode 100644 index de257f1..0000000 --- a/.github/workflows/swift.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Swift - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - workflow_dispatch: - -jobs: - SwiftActions: - strategy: - fail-fast: false - matrix: - os: [macos-15, ubuntu-latest] - - runs-on: ${{ matrix.os }} - - steps: - - name: Checkout Source - uses: actions/checkout@v4 - - - name: Setup Toolchain - if: ${{ runner.os == 'Linux' }} - shell: bash - run: sudo apt-get install sqlite3 libsqlite3-dev - - - name: Swift Build - uses: SwiftActions/SwiftBuild@main - - - name: Swift Test - uses: SwiftActions/SwiftTest@main - \ No newline at end of file diff --git a/.swiftformat b/.swiftformat index 66a20d4..17d120d 100644 --- a/.swiftformat +++ b/.swiftformat @@ -11,5 +11,7 @@ --disable blankLinesAtStartOfScope --disable hoistPatternLet --disable redundantType +--disable swiftTestingTestCaseNames --disable unusedArguments --disable wrapArguments +--disable wrapPropertyBodies diff --git a/Sources/TranslationCatalogIO/Internal/Resource.swift b/Sources/TranslationCatalogIO/Internal/Resource.swift index 0be5baa..544aa12 100644 --- a/Sources/TranslationCatalogIO/Internal/Resource.swift +++ b/Sources/TranslationCatalogIO/Internal/Resource.swift @@ -21,7 +21,7 @@ struct Resource: Codable, DynamicNodeDecoding, DynamicNodeEncoding { .element } } - + static func nodeEncoding(for key: any CodingKey) -> XMLEncoder.NodeEncoding { switch key { case CodingKeys.name, CodingKeys.formatted: diff --git a/Sources/TranslationCatalogIO/Internal/StringsXml.swift b/Sources/TranslationCatalogIO/Internal/StringsXml.swift index 779f050..851a37e 100644 --- a/Sources/TranslationCatalogIO/Internal/StringsXml.swift +++ b/Sources/TranslationCatalogIO/Internal/StringsXml.swift @@ -12,7 +12,7 @@ struct StringsXml: Codable, DynamicNodeDecoding, DynamicNodeEncoding { static func nodeDecoding(for key: CodingKey) -> XMLDecoder.NodeDecoding { .element } - + static func nodeEncoding(for key: any CodingKey) -> XMLEncoder.NodeEncoding { .element } @@ -25,7 +25,7 @@ struct StringsXml: Codable, DynamicNodeDecoding, DynamicNodeEncoding { static func make(with data: Data) throws -> StringsXml { try XMLDecoder().decode(StringsXml.self, from: data) } - + func encoded() throws -> Data { let encoder = XMLEncoder() encoder.outputFormatting = [.sortedKeys] diff --git a/Sources/localizer/Extensions/FileManager+localizer.swift b/Sources/localizer/Extensions/FileManager+localizer.swift index b164776..e85522a 100644 --- a/Sources/localizer/Extensions/FileManager+localizer.swift +++ b/Sources/localizer/Extensions/FileManager+localizer.swift @@ -11,8 +11,7 @@ extension FileManager { // Relative Path? let directory = URL(fileURLWithPath: currentDirectoryPath, isDirectory: true) - let relativeURL = directory.appendingPathComponent(filename) - return relativeURL + return directory.appendingPathComponent(filename) } @available(*, deprecated) diff --git a/Tests/TranslationCatalogTests/ExpressionEncoderTests.swift b/Tests/TranslationCatalogTests/ExpressionEncoderTests.swift index b399369..6c50c72 100644 --- a/Tests/TranslationCatalogTests/ExpressionEncoderTests.swift +++ b/Tests/TranslationCatalogTests/ExpressionEncoderTests.swift @@ -3,7 +3,7 @@ import TranslationCatalog import XCTest final class ExpressionEncoderTests: XCTestCase { - + private let locale: Locale = Locale(identifier: "en_US") private let expressions: [TranslationCatalog.Expression] = [ Expression( @@ -25,7 +25,7 @@ final class ExpressionEncoderTests: XCTestCase { languageCode: .english ), ] - + func testAndroidXMLEncoding() throws { let data = try ExpressionEncoder.encodeValues( for: expressions, @@ -43,7 +43,7 @@ final class ExpressionEncoderTests: XCTestCase { """) } - + func testAppleStringsEncoding() throws { let data = try ExpressionEncoder.encodeValues( for: expressions, @@ -58,7 +58,7 @@ final class ExpressionEncoderTests: XCTestCase { "EXP_03" = "Hello %@, welcome to %@!"; """) } - + func testJSONEncoding() throws { let data = try ExpressionEncoder.encodeValues( for: expressions, diff --git a/Tests/TranslationCatalogTests/FilesystemEncodingTests.swift b/Tests/TranslationCatalogTests/FilesystemEncodingTests.swift index d0270df..06a02ef 100644 --- a/Tests/TranslationCatalogTests/FilesystemEncodingTests.swift +++ b/Tests/TranslationCatalogTests/FilesystemEncodingTests.swift @@ -5,13 +5,13 @@ import XCTest class FilesystemEncodingTests: XCTestCase { func testProjectDocumentEncoding() throws { - let document = ProjectDocument( - id: UUID(uuidString: "24D67823-F859-40A1-88C2-A56F1170905B")!, + let document = try ProjectDocument( + id: XCTUnwrap(UUID(uuidString: "24D67823-F859-40A1-88C2-A56F1170905B")), name: "Example", expressionIds: [ - UUID(uuidString: "7F9D2FF1-31C1-47A1-94EE-E23BB0A7AD2B")!, - UUID(uuidString: "592E488D-4E3C-490B-8725-C45FF7DEC872")!, - UUID(uuidString: "FB7C761C-9026-49C2-BBC7-9B7B897CAA6D")!, + XCTUnwrap(UUID(uuidString: "7F9D2FF1-31C1-47A1-94EE-E23BB0A7AD2B")), + XCTUnwrap(UUID(uuidString: "592E488D-4E3C-490B-8725-C45FF7DEC872")), + XCTUnwrap(UUID(uuidString: "FB7C761C-9026-49C2-BBC7-9B7B897CAA6D")), ] ) diff --git a/Tests/TranslationCatalogTests/KeyHierarchy2Tests.swift b/Tests/TranslationCatalogTests/KeyHierarchy2Tests.swift index a3e5dd0..4de1e80 100644 --- a/Tests/TranslationCatalogTests/KeyHierarchy2Tests.swift +++ b/Tests/TranslationCatalogTests/KeyHierarchy2Tests.swift @@ -51,7 +51,7 @@ final class KeyHierarchy2Tests: XCTestCase { hierarchy = try KeyHierarchy.make(with: keys) } - func testHierarchyGeneration() throws { + func testHierarchyGeneration() { XCTAssertTrue(hierarchy.contents.isEmpty) XCTAssertEqual(hierarchy.nodes.count, 1) XCTAssertEqual(hierarchy.nodes.map(\.id), [ @@ -63,7 +63,7 @@ final class KeyHierarchy2Tests: XCTestCase { XCTAssertTrue(hierarchy.containsPhantoms) } - func testNodeAtPath() throws { + func testNodeAtPath() { var node = hierarchy.node(at: [["UNKNOWN"]]) XCTAssertNil(node) node = hierarchy.node(at: [["PAYMENT"], ["METHOD"], ["EXPIRATION"]]) @@ -72,12 +72,12 @@ final class KeyHierarchy2Tests: XCTestCase { XCTAssertNotNil(node) } - func testRemoveNodeAtPath() throws { + func testRemoveNodeAtPath() { let node = hierarchy.removeNode(at: [["PAYMENT"], ["METHOD"], ["CONFIRM"]]) XCTAssertNotNil(node) } - func testOrphanNodes() throws { + func testOrphanNodes() { let nodes = hierarchy.orphanNodes() XCTAssertEqual(nodes.count, 8) XCTAssertEqual(nodes, [ @@ -92,7 +92,7 @@ final class KeyHierarchy2Tests: XCTestCase { ]) } - func testPhantomNodes() throws { + func testPhantomNodes() { let nodes = hierarchy.phantomNodes() XCTAssertEqual(nodes.count, 2) XCTAssertEqual(nodes, [ @@ -101,7 +101,7 @@ final class KeyHierarchy2Tests: XCTestCase { ]) } - func testLocalizedStringConvertible() throws { + func testLocalizedStringConvertible() { let syntax = hierarchy.syntaxTree() XCTAssertEqual(syntax, """ import LocaleSupport diff --git a/Tests/TranslationCatalogTests/KeyHierarchyTests.swift b/Tests/TranslationCatalogTests/KeyHierarchyTests.swift index e125196..4321030 100644 --- a/Tests/TranslationCatalogTests/KeyHierarchyTests.swift +++ b/Tests/TranslationCatalogTests/KeyHierarchyTests.swift @@ -47,7 +47,7 @@ final class KeyHierarchyTests: XCTestCase { hierarchy = try KeyHierarchy.make(with: keys) } - func testHierarchyGeneration() throws { + func testHierarchyGeneration() { XCTAssertEqual(hierarchy.contents.count, 1) XCTAssertEqual(Array(hierarchy.contents.keys), [ ["GREETING"], @@ -65,7 +65,7 @@ final class KeyHierarchyTests: XCTestCase { XCTAssertTrue(hierarchy.containsPhantoms) } - func testNodeAtPath() throws { + func testNodeAtPath() { var node = hierarchy.node(at: [["UNKNOWN"]]) XCTAssertNil(node) node = hierarchy.node(at: [["HIDDEN"]]) @@ -74,12 +74,12 @@ final class KeyHierarchyTests: XCTestCase { XCTAssertNotNil(node) } - func testRemoveNodeAtPath() throws { + func testRemoveNodeAtPath() { let node = hierarchy.removeNode(at: [["PLATFORM"], ["APPLE"]]) XCTAssertNotNil(node) } - func testOrphanNodes() throws { + func testOrphanNodes() { let nodes = hierarchy.orphanNodes() XCTAssertEqual(nodes.count, 4) XCTAssertEqual(nodes, [ @@ -90,7 +90,7 @@ final class KeyHierarchyTests: XCTestCase { ]) } - func testPhantomNodes() throws { + func testPhantomNodes() { let nodes = hierarchy.phantomNodes() XCTAssertEqual(nodes.count, 1) XCTAssertEqual(nodes, [ @@ -98,7 +98,7 @@ final class KeyHierarchyTests: XCTestCase { ]) } - func testLocalizedStringConvertible() throws { + func testLocalizedStringConvertible() { let syntax = hierarchy.syntaxTree() XCTAssertEqual(syntax, """ import LocaleSupport @@ -214,7 +214,7 @@ final class KeyHierarchyTests: XCTestCase { key: "ZULU_ZONE", defaultValue: "zone" ) - var test = hierarchy! + var test = try XCTUnwrap(hierarchy) try test.processKey(key, path: [["ZULU"], ["ZONE"]]) let syntax = try test .compressed(mergePhantoms: false) diff --git a/Tests/TranslationCatalogTests/NodeSortTests.swift b/Tests/TranslationCatalogTests/NodeSortTests.swift index c2b1939..ca8d849 100644 --- a/Tests/TranslationCatalogTests/NodeSortTests.swift +++ b/Tests/TranslationCatalogTests/NodeSortTests.swift @@ -7,7 +7,7 @@ final class NodeSortTests: XCTestCase { let comparator = NodePathSortComparator() - func testSorting() throws { + func testSorting() { let nodes: [Node] = [ [["Account"], ["New"]], [["Account"], ["Add"]],