Refactor in one unique command with subcommand + add a new command to generate ressources from a configuration file
Some checks failed
gitea-openium/resgen.swift/pipeline/head There was a failure building this commit
Some checks failed
gitea-openium/resgen.swift/pipeline/head There was a failure building this commit
This commit is contained in:
118
Sources/ResgenSwift/Strings/Stringium/Stringium.swift
Normal file
118
Sources/ResgenSwift/Strings/Stringium/Stringium.swift
Normal file
@ -0,0 +1,118 @@
|
||||
//
|
||||
// Stringium.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 10/01/2022.
|
||||
//
|
||||
|
||||
import ToolCore
|
||||
import Foundation
|
||||
import ArgumentParser
|
||||
|
||||
struct Stringium: ParsableCommand {
|
||||
|
||||
// MARK: - Command Configuration
|
||||
|
||||
static var configuration = CommandConfiguration(
|
||||
abstract: "Generate strings with custom scripts.",
|
||||
version: ResgenSwiftVersion
|
||||
)
|
||||
|
||||
// MARK: - Static
|
||||
|
||||
static let toolName = "Stringium"
|
||||
static let defaultExtensionName = "String"
|
||||
static let noTranslationTag: String = "notranslation"
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
var extensionFileName: String {
|
||||
if let extensionSuffix = options.extensionSuffix {
|
||||
return "\(options.extensionName)+\(extensionSuffix).swift"
|
||||
}
|
||||
return "\(options.extensionName).swift"
|
||||
}
|
||||
|
||||
var extensionFilePath: String { "\(options.extensionOutputPath)/\(extensionFileName)" }
|
||||
|
||||
var inputFilenameWithoutExt: String {
|
||||
URL(fileURLWithPath: options.inputFile)
|
||||
.deletingPathExtension()
|
||||
.lastPathComponent
|
||||
}
|
||||
|
||||
var generateStaticVariable: Bool {
|
||||
options.extensionName == Self.defaultExtensionName
|
||||
}
|
||||
|
||||
// MARK: - Command options
|
||||
|
||||
@OptionGroup var options: StringiumOptions
|
||||
|
||||
// MARK: - Run
|
||||
|
||||
mutating func run() {
|
||||
print("[\(Self.toolName)] Starting strings generation")
|
||||
|
||||
// Check requirements
|
||||
guard checkRequirements() else { return }
|
||||
|
||||
print("[\(Self.toolName)] Will generate strings")
|
||||
|
||||
// Parse input file
|
||||
let sections = TwineFileParser.parse(options.inputFile)
|
||||
|
||||
// Generate strings files
|
||||
StringsFileGenerator.writeStringsFiles(sections: sections,
|
||||
langs: options.langs,
|
||||
defaultLang: options.defaultLang,
|
||||
tags: options.tags,
|
||||
outputPath: options.stringsFileOutputPath,
|
||||
inputFilenameWithoutExt: inputFilenameWithoutExt)
|
||||
|
||||
// Generate extension
|
||||
StringsFileGenerator.writeExtensionFiles(sections: sections,
|
||||
defaultLang: options.defaultLang,
|
||||
tags: options.tags,
|
||||
staticVar: generateStaticVariable,
|
||||
inputFilename: inputFilenameWithoutExt,
|
||||
extensionName: options.extensionName,
|
||||
extensionFilePath: extensionFilePath)
|
||||
|
||||
print("[\(Self.toolName)] Strings generated")
|
||||
}
|
||||
|
||||
// MARK: - Requirements
|
||||
|
||||
private func checkRequirements() -> Bool {
|
||||
let fileManager = FileManager()
|
||||
|
||||
// Input file
|
||||
guard fileManager.fileExists(atPath: options.inputFile) else {
|
||||
let error = StringiumError.fileNotExists(options.inputFile)
|
||||
print(error.localizedDescription)
|
||||
Stringium.exit(withError: error)
|
||||
}
|
||||
|
||||
// Langs
|
||||
guard options.langs.isEmpty == false else {
|
||||
let error = StringiumError.langsListEmpty
|
||||
print(error.localizedDescription)
|
||||
Stringium.exit(withError: error)
|
||||
}
|
||||
|
||||
guard options.langs.contains(options.defaultLang) else {
|
||||
let error = StringiumError.defaultLangsNotInLangs
|
||||
print(error.localizedDescription)
|
||||
Stringium.exit(withError: error)
|
||||
}
|
||||
|
||||
// Check if needed to regenerate
|
||||
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration, inputFilePath: options.inputFile, extensionFilePath: extensionFilePath) else {
|
||||
print("[\(Self.toolName)] Strings are already up to date :) ")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
38
Sources/ResgenSwift/Strings/Stringium/StringiumError.swift
Normal file
38
Sources/ResgenSwift/Strings/Stringium/StringiumError.swift
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// StringToolError.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 05/01/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum StringiumError: Error {
|
||||
case fileNotExists(String)
|
||||
case langsListEmpty
|
||||
case defaultLangsNotInLangs
|
||||
case writeFile(String, String)
|
||||
case langNotDefined(String, String, Bool)
|
||||
|
||||
var localizedDescription: String {
|
||||
switch self {
|
||||
case .fileNotExists(let filename):
|
||||
return " error:[\(Stringium.toolName)] File \(filename) does not exists "
|
||||
|
||||
case .langsListEmpty:
|
||||
return " error:[\(Stringium.toolName)] Langs list is empty"
|
||||
|
||||
case .defaultLangsNotInLangs:
|
||||
return " error:[\(Stringium.toolName)] Langs list does not contains the default lang"
|
||||
|
||||
case .writeFile(let subErrorDescription, let filename):
|
||||
return " error:[\(Stringium.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)"
|
||||
|
||||
case .langNotDefined(let lang, let definitionName, let isReference):
|
||||
if isReference {
|
||||
return " error:[\(Stringium.toolName)] Reference are handled only by TwineTool. Please use it or remove reference from you strings file."
|
||||
}
|
||||
return " error:[\(Stringium.toolName)] Lang \"\(lang)\" not found for \"\(definitionName)\""
|
||||
}
|
||||
}
|
||||
}
|
60
Sources/ResgenSwift/Strings/Stringium/StringiumOptions.swift
Normal file
60
Sources/ResgenSwift/Strings/Stringium/StringiumOptions.swift
Normal file
@ -0,0 +1,60 @@
|
||||
//
|
||||
// StringiumOptions.swift
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 10/01/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ArgumentParser
|
||||
|
||||
struct StringiumOptions: ParsableArguments {
|
||||
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
||||
var forceGeneration = false
|
||||
|
||||
@Argument(help: "Input files where strings ared defined.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
||||
var inputFile: String
|
||||
|
||||
@Option(name: .customLong("output-path"), help: "Path where to strings file.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
||||
fileprivate var outputPathRaw: String
|
||||
|
||||
@Option(name: .customLong("langs"), help: "Langs to generate.")
|
||||
fileprivate var langsRaw: String
|
||||
|
||||
@Option(help: "Default langs.")
|
||||
var defaultLang: String
|
||||
|
||||
@Option(name: .customLong("tags"), help: "Tags to generate.")
|
||||
fileprivate var tagsRaw: String = "ios iosonly iosOnly notranslation"
|
||||
|
||||
@Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
||||
var extensionOutputPath: String
|
||||
|
||||
@Option(help: "Extension name. If not specified, it will generate an String extension. Using default extension name will generate static property.")
|
||||
var extensionName: String = Stringium.defaultExtensionName
|
||||
|
||||
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+{extensionSuffix}.swift")
|
||||
var extensionSuffix: String?
|
||||
}
|
||||
|
||||
extension StringiumOptions {
|
||||
var stringsFileOutputPath: String {
|
||||
var outputPath = outputPathRaw
|
||||
if outputPath.last == "/" {
|
||||
outputPath = String(outputPath.dropLast())
|
||||
}
|
||||
return outputPath
|
||||
}
|
||||
|
||||
var langs: [String] {
|
||||
langsRaw
|
||||
.split(separator: " ")
|
||||
.map { String($0) }
|
||||
}
|
||||
|
||||
var tags: [String] {
|
||||
tagsRaw
|
||||
.split(separator: " ")
|
||||
.map { String($0) }
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user