Make Font UIKit generation optional

This commit is contained in:
2025-07-17 10:43:54 +02:00
parent e22f9ba894
commit aaeca93cbc
10 changed files with 64 additions and 54 deletions

View File

@@ -2,13 +2,13 @@
ResgenSwift is a package, fully written in Swift, to help you automatize ressource update and generation. 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 <subcommand>` for detailed help.
## Fonts ## 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`. 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** **Example**

View File

@@ -22,7 +22,7 @@ enum ColorsToolError: Error {
var description: String { var description: String {
switch self { switch self {
case .extensionNamesCollision(let extensionName): 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): 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\"" return "error: [\(Colors.toolName)] Bad line format: \(info). Accepted format are: colorName=\"#RGB/#ARGB\"; colorName \"#RGB/#ARGB\"; colorName \"#RGB/#ARGB\" \"#RGB/#ARGB\""

View File

@@ -30,10 +30,10 @@ struct ColorsToolOptions: ParsableArguments {
@Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
var extensionOutputPath: String? 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? 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? var extensionNameUIKit: String?
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+ColorsMyApp.swift") @Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+ColorsMyApp.swift")

View File

@@ -18,20 +18,20 @@ struct FontsOptions: ParsableArguments {
@Argument(help: "Input files where fonts ared defined.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) @Argument(help: "Input files where fonts ared defined.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
var inputFile: String 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") @Option(help: "Tell if it will generate static properties or methods")
var staticMembers: Bool = false 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.") @Option(help: "Extension name. If not specified, it will generate an Font extension.")
var extensionName: String = Fonts.defaultExtensionName var extensionName: String = Fonts.defaultExtensionName
@Option(help: "Extension name. If not specified, it will generate an UIFont extension.") @Option(help: "Extension name. If not specified, no extension will be generated.")
var extensionNameUIKit: String = Fonts.defaultExtensionNameUIKit var extensionNameUIKit: String?
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+FontsMyApp.swift") @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") @Option(name: .customLong("info-plist-paths"), help: "Info.plist paths (array). Will be used to update UIAppFonts content")
fileprivate var infoPlistPathsRaw: String = "" fileprivate var infoPlistPathsRaw: String = ""
@@ -44,7 +44,7 @@ extension FontsOptions {
// MARK: - SwiftUI // MARK: - SwiftUI
var extensionFileName: String { var extensionFileName: String {
if extensionSuffix.isEmpty == false { if let extensionSuffix {
return "\(extensionName)+\(extensionSuffix).swift" return "\(extensionName)+\(extensionSuffix).swift"
} }
return "\(extensionName).swift" return "\(extensionName).swift"
@@ -56,15 +56,19 @@ extension FontsOptions {
// MARK: - UIKit // MARK: - UIKit
var extensionFileNameUIKit: String { var extensionFileNameUIKit: String? {
if extensionSuffix.isEmpty == false { guard let extensionNameUIKit else { return nil }
if let extensionSuffix {
return "\(extensionNameUIKit)+\(extensionSuffix).swift" return "\(extensionNameUIKit)+\(extensionSuffix).swift"
} }
return "\(extensionNameUIKit).swift" return "\(extensionNameUIKit).swift"
} }
var extensionFilePathUIKit: String { var extensionFilePathUIKit: String? {
"\(extensionOutputPath)/\(extensionFileNameUIKit)" guard let extensionFileNameUIKit else { return nil }
return "\(extensionOutputPath)/\(extensionFileNameUIKit)"
} }
// MARK: - // MARK: -

View File

@@ -22,7 +22,6 @@ struct Fonts: ParsableCommand {
static let toolName = "Fonts" static let toolName = "Fonts"
static let defaultExtensionName = "Font" static let defaultExtensionName = "Font"
static let defaultExtensionNameUIKit = "UIFont"
// MARK: - Command Options // MARK: - Command Options
@@ -61,16 +60,25 @@ struct Fonts: ParsableCommand {
isSwiftUI: true isSwiftUI: true
) )
if let extensionNameUIKit = options.extensionNameUIKit,
let extensionFilePathUIKit = options.extensionFilePathUIKit {
FontExtensionGenerator.writeExtensionFile( FontExtensionGenerator.writeExtensionFile(
fontsNames: fontsNames, fontsNames: fontsNames,
staticVar: options.staticMembers, staticVar: options.staticMembers,
extensionName: options.extensionNameUIKit, extensionName: extensionNameUIKit,
extensionFilePath: options.extensionFilePathUIKit, extensionFilePath: extensionFilePathUIKit,
isSwiftUI: false isSwiftUI: false
) )
}
if options.infoPlistPaths.isEmpty == false {
let plistUpdateFontsData = FontPlistGenerator.generatePlistUIAppsFontContent(
for: fontsNames,
infoPlistPaths: options.infoPlistPaths
)
print("Info.plist has been updated with:") print("Info.plist has been updated with:")
print("\(FontPlistGenerator.generatePlistUIAppsFontContent(for: fontsNames, infoPlistPaths: options.infoPlistPaths))") print(plistUpdateFontsData)
}
print("[\(Self.toolName)] Fonts generated") print("[\(Self.toolName)] Fonts generated")
} }

View File

@@ -14,6 +14,7 @@ enum FontsToolError: Error {
case inputFolderNotFound(String) case inputFolderNotFound(String)
case fileNotExists(String) case fileNotExists(String)
case writeExtension(String, String) case writeExtension(String, String)
case missingExtensionPath
var description: String { var description: String {
switch self { switch self {
@@ -31,6 +32,9 @@ enum FontsToolError: Error {
case let .writeExtension(filename, info): case let .writeExtension(filename, info):
return "error: [\(Fonts.toolName)] An error occured while writing extension in \(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"
} }
} }
} }

View File

@@ -181,7 +181,7 @@ struct ColorsConfiguration: Codable, CustomDebugStringConvertible {
struct FontsConfiguration: Codable, CustomDebugStringConvertible { struct FontsConfiguration: Codable, CustomDebugStringConvertible {
let inputFile: String let inputFile: String
let extensionOutputPath: String let extensionOutputPath: String?
let extensionName: String? let extensionName: String?
let extensionNameUIKit: String? let extensionNameUIKit: String?
let extensionSuffix: String? let extensionSuffix: String?
@@ -197,7 +197,7 @@ struct FontsConfiguration: Codable, CustomDebugStringConvertible {
internal init( internal init(
inputFile: String, inputFile: String,
extensionOutputPath: String, extensionOutputPath: String?,
extensionName: String?, extensionName: String?,
extensionNameUIKit: String?, extensionNameUIKit: String?,
extensionSuffix: String?, extensionSuffix: String?,
@@ -217,7 +217,7 @@ struct FontsConfiguration: Codable, CustomDebugStringConvertible {
""" """
Fonts configuration: Fonts configuration:
- Input file: \(inputFile) - Input file: \(inputFile)
- Extension output path: \(extensionOutputPath) - Extension output path: \(extensionOutputPath ?? "-")
- Extension name: \(extensionName ?? "-") - Extension name: \(extensionName ?? "-")
- Extension name UIKit: \(extensionNameUIKit ?? "-") - Extension name UIKit: \(extensionNameUIKit ?? "-")
- Extension suffix: \(extensionSuffix ?? "-") - Extension suffix: \(extensionSuffix ?? "-")

View File

@@ -23,32 +23,26 @@ extension FontsConfiguration: Runnable {
args += [ args += [
inputFile.prependIfRelativePath(projectDirectory), inputFile.prependIfRelativePath(projectDirectory),
"--extension-output-path",
extensionOutputPath.prependIfRelativePath(projectDirectory),
"--static-members", "--static-members",
"\(staticMembersOptions)" "\(staticMembersOptions)"
] ]
if let extensionName { // 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 += [ args += [
"--extension-name", argumentName,
extensionName argumentValue
] ]
} }
if let extensionNameUIKit {
args += [
"--extension-name-ui-kit",
extensionNameUIKit
]
}
if let extensionSuffix {
args += [
"--extension-suffix",
extensionSuffix
]
} }
// Add infoPlist paths
if let infoPlistPaths { if let infoPlistPaths {
let adjustedPlistPaths = infoPlistPaths let adjustedPlistPaths = infoPlistPaths
.split(separator: " ") .split(separator: " ")

View File

@@ -24,7 +24,7 @@ enum ImagesError: Error {
var description: String { var description: String {
switch self { switch self {
case .extensionNamesCollision(let extensionName): 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): case .inputFolderNotFound(let inputFolder):
return "error: [\(Images.toolName)] Input folder not found: \(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)" return "error: [\(Images.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)"
case .createAssetFolder(let folder): 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: 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): case .unknown(let errorDescription):
return "error: [\(Images.toolName)] Unknown error: \(errorDescription)" return "error: [\(Images.toolName)] Unknown error: \(errorDescription)"

View File

@@ -30,10 +30,10 @@ struct ImagesOptions: ParsableArguments {
@Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
var extensionOutputPath: String? 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? 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? var extensionNameUIKit: String?
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+Image{extensionSuffix}.swift") @Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+Image{extensionSuffix}.swift")