feat(RES-34): Fix plist font filename (#14)
All checks were successful
gitea-openium/resgen.swift/pipeline/head This commit looks good

Reviewed-on: #14
This commit is contained in:
2025-05-05 09:53:05 +02:00
parent 8442c89944
commit 756de4f1de
96 changed files with 3028 additions and 2852 deletions

View File

@ -8,7 +8,7 @@
import Foundation
extension String {
func prependIfRelativePath(_ prependPath: String) -> String {
// If path starts with "/", it's an absolute path
if self.hasPrefix("/") {

View File

@ -5,32 +5,32 @@
// Created by Thibaut Schmitt on 30/08/2022.
//
import ToolCore
import Foundation
import ArgumentParser
import Foundation
import ToolCore
struct Generate: ParsableCommand {
// MARK: - CommandConfiguration
static var configuration = CommandConfiguration(
abstract: "A utility to generate ressources based on a configuration file",
version: ResgenSwiftVersion
)
// MARK: - Static
static let toolName = "Generate"
// MARK: - Command Options
@OptionGroup var options: GenerateOptions
// MARK: - Run
public func run() throws {
func run() throws {
print("[\(Self.toolName)] Starting Resgen with configuration: \(options.configurationFile)")
// Parse
let configuration = ConfigurationFileParser.parse(options.configurationFile)
print("Found configurations :")
@ -41,18 +41,22 @@ struct Generate: ParsableCommand {
print(" - \(configuration.strings.count) strings configuration(s)")
print(" - \(configuration.tags.count) tags configuration(s)")
print()
if let architecture = configuration.architecture {
ArchitectureGenerator.writeArchitecture(architecture,
projectDirectory: options.projectDirectory)
ArchitectureGenerator.writeArchitecture(
architecture,
projectDirectory: options.projectDirectory
)
}
// Execute commands
configuration.runnableConfigurations
.forEach {
let begin = Date()
$0.run(projectDirectory: options.projectDirectory,
force: options.forceGeneration)
$0.run(
projectDirectory: options.projectDirectory,
force: options.forceGeneration
)
print("Took: \(Date().timeIntervalSince(begin))s\n")
}

View File

@ -8,26 +8,26 @@
import Foundation
enum GenerateError: Error {
case fileNotExists(String)
case invalidConfigurationFile(String, String)
case commandError([String], String)
case writeFile(String, String)
var description: String {
switch self {
case .fileNotExists(let filename):
return "error: [\(Generate.toolName)] File \(filename) does not exists"
case .invalidConfigurationFile(let filename, let underneathErrorDescription):
case let .invalidConfigurationFile(filename, underneathErrorDescription):
return "error: [\(Generate.toolName)] File \(filename) is not a valid configuration file. Underneath error: \(underneathErrorDescription)"
case .commandError(let command, let terminationStatus):
case let .commandError(command, terminationStatus):
let readableCommand = command
.map { $0 }
.joined(separator: " ")
return "error: [\(Generate.toolName)] An error occured while running command '\(readableCommand)'. Command terminate with status code: \(terminationStatus)"
case .writeFile(let filename, let info):
case let .writeFile(filename, info):
return "error: [\(Generate.toolName)] An error occured while writing file in \(filename): \(info)"
}
}

View File

@ -5,16 +5,17 @@
// Created by Thibaut Schmitt on 30/08/2022.
//
import Foundation
import ArgumentParser
import Foundation
struct GenerateOptions: ParsableArguments {
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
var forceGeneration = false
@Argument(help: "Configuration file.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
var configurationFile: String
@Option(help: "Project directory. It will be added to every relative path (path that does not start with `/`",
transform: {
if $0.last == "/" {

View File

@ -5,10 +5,11 @@
// Created by Thibaut Schmitt on 18/11/2022.
//
import ToolCore
import Foundation
import ToolCore
enum ArchitectureGenerator {
struct ArchitectureGenerator {
static func writeArchitecture(_ architecture: ConfigurationArchitecture, projectDirectory: String) {
// Create extension content
var architectureContent = [
@ -16,21 +17,21 @@ struct ArchitectureGenerator {
architecture.getClass()
]
.joined(separator: "\n\n")
architectureContent += "\n"
let filename = "\(architecture.classname).swift"
guard let filePath = architecture.path?.prependIfRelativePath(projectDirectory) else {
let error = GenerateError.writeFile(filename, "Path of file is not defined.")
print(error.description)
Generate.exit(withError: error)
}
// Write content
let architectureFilePathURL = URL(fileURLWithPath: "\(filePath)/\(filename)")
do {
try architectureContent.write(to: architectureFilePathURL, atomically: false, encoding: .utf8)
} catch let error {
} catch {
let error = GenerateError.writeFile(filename, error.localizedDescription)
print(error.description)
Generate.exit(withError: error)

View File

@ -8,6 +8,7 @@
import Foundation
struct ConfigurationFile: Codable, CustomDebugStringConvertible {
var architecture: ConfigurationArchitecture?
var analytics: [AnalyticsConfiguration]
var colors: [ColorsConfiguration]
@ -15,12 +16,12 @@ struct ConfigurationFile: Codable, CustomDebugStringConvertible {
var images: [ImagesConfiguration]
var strings: [StringsConfiguration]
var tags: [TagsConfiguration]
var runnableConfigurations: [Runnable] {
let runnables: [[Runnable]] = [analytics, colors, fonts, images, strings, tags]
return Array(runnables.joined())
}
var debugDescription: String {
"""
\(analytics)
@ -44,20 +45,21 @@ struct ConfigurationFile: Codable, CustomDebugStringConvertible {
}
struct ConfigurationArchitecture: Codable {
let property: String
let classname: String
let path: String?
let children: [ConfigurationArchitecture]?
let children: [Self]?
func getProperty(isStatic: Bool) -> String {
" \(isStatic ? "static " : "")let \(property) = \(classname)()"
}
func getClass(generateStaticProperty: Bool = true) -> String {
guard children?.isEmpty == false else {
return "final class \(classname): Sendable {}"
}
let classDefinition = [
"class \(classname) {",
children?.map { $0.getProperty(isStatic: generateStaticProperty) }.joined(separator: "\n"),
@ -65,12 +67,12 @@ struct ConfigurationArchitecture: Codable {
]
.compactMap { $0 }
.joined(separator: "\n")
return [classDefinition, "", getSubclass()]
.compactMap { $0 }
.joined(separator: "\n")
}
func getSubclass() -> String? {
guard let children else { return nil }
return children.compactMap { arch in
@ -81,26 +83,29 @@ struct ConfigurationArchitecture: Codable {
}
struct AnalyticsConfiguration: Codable, CustomDebugStringConvertible {
let inputFile: String
let target: String
let extensionOutputPath: String
let extensionName: String?
let extensionSuffix: String?
private let staticMembers: Bool?
var staticMembersOptions: Bool {
if let staticMembers = staticMembers {
if let staticMembers {
return staticMembers
}
return false
}
internal init(inputFile: String,
target: String,
extensionOutputPath: String,
extensionName: String?,
extensionSuffix: String?,
staticMembers: Bool?) {
internal init(
inputFile: String,
target: String,
extensionOutputPath: String,
extensionName: String?,
extensionSuffix: String?,
staticMembers: Bool?
) {
self.inputFile = inputFile
self.target = target
self.extensionOutputPath = extensionOutputPath
@ -108,7 +113,7 @@ struct AnalyticsConfiguration: Codable, CustomDebugStringConvertible {
self.extensionSuffix = extensionSuffix
self.staticMembers = staticMembers
}
var debugDescription: String {
"""
Analytics configuration:
@ -122,6 +127,7 @@ struct AnalyticsConfiguration: Codable, CustomDebugStringConvertible {
}
struct ColorsConfiguration: Codable, CustomDebugStringConvertible {
let inputFile: String
let style: String
let xcassetsPath: String
@ -130,22 +136,24 @@ struct ColorsConfiguration: Codable, CustomDebugStringConvertible {
let extensionNameUIKit: String?
let extensionSuffix: String?
private let staticMembers: Bool?
var staticMembersOptions: Bool {
if let staticMembers = staticMembers {
if let staticMembers {
return staticMembers
}
return false
}
internal init(inputFile: String,
style: String,
xcassetsPath: String,
extensionOutputPath: String,
extensionName: String?,
extensionNameUIKit: String?,
extensionSuffix: String?,
staticMembers: Bool?) {
internal init(
inputFile: String,
style: String,
xcassetsPath: String,
extensionOutputPath: String,
extensionName: String?,
extensionNameUIKit: String?,
extensionSuffix: String?,
staticMembers: Bool?
) {
self.inputFile = inputFile
self.style = style
self.xcassetsPath = xcassetsPath
@ -155,7 +163,7 @@ struct ColorsConfiguration: Codable, CustomDebugStringConvertible {
self.extensionSuffix = extensionSuffix
self.staticMembers = staticMembers
}
var debugDescription: String {
"""
Colors configuration:
@ -171,6 +179,7 @@ struct ColorsConfiguration: Codable, CustomDebugStringConvertible {
}
struct FontsConfiguration: Codable, CustomDebugStringConvertible {
let inputFile: String
let extensionOutputPath: String
let extensionName: String?
@ -178,21 +187,23 @@ struct FontsConfiguration: Codable, CustomDebugStringConvertible {
let extensionSuffix: String?
let infoPlistPaths: String?
private let staticMembers: Bool?
var staticMembersOptions: Bool {
if let staticMembers = staticMembers {
if let staticMembers {
return staticMembers
}
return false
}
internal init(inputFile: String,
extensionOutputPath: String,
extensionName: String?,
extensionNameUIKit: String?,
extensionSuffix: String?,
infoPlistPaths: String?,
staticMembers: Bool?) {
internal init(
inputFile: String,
extensionOutputPath: String,
extensionName: String?,
extensionNameUIKit: String?,
extensionSuffix: String?,
infoPlistPaths: String?,
staticMembers: Bool?
) {
self.inputFile = inputFile
self.extensionOutputPath = extensionOutputPath
self.extensionName = extensionName
@ -201,7 +212,7 @@ struct FontsConfiguration: Codable, CustomDebugStringConvertible {
self.infoPlistPaths = infoPlistPaths
self.staticMembers = staticMembers
}
var debugDescription: String {
"""
Fonts configuration:
@ -216,6 +227,7 @@ struct FontsConfiguration: Codable, CustomDebugStringConvertible {
}
struct ImagesConfiguration: Codable, CustomDebugStringConvertible {
let inputFile: String
let xcassetsPath: String
let extensionOutputPath: String
@ -223,21 +235,23 @@ struct ImagesConfiguration: Codable, CustomDebugStringConvertible {
let extensionNameUIKit: String?
let extensionSuffix: String?
private let staticMembers: Bool?
var staticMembersOptions: Bool {
if let staticMembers = staticMembers {
if let staticMembers {
return staticMembers
}
return false
}
internal init(inputFile: String,
xcassetsPath: String,
extensionOutputPath: String,
extensionName: String?,
extensionNameUIKit: String?,
extensionSuffix: String?,
staticMembers: Bool?) {
internal init(
inputFile: String,
xcassetsPath: String,
extensionOutputPath: String,
extensionName: String?,
extensionNameUIKit: String?,
extensionSuffix: String?,
staticMembers: Bool?
) {
self.inputFile = inputFile
self.xcassetsPath = xcassetsPath
self.extensionOutputPath = extensionOutputPath
@ -246,7 +260,7 @@ struct ImagesConfiguration: Codable, CustomDebugStringConvertible {
self.extensionSuffix = extensionSuffix
self.staticMembers = staticMembers
}
var debugDescription: String {
"""
Images configuration:
@ -261,6 +275,7 @@ struct ImagesConfiguration: Codable, CustomDebugStringConvertible {
}
struct StringsConfiguration: Codable, CustomDebugStringConvertible {
let inputFile: String
let outputPath: String
let langs: String
@ -272,28 +287,30 @@ struct StringsConfiguration: Codable, CustomDebugStringConvertible {
private let xcStrings: Bool?
var staticMembersOptions: Bool {
if let staticMembers = staticMembers {
if let staticMembers {
return staticMembers
}
return false
}
var xcStringsOptions: Bool {
if let xcStrings = xcStrings {
if let xcStrings {
return xcStrings
}
return false
}
internal init(inputFile: String,
outputPath: String,
langs: String,
defaultLang: String,
extensionOutputPath: String,
extensionName: String?,
extensionSuffix: String?,
staticMembers: Bool?,
xcStrings: Bool?) {
internal init(
inputFile: String,
outputPath: String,
langs: String,
defaultLang: String,
extensionOutputPath: String,
extensionName: String?,
extensionSuffix: String?,
staticMembers: Bool?,
xcStrings: Bool?
) {
self.inputFile = inputFile
self.outputPath = outputPath
self.langs = langs
@ -304,7 +321,7 @@ struct StringsConfiguration: Codable, CustomDebugStringConvertible {
self.staticMembers = staticMembers
self.xcStrings = xcStrings
}
var debugDescription: String {
"""
Strings configuration:
@ -320,26 +337,29 @@ struct StringsConfiguration: Codable, CustomDebugStringConvertible {
}
struct TagsConfiguration: Codable, CustomDebugStringConvertible {
let inputFile: String
let lang: String
let extensionOutputPath: String
let extensionName: String?
let extensionSuffix: String?
private let staticMembers: Bool?
var staticMembersOptions: Bool {
if let staticMembers = staticMembers {
if let staticMembers {
return staticMembers
}
return false
}
internal init(inputFile: String,
lang: String,
extensionOutputPath: String,
extensionName: String?,
extensionSuffix: String?,
staticMembers: Bool?) {
internal init(
inputFile: String,
lang: String,
extensionOutputPath: String,
extensionName: String?,
extensionSuffix: String?,
staticMembers: Bool?
) {
self.inputFile = inputFile
self.lang = lang
self.extensionOutputPath = extensionOutputPath
@ -347,7 +367,7 @@ struct TagsConfiguration: Codable, CustomDebugStringConvertible {
self.extensionSuffix = extensionSuffix
self.staticMembers = staticMembers
}
var debugDescription: String {
"""
Tags configuration:

View File

@ -8,14 +8,15 @@
import Foundation
import Yams
class ConfigurationFileParser {
enum ConfigurationFileParser {
static func parse(_ configurationFile: String) -> ConfigurationFile {
guard let data = FileManager().contents(atPath: configurationFile) else {
let error = GenerateError.fileNotExists(configurationFile)
print(error.description)
Generate.exit(withError: error)
}
do {
return try YAMLDecoder().decode(ConfigurationFile.self, from: data)
} catch {

View File

@ -8,13 +8,14 @@
import Foundation
extension AnalyticsConfiguration: Runnable {
func run(projectDirectory: String, force: Bool) {
var args = [String]()
if force {
args += ["-f"]
}
args += [
inputFile.prependIfRelativePath(projectDirectory),
"--target",
@ -24,20 +25,20 @@ extension AnalyticsConfiguration: Runnable {
"--static-members",
"\(staticMembersOptions)"
]
if let extensionName = extensionName {
if let extensionName {
args += [
"--extension-name",
extensionName
]
}
if let extensionSuffix = extensionSuffix {
if let extensionSuffix {
args += [
"--extension-suffix",
extensionSuffix
]
}
Analytics.main(args)
}
}

View File

@ -8,18 +8,19 @@
import Foundation
extension ColorsConfiguration: Runnable {
func run(projectDirectory: String, force: Bool) {
let args = getArguments(projectDirectory: projectDirectory, force: force)
Colors.main(args)
}
func getArguments(projectDirectory: String, force: Bool) -> [String] {
var args = [String]()
if force {
args += ["-f"]
}
args += [
inputFile.prependIfRelativePath(projectDirectory),
"--style",
@ -31,26 +32,26 @@ extension ColorsConfiguration: Runnable {
"--static-members",
"\(staticMembersOptions)"
]
if let extensionName = extensionName {
if let extensionName {
args += [
"--extension-name",
extensionName
]
}
if let extensionNameUIKit = extensionNameUIKit {
if let extensionNameUIKit {
args += [
"--extension-name-ui-kit",
extensionNameUIKit
]
}
if let extensionSuffix = extensionSuffix {
if let extensionSuffix {
args += [
"--extension-suffix",
extensionSuffix
]
}
return args
}
}

View File

@ -8,18 +8,19 @@
import Foundation
extension FontsConfiguration: Runnable {
func run(projectDirectory: String, force: Bool) {
let args = getArguments(projectDirectory: projectDirectory, force: force)
Fonts.main(args)
}
func getArguments(projectDirectory: String, force: Bool) -> [String] {
var args = [String]()
if force {
args += ["-f"]
}
args += [
inputFile.prependIfRelativePath(projectDirectory),
"--extension-output-path",
@ -27,39 +28,39 @@ extension FontsConfiguration: Runnable {
"--static-members",
"\(staticMembersOptions)"
]
if let extensionName = extensionName {
if let extensionName {
args += [
"--extension-name",
extensionName
]
}
if let extensionNameUIKit = extensionNameUIKit {
if let extensionNameUIKit {
args += [
"--extension-name-ui-kit",
extensionNameUIKit
]
}
if let extensionSuffix = extensionSuffix {
if let extensionSuffix {
args += [
"--extension-suffix",
extensionSuffix
]
}
if let infoPlistPaths = infoPlistPaths {
if let infoPlistPaths {
let adjustedPlistPaths = infoPlistPaths
.split(separator: " ")
.map { String($0).prependIfRelativePath(projectDirectory) }
.joined(separator: " ")
args += [
"--info-plist-paths",
adjustedPlistPaths
]
}
return args
}
}

View File

@ -1,6 +1,6 @@
//
// ImagesConfiguration+Runnable.swift
//
//
//
// Created by Thibaut Schmitt on 30/08/2022.
//
@ -8,18 +8,19 @@
import Foundation
extension ImagesConfiguration: Runnable {
func run(projectDirectory: String, force: Bool) {
let args = getArguments(projectDirectory: projectDirectory, force: force)
Images.main(args)
}
func getArguments(projectDirectory: String, force: Bool) -> [String] {
var args = [String]()
if force {
args += ["-f"] // Images has a -f and -F options
}
args += [
inputFile.prependIfRelativePath(projectDirectory),
"--xcassets-path",
@ -29,26 +30,28 @@ extension ImagesConfiguration: Runnable {
"--static-members",
"\(staticMembersOptions)"
]
if let extensionName = extensionName {
if let extensionName {
args += [
"--extension-name",
extensionName
]
}
if let extensionNameUIKit = extensionNameUIKit {
if let extensionNameUIKit {
args += [
"--extension-name-ui-kit",
extensionNameUIKit
]
}
if let extensionSuffix = extensionSuffix {
if let extensionSuffix {
args += [
"--extension-suffix",
extensionSuffix
]
}
return args
}
}

View File

@ -8,5 +8,6 @@
import Foundation
protocol Runnable {
func run(projectDirectory: String, force: Bool)
}

View File

@ -8,9 +8,10 @@
import Foundation
extension StringsConfiguration: Runnable {
func run(projectDirectory: String, force: Bool) {
var args = [String]()
if force {
args += ["-f"]
}
@ -30,21 +31,21 @@ extension StringsConfiguration: Runnable {
"--xc-strings",
"\(xcStringsOptions)"
]
if let extensionName = extensionName {
if let extensionName {
args += [
"--extension-name",
extensionName
]
}
if let extensionSuffix = extensionSuffix {
if let extensionSuffix {
args += [
"--extension-suffix",
extensionSuffix
]
}
Stringium.main(args)
}
}

View File

@ -8,13 +8,14 @@
import Foundation
extension TagsConfiguration: Runnable {
func run(projectDirectory: String, force: Bool) {
var args = [String]()
if force {
args += ["-f"]
}
args += [
inputFile.prependIfRelativePath(projectDirectory),
"--lang",
@ -24,20 +25,20 @@ extension TagsConfiguration: Runnable {
"--static-members",
"\(staticMembersOptions)"
]
if let extensionName = extensionName {
if let extensionName {
args += [
"--extension-name",
extensionName
]
}
if let extensionSuffix = extensionSuffix {
if let extensionSuffix {
args += [
"--extension-suffix",
extensionSuffix
]
}
Tags.main(args)
}
}