Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ArgumentParser #16

Merged
merged 9 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"pins" : [
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser.git",
"state" : {
"revision" : "46989693916f56d1186bd59ac15124caef896560",
"version" : "1.3.1"
}
}
],
"version" : 2
}
8 changes: 7 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ let package = Package(
products: [
.executable(name: "swiftpolyglot", targets: ["SwiftPolyglot"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser.git", .upToNextMajor(from: "1.3.1")),
],
targets: [
.executableTarget(
name: "SwiftPolyglot",
dependencies: ["SwiftPolyglotCore"]
dependencies: [
"SwiftPolyglotCore",
.product(name: "ArgumentParser", package: "swift-argument-parser")
]
),
.target(name: "SwiftPolyglotCore"),
.testTarget(
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ $ swift build -c release

```
$ cd ../path/to/your/project
$ swift run --package-path ../path/to/SwiftPolyglot swiftpolyglot "en,es,de"
$ swift run --package-path ../path/to/SwiftPolyglot swiftpolyglot en es de
```

## Arguments

You must specify at least one language code, they must be within quotation marks, and they must be separated by commas. If you are not providing a translation for your language of origin, you do not need to specify that language. Otherwise, you will get errors due to missing translations.
You must specify at least one language code, and they must be separated by spaces. If you are not providing a translation for your language of origin, you do not need to specify that language. Otherwise, you will get errors due to missing translations.

By default, SwiftPolyglot will not throw an error at the end of the script if there are translations missing. However, you can enable error throwing by adding the argument `--errorOnMissing`
By default, SwiftPolyglot will not throw an error at the end of the script if there are translations missing. However, you can enable error throwing by adding the flag `--error-on-missing`

## Integrating with GitHub Actions

Expand All @@ -60,6 +60,6 @@ jobs:
- name: validate translations
run: |
swift build --package-path ../SwiftPolyglot --configuration release
swift run --package-path ../SwiftPolyglot swiftpolyglot "es,fr,de,it" --errorOnMissing
swift run --package-path ../SwiftPolyglot swiftpolyglot es fr de it --error-on-missing
```

15 changes: 15 additions & 0 deletions Sources/SwiftPolyglot/RuntimeError.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
enum RuntimeError: Error {
case coreError(description: String)
case fileListingNotPossible
}

extension RuntimeError: CustomStringConvertible {
var description: String {
switch self {
case let .coreError(description):
return description
case .fileListingNotPossible:
return "It was not possible to list all files to be checked"
}
}
}
36 changes: 36 additions & 0 deletions Sources/SwiftPolyglot/SwiftPolyglot.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import ArgumentParser
import Foundation
import SwiftPolyglotCore

@main
struct SwiftPolyglot: ParsableCommand {
static let configuration: CommandConfiguration = .init(commandName: "swiftpolyglot")

@Flag(help: "Log errors instead of warnings for missing translations.")
private var errorOnMissing = false

@Argument(help: "Specify the language(s) to be checked.")
private var languages: [String]

func run() throws {
guard
let enumerator = FileManager.default.enumerator(atPath: FileManager.default.currentDirectoryPath),
let filePaths = enumerator.allObjects as? [String]
else {
throw RuntimeError.fileListingNotPossible
}

let swiftPolyglotCore: SwiftPolyglotCore = .init(
filePaths: filePaths,
languageCodes: languages,
logsErrorOnMissingTranslation: errorOnMissing,
isRunningInAGitHubAction: ProcessInfo.processInfo.environment["GITHUB_ACTIONS"] == "true"
)

do {
try swiftPolyglotCore.run()
} catch {
throw RuntimeError.coreError(description: error.localizedDescription)
}
}
}
22 changes: 0 additions & 22 deletions Sources/SwiftPolyglot/main.swift

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,39 +1,29 @@
import Foundation

public struct SwiftPolyglot {
private static let errorOnMissingArgument = "--errorOnMissing"

private let arguments: [String]
public struct SwiftPolyglotCore {
private let filePaths: [String]
private let languageCodes: [String]
private let runningOnAGitHubAction: Bool

private var logErrorOnMissing: Bool {
arguments.contains(Self.errorOnMissingArgument)
}

public init(arguments: [String], filePaths: [String], runningOnAGitHubAction: Bool) throws {
let languageCodes = arguments[0].split(separator: ",").map(String.init)

guard
!languageCodes.contains(Self.errorOnMissingArgument),
!languageCodes.isEmpty
else {
throw SwiftPolyglotError.noLanguageCodes
}

self.arguments = arguments
private let logsErrorOnMissingTranslation: Bool
private let isRunningInAGitHubAction: Bool

public init(
filePaths: [String],
languageCodes: [String],
logsErrorOnMissingTranslation: Bool,
isRunningInAGitHubAction: Bool
) {
self.filePaths = filePaths
self.languageCodes = languageCodes
self.runningOnAGitHubAction = runningOnAGitHubAction
self.logsErrorOnMissingTranslation = logsErrorOnMissingTranslation
self.isRunningInAGitHubAction = isRunningInAGitHubAction
}

public func run() throws {
var missingTranslations = false

try searchDirectory(for: languageCodes, missingTranslations: &missingTranslations)

if missingTranslations, logErrorOnMissing {
if missingTranslations, logsErrorOnMissingTranslation {
throw SwiftPolyglotError.missingTranslations
} else if missingTranslations {
print("Completed with missing translations.")
Expand Down Expand Up @@ -90,7 +80,7 @@ public struct SwiftPolyglot {
let jsonDict = jsonObject as? [String: Any],
let strings = jsonDict["strings"] as? [String: [String: Any]]
else {
if runningOnAGitHubAction {
if isRunningInAGitHubAction {
print("::warning file=\(fileURL.path)::Could not process file at path: \(fileURL.path)")
} else {
print("Could not process file at path: \(fileURL.path)")
Expand Down Expand Up @@ -170,8 +160,8 @@ public struct SwiftPolyglot {
}

private func logWarning(file: String, message: String) {
if runningOnAGitHubAction {
if logErrorOnMissing {
if isRunningInAGitHubAction {
if logsErrorOnMissingTranslation {
print("::error file=\(file)::\(message)")
} else {
print("::warning file=\(file)::\(message)")
Expand Down
11 changes: 4 additions & 7 deletions Sources/SwiftPolyglotCore/SwiftPolyglotError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@ import Foundation

enum SwiftPolyglotError: Error {
case missingTranslations
case noLanguageCodes
case unsupportedVariation(variation: String)
}

extension SwiftPolyglotError: LocalizedError {
public var errorDescription: String? {
switch self {
case .missingTranslations:
return "Error: One or more translations are missing."
case .noLanguageCodes:
return "Usage: swiftpolyglot <comma-separated language codes> [--errorOnMissing]"
case let .unsupportedVariation(variation):
return "Variation type '\(variation)' is not supported. Please create an issue in GitHub"
case .missingTranslations:
return "Error: One or more translations are missing."
case let .unsupportedVariation(variation):
return "Variation type '\(variation)' is not supported. Please create an issue in GitHub"
}
}
}
36 changes: 20 additions & 16 deletions Tests/SwiftPolyglotCoreTests/SwiftPolyglotCoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ final class SwiftPolyglotCoreTests: XCTestCase {
return
}

let swiftPolyglot: SwiftPolyglot = try .init(
arguments: ["ca,de,en,es"],
let swiftPolyglotCore: SwiftPolyglotCore = .init(
filePaths: [stringCatalogFilePath],
runningOnAGitHubAction: false
languageCodes: ["ca", "de", "en", "es"],
logsErrorOnMissingTranslation: false,
isRunningInAGitHubAction: false
)

XCTAssertNoThrow(try swiftPolyglot.run())
XCTAssertNoThrow(try swiftPolyglotCore.run())
}

func testStringCatalogVariationsFullyTranslated() throws {
Expand All @@ -35,13 +36,14 @@ final class SwiftPolyglotCoreTests: XCTestCase {
return
}

let swiftPolyglot: SwiftPolyglot = try .init(
arguments: ["ca,de,en,es"],
let swiftPolyglotCore: SwiftPolyglotCore = .init(
filePaths: [stringCatalogFilePath],
runningOnAGitHubAction: false
languageCodes: ["ca", "de", "en", "es"],
logsErrorOnMissingTranslation: false,
isRunningInAGitHubAction: false
)

XCTAssertNoThrow(try swiftPolyglot.run())
XCTAssertNoThrow(try swiftPolyglotCore.run())
}

func testStringCatalogWithMissingTranslations() throws {
Expand All @@ -56,13 +58,14 @@ final class SwiftPolyglotCoreTests: XCTestCase {
return
}

let swiftPolyglot: SwiftPolyglot = try .init(
arguments: ["ca,de,en,es", "--errorOnMissing"],
let swiftPolyglotCore: SwiftPolyglotCore = .init(
filePaths: [stringCatalogFilePath],
runningOnAGitHubAction: false
languageCodes: ["ca", "de", "en", "es"],
logsErrorOnMissingTranslation: true,
isRunningInAGitHubAction: false
)

XCTAssertThrowsError(try swiftPolyglot.run())
XCTAssertThrowsError(try swiftPolyglotCore.run())
}

func testStringCatalogWithMissingVariations() throws {
Expand All @@ -77,12 +80,13 @@ final class SwiftPolyglotCoreTests: XCTestCase {
return
}

let swiftPolyglot: SwiftPolyglot = try .init(
arguments: ["de,en", "--errorOnMissing"],
let swiftPolyglotCore: SwiftPolyglotCore = .init(
filePaths: [stringCatalogFilePath],
runningOnAGitHubAction: false
languageCodes: ["de, en"],
logsErrorOnMissingTranslation: true,
isRunningInAGitHubAction: false
)

XCTAssertThrowsError(try swiftPolyglot.run())
XCTAssertThrowsError(try swiftPolyglotCore.run())
}
}
Loading