From aaeca93cbcfb50459abb06b6c2006bd87f121aad Mon Sep 17 00:00:00 2001 From: Thibaut Schmitt Date: Thu, 17 Jul 2025 10:43:54 +0200 Subject: [PATCH] Make Font UIKit generation optional --- README.md | 4 +-- .../ResgenSwift/Colors/ColorsToolError.swift | 2 +- .../Colors/ColorsToolOptions.swift | 4 +-- Sources/ResgenSwift/Fonts/FontOptions.swift | 26 ++++++++------ Sources/ResgenSwift/Fonts/Fonts.swift | 28 +++++++++------ .../ResgenSwift/Fonts/FontsToolError.swift | 4 +++ .../Generate/Model/ConfigurationFile.swift | 6 ++-- .../FontsConfiguration+Runnable.swift | 34 ++++++++----------- Sources/ResgenSwift/Images/ImagesError.swift | 6 ++-- .../ResgenSwift/Images/ImagesOptions.swift | 4 +-- 10 files changed, 64 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 8951a82..e3f9578 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ ResgenSwift is a package, fully written in Swift, to help you automatize ressource update and generation. -> 🧐 For all commands, see samples files in `SampleFiles` +> 🧐 For all commands, see samples files in `SampleFiles` and use `resgen-swift help` and `resgen-swift help ` for detailed help. ## Fonts Font generator generates an extension of `UIFont` and `Font` (or custom classes). It also prints content of `UIAppFonts` from your project `.plist`. If project `.plist` is specified, it will update `UIAppFonts` content of all `.plist`. -iOS required to use the **real name** of the font, this name can be different from its filename. To get the **real name**, it uses `fc-scan`. So, be sure that the `$PATH` contains path of `fc-scan`. +iOS required to use the **real name** of the font, this name can be different from its filename. To get the **real name**, it uses `fc-scan`. So, be sure that your `$PATH` variable contains path of `fc-scan`. **Example** diff --git a/Sources/ResgenSwift/Colors/ColorsToolError.swift b/Sources/ResgenSwift/Colors/ColorsToolError.swift index 207d3f3..a0e2290 100644 --- a/Sources/ResgenSwift/Colors/ColorsToolError.swift +++ b/Sources/ResgenSwift/Colors/ColorsToolError.swift @@ -22,7 +22,7 @@ enum ColorsToolError: Error { var description: String { switch self { case .extensionNamesCollision(let extensionName): - return "error: [\(Fonts.toolName)] Error on extension names, extension name and SwiftUI extension name should be different (\(extensionName) is used on both)" + return "error: [\(Colors.toolName)] Error on extension names, extension name and SwiftUI extension name should be different (\(extensionName) is used on both)" case .badFormat(let info): return "error: [\(Colors.toolName)] Bad line format: \(info). Accepted format are: colorName=\"#RGB/#ARGB\"; colorName \"#RGB/#ARGB\"; colorName \"#RGB/#ARGB\" \"#RGB/#ARGB\"" diff --git a/Sources/ResgenSwift/Colors/ColorsToolOptions.swift b/Sources/ResgenSwift/Colors/ColorsToolOptions.swift index ceb3b94..4297e8e 100644 --- a/Sources/ResgenSwift/Colors/ColorsToolOptions.swift +++ b/Sources/ResgenSwift/Colors/ColorsToolOptions.swift @@ -30,10 +30,10 @@ struct ColorsToolOptions: ParsableArguments { @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) var extensionOutputPath: String? - @Option(help: "Extension name. If not specified, no extension will be generated.") + @Option(help: "SwiftUI extension name. If not specified, no extension will be generated.") var extensionName: String? - @Option(help: "SwiftUI Extension name. If not specified, no extension will be generated.") + @Option(help: "UIKit extension name. If not specified, no extension will be generated.") var extensionNameUIKit: String? @Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+ColorsMyApp.swift") diff --git a/Sources/ResgenSwift/Fonts/FontOptions.swift b/Sources/ResgenSwift/Fonts/FontOptions.swift index 42a3218..ac14250 100644 --- a/Sources/ResgenSwift/Fonts/FontOptions.swift +++ b/Sources/ResgenSwift/Fonts/FontOptions.swift @@ -18,20 +18,20 @@ struct FontsOptions: ParsableArguments { @Argument(help: "Input files where fonts ared defined.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) var inputFile: String - @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) - var extensionOutputPath: String - @Option(help: "Tell if it will generate static properties or methods") var staticMembers: Bool = false + @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 Font extension.") var extensionName: String = Fonts.defaultExtensionName - @Option(help: "Extension name. If not specified, it will generate an UIFont extension.") - var extensionNameUIKit: String = Fonts.defaultExtensionNameUIKit + @Option(help: "Extension name. If not specified, no extension will be generated.") + var extensionNameUIKit: String? @Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+FontsMyApp.swift") - var extensionSuffix: String = "" + var extensionSuffix: String? @Option(name: .customLong("info-plist-paths"), help: "Info.plist paths (array). Will be used to update UIAppFonts content") fileprivate var infoPlistPathsRaw: String = "" @@ -44,7 +44,7 @@ extension FontsOptions { // MARK: - SwiftUI var extensionFileName: String { - if extensionSuffix.isEmpty == false { + if let extensionSuffix { return "\(extensionName)+\(extensionSuffix).swift" } return "\(extensionName).swift" @@ -56,15 +56,19 @@ extension FontsOptions { // MARK: - UIKit - var extensionFileNameUIKit: String { - if extensionSuffix.isEmpty == false { + var extensionFileNameUIKit: String? { + guard let extensionNameUIKit else { return nil } + + if let extensionSuffix { return "\(extensionNameUIKit)+\(extensionSuffix).swift" } return "\(extensionNameUIKit).swift" } - var extensionFilePathUIKit: String { - "\(extensionOutputPath)/\(extensionFileNameUIKit)" + var extensionFilePathUIKit: String? { + guard let extensionFileNameUIKit else { return nil } + + return "\(extensionOutputPath)/\(extensionFileNameUIKit)" } // MARK: - diff --git a/Sources/ResgenSwift/Fonts/Fonts.swift b/Sources/ResgenSwift/Fonts/Fonts.swift index 9e4bbca..82d930d 100644 --- a/Sources/ResgenSwift/Fonts/Fonts.swift +++ b/Sources/ResgenSwift/Fonts/Fonts.swift @@ -22,7 +22,6 @@ struct Fonts: ParsableCommand { static let toolName = "Fonts" static let defaultExtensionName = "Font" - static let defaultExtensionNameUIKit = "UIFont" // MARK: - Command Options @@ -61,16 +60,25 @@ struct Fonts: ParsableCommand { isSwiftUI: true ) - FontExtensionGenerator.writeExtensionFile( - fontsNames: fontsNames, - staticVar: options.staticMembers, - extensionName: options.extensionNameUIKit, - extensionFilePath: options.extensionFilePathUIKit, - isSwiftUI: false - ) + if let extensionNameUIKit = options.extensionNameUIKit, + let extensionFilePathUIKit = options.extensionFilePathUIKit { + FontExtensionGenerator.writeExtensionFile( + fontsNames: fontsNames, + staticVar: options.staticMembers, + extensionName: extensionNameUIKit, + extensionFilePath: extensionFilePathUIKit, + isSwiftUI: false + ) + } - print("Info.plist has been updated with:") - print("\(FontPlistGenerator.generatePlistUIAppsFontContent(for: fontsNames, infoPlistPaths: options.infoPlistPaths))") + if options.infoPlistPaths.isEmpty == false { + let plistUpdateFontsData = FontPlistGenerator.generatePlistUIAppsFontContent( + for: fontsNames, + infoPlistPaths: options.infoPlistPaths + ) + print("Info.plist has been updated with:") + print(plistUpdateFontsData) + } print("[\(Self.toolName)] Fonts generated") } diff --git a/Sources/ResgenSwift/Fonts/FontsToolError.swift b/Sources/ResgenSwift/Fonts/FontsToolError.swift index 5e851e1..237e833 100644 --- a/Sources/ResgenSwift/Fonts/FontsToolError.swift +++ b/Sources/ResgenSwift/Fonts/FontsToolError.swift @@ -14,6 +14,7 @@ enum FontsToolError: Error { case inputFolderNotFound(String) case fileNotExists(String) case writeExtension(String, String) + case missingExtensionPath var description: String { switch self { @@ -31,6 +32,9 @@ enum FontsToolError: Error { case let .writeExtension(filename, info): return "error: [\(Fonts.toolName)] An error occured while writing extension in \(filename): \(info)" + + case .missingExtensionPath: + return "error: [\(Fonts.toolName)] Extension need to be generated but no `extensionOutputPath` is provided" } } } diff --git a/Sources/ResgenSwift/Generate/Model/ConfigurationFile.swift b/Sources/ResgenSwift/Generate/Model/ConfigurationFile.swift index 1fe0a31..ff3b680 100644 --- a/Sources/ResgenSwift/Generate/Model/ConfigurationFile.swift +++ b/Sources/ResgenSwift/Generate/Model/ConfigurationFile.swift @@ -181,7 +181,7 @@ struct ColorsConfiguration: Codable, CustomDebugStringConvertible { struct FontsConfiguration: Codable, CustomDebugStringConvertible { let inputFile: String - let extensionOutputPath: String + let extensionOutputPath: String? let extensionName: String? let extensionNameUIKit: String? let extensionSuffix: String? @@ -197,7 +197,7 @@ struct FontsConfiguration: Codable, CustomDebugStringConvertible { internal init( inputFile: String, - extensionOutputPath: String, + extensionOutputPath: String?, extensionName: String?, extensionNameUIKit: String?, extensionSuffix: String?, @@ -217,7 +217,7 @@ struct FontsConfiguration: Codable, CustomDebugStringConvertible { """ Fonts configuration: - Input file: \(inputFile) - - Extension output path: \(extensionOutputPath) + - Extension output path: \(extensionOutputPath ?? "-") - Extension name: \(extensionName ?? "-") - Extension name UIKit: \(extensionNameUIKit ?? "-") - Extension suffix: \(extensionSuffix ?? "-") diff --git a/Sources/ResgenSwift/Generate/Runnable/FontsConfiguration+Runnable.swift b/Sources/ResgenSwift/Generate/Runnable/FontsConfiguration+Runnable.swift index 6a9db9f..d603552 100644 --- a/Sources/ResgenSwift/Generate/Runnable/FontsConfiguration+Runnable.swift +++ b/Sources/ResgenSwift/Generate/Runnable/FontsConfiguration+Runnable.swift @@ -23,32 +23,26 @@ extension FontsConfiguration: Runnable { args += [ inputFile.prependIfRelativePath(projectDirectory), - "--extension-output-path", - extensionOutputPath.prependIfRelativePath(projectDirectory), "--static-members", "\(staticMembersOptions)" ] - if let extensionName { - args += [ - "--extension-name", - extensionName - ] - } - if let extensionNameUIKit { - args += [ - "--extension-name-ui-kit", - extensionNameUIKit - ] - } - - if let extensionSuffix { - args += [ - "--extension-suffix", - extensionSuffix - ] + // Add optional parameters + [ + ("--extension-output-path", extensionOutputPath?.prependIfRelativePath(projectDirectory)), + ("--extension-name", extensionName), + ("--extension-name-ui-kit", extensionNameUIKit), + ("--extension-suffix", extensionSuffix) + ].forEach { argumentName, argumentValue in + if let argumentValue { + args += [ + argumentName, + argumentValue + ] + } } + // Add infoPlist paths if let infoPlistPaths { let adjustedPlistPaths = infoPlistPaths .split(separator: " ") diff --git a/Sources/ResgenSwift/Images/ImagesError.swift b/Sources/ResgenSwift/Images/ImagesError.swift index efe42de..a24ccce 100644 --- a/Sources/ResgenSwift/Images/ImagesError.swift +++ b/Sources/ResgenSwift/Images/ImagesError.swift @@ -24,7 +24,7 @@ enum ImagesError: Error { var description: String { switch self { case .extensionNamesCollision(let extensionName): - return "error: [\(Fonts.toolName)] Error on extension names, extension name and SwiftUI extension name should be different (\(extensionName) is used on both)" + return "error: [\(Images.toolName)] Error on extension names, extension name and SwiftUI extension name should be different (\(extensionName) is used on both)" case .inputFolderNotFound(let inputFolder): return "error: [\(Images.toolName)] Input folder not found: \(inputFolder)" @@ -48,10 +48,10 @@ enum ImagesError: Error { return "error: [\(Images.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)" case .createAssetFolder(let folder): - return "error: [\(Colors.toolName)] An error occured while creating folder `\(folder)`" + return "error: [\(Images.toolName)] An error occured while creating folder `\(folder)`" case .missingExtensionPath: - return "error: [\(Colors.toolName)] Extension need to be generated but no `extensionOutputPath` is provided" + return "error: [\(Images.toolName)] Extension need to be generated but no `extensionOutputPath` is provided" case .unknown(let errorDescription): return "error: [\(Images.toolName)] Unknown error: \(errorDescription)" diff --git a/Sources/ResgenSwift/Images/ImagesOptions.swift b/Sources/ResgenSwift/Images/ImagesOptions.swift index 8f8cf09..f544a70 100644 --- a/Sources/ResgenSwift/Images/ImagesOptions.swift +++ b/Sources/ResgenSwift/Images/ImagesOptions.swift @@ -30,10 +30,10 @@ struct ImagesOptions: ParsableArguments { @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) var extensionOutputPath: String? - @Option(help: "Extension name. If not specified, no extension will be generated.") + @Option(help: "SwiftUI extension name. If not specified, no extension will be generated.") var extensionName: String? - @Option(help: "Extension name. If not specified, no extension will be generated.") + @Option(help: "UIKit extension name. If not specified, no extension will be generated.") var extensionNameUIKit: String? @Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+Image{extensionSuffix}.swift")