Squashed commit of the following:
Some checks failed
gitea-openium/resgen.swift/pipeline/head There was a failure building this commit

commit aa59ef28ea56315eb421ba044ddaf0c4066bfff8
Author: Thibaut Schmitt <t.schmitt@openium.fr>
Date:   Mon Nov 7 10:26:28 2022 +0100

    Add trailing carrier at the end of generated extension files

commit e985950aa1e39d81d4938e15f8724c0f7723b003
Author: Thibaut Schmitt <t.schmitt@openium.fr>
Date:   Fri Nov 4 16:37:34 2022 +0100

    Replace installation script by script that install completion file
    Setup a Makefile to install resgen

commit d574384c151259610a4c2f837b14068bb7716e44
Author: Thibaut Schmitt <t.schmitt@openium.fr>
Date:   Fri Nov 4 14:33:39 2022 +0100

    Refactor
    Improve testability
    Add tests on SwiftUI generated code
    Add tests on  command

commit d9e76632c3037da0ed9e1dd37056685416579da9
Author: Thibaut Schmitt <t.schmitt@openium.fr>
Date:   Thu Nov 3 15:43:47 2022 +0100

    Fixing bad merge on FontOptions

commit 76b5ebfcd1cde7a7d4c83f516a4fc937841e7715
Author: Thibaut Schmitt <t.schmitt@openium.fr>
Date:   Thu Nov 3 15:37:28 2022 +0100

    Squashed commit of the following:

    commit 085f1ffc33
    Author: Thibaut Schmitt <t.schmitt@openium.fr>
    Date:   Thu Nov 3 15:00:27 2022 +0100

        Refactor SwiftUI extension generation and generation SwiftUI extension for images

    commit 4f7d7e18b1
    Author: Thibaut Schmitt <t.schmitt@openium.fr>
    Date:   Mon Oct 31 16:21:32 2022 +0100

        Génération de composant SwiftUI: Color et Image

    commit 0797667b25
    Author: Thibaut Schmitt <t.schmitt@openium.fr>
    Date:   Mon Oct 31 16:21:12 2022 +0100

        Génération de composant SwiftUI: Color et Image

commit 417a2630925841dd486ae1d684d28ab7dca240e0
Author: Thibaut Schmitt <t.schmitt@openium.fr>
Date:   Wed Oct 19 17:13:03 2022 +0200

    Update Info.plist UIAppFonts key when generating fonts (if plist path if defined)
This commit is contained in:
2022-11-07 10:32:17 +01:00
parent 6203700b0c
commit 41733d2680
75 changed files with 1487 additions and 933 deletions

View File

@ -21,16 +21,25 @@ struct FontsOptions: ParsableArguments {
@Option(help: "Tell if it will generate static properties or methods")
var staticMembers: Bool = false
@Option(help: "Extension name. If not specified, it will generate an UIFont extension. Using default extension name will generate static property.")
@Option(help: "Extension name. If not specified, it will generate an UIFont extension.")
var extensionName: String = Fonts.defaultExtensionName
@Option(help: "Extension name. If not specified, it will generate an Font extension.")
var extensionNameSwiftUI: String = Fonts.defaultExtensionNameSUI
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+FontsMyApp.swift")
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 = ""
}
// MARK: - Computed var
extension FontsOptions {
// MARK: - UIKit
var extensionFileName: String {
if extensionSuffix.isEmpty == false {
return "\(extensionName)+\(extensionSuffix).swift"
@ -41,4 +50,25 @@ extension FontsOptions {
var extensionFilePath: String {
"\(extensionOutputPath)/\(extensionFileName)"
}
// MARK: - SwiftUI
var extensionFileNameSwiftUI: String {
if extensionSuffix.isEmpty == false {
return "\(extensionNameSwiftUI)+\(extensionSuffix).swift"
}
return "\(extensionNameSwiftUI).swift"
}
var extensionFilePathSwiftUI: String {
"\(extensionOutputPath)/\(extensionFileNameSwiftUI)"
}
// MARK: -
var infoPlistPaths: [String] {
infoPlistPathsRaw
.split(separator: " ")
.map { String($0) }
}
}

View File

@ -22,6 +22,7 @@ struct Fonts: ParsableCommand {
static let toolName = "Fonts"
static let defaultExtensionName = "UIFont"
static let defaultExtensionNameSUI = "Font"
// MARK: - Command Options
@ -50,10 +51,17 @@ struct Fonts: ParsableCommand {
FontExtensionGenerator.writeExtensionFile(fontsNames: fontsNames,
staticVar: options.staticMembers,
extensionName: options.extensionName,
extensionFilePath: options.extensionFilePath)
extensionFilePath: options.extensionFilePath,
isSwiftUI: false)
print("Info.plist information:")
print("\(FontPlistGenerator.generatePlistUIAppsFontContent(for: fontsNames))")
FontExtensionGenerator.writeExtensionFile(fontsNames: fontsNames,
staticVar: options.staticMembers,
extensionName: options.extensionNameSwiftUI,
extensionFilePath: options.extensionFilePathSwiftUI,
isSwiftUI: true)
print("Info.plist has been updated with:")
print("\(FontPlistGenerator.generatePlistUIAppsFontContent(for: fontsNames, infoPlistPaths: options.infoPlistPaths))")
print("[\(Self.toolName)] Fonts generated")
}
@ -70,6 +78,13 @@ struct Fonts: ParsableCommand {
Fonts.exit(withError: error)
}
// Extension for UIKit and SwiftUI should have different name
guard options.extensionName != options.extensionNameSwiftUI else {
let error = FontsToolError.extensionNamesCollision(options.extensionName)
print(error.localizedDescription)
Fonts.exit(withError: error)
}
// Check if needed to regenerate
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration,
inputFilePath: options.inputFile,

View File

@ -8,6 +8,7 @@
import Foundation
enum FontsToolError: Error {
case extensionNamesCollision(String)
case fcScan(String, Int32, String?)
case inputFolderNotFound(String)
case fileNotExists(String)
@ -15,6 +16,9 @@ enum FontsToolError: Error {
var localizedDescription: 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)"
case .fcScan(let path, let code, let output):
return "error:[\(Fonts.toolName)] Error while getting fontName (fc-scan --format %{postscriptname} \(path). fc-scan exit with \(code) and output is: \(output ?? "no output")"

View File

@ -6,12 +6,34 @@
//
import Foundation
import ToolCore
class FontPlistGenerator {
static func generatePlistUIAppsFontContent(for fonts: [FontName]) -> String {
var plistData = "<key>UIAppFonts</key>\n\t<array>\n"
fonts
static func generatePlistUIAppsFontContent(for fonts: [FontName], infoPlistPaths: [String]) -> String {
let fontsToAddToPlist = fonts
.compactMap { $0 }
// Update each plist
infoPlistPaths.forEach { infoPlist in
// Remove UIAppFonts value
Shell.shell(launchPath: "/usr/libexec/PlistBuddy",
["-c", "delete :UIAppFonts", infoPlist])
// Add UIAppFonts empty array
debugPrint("Will PlistBuddy -c add :UIAppFonts array \(infoPlist)")
Shell.shell(launchPath: "/usr/libexec/PlistBuddy",
["-c", "add :UIAppFonts array", infoPlist])
// Fill array with fonts
fontsToAddToPlist
.forEach {
Shell.shell(launchPath: "/usr/libexec/PlistBuddy",
["-c", "add :UIAppFonts: string \($0)", infoPlist])
}
}
var plistData = "<key>UIAppFonts</key>\n\t<array>\n"
fontsToAddToPlist
.forEach {
plistData += "\t\t<string>\($0)</string>\n"
}

View File

@ -9,12 +9,28 @@ import Foundation
import ToolCore
class FontExtensionGenerator {
private static func getFontNameEnum(fontsNames: [String]) -> String {
var enumDefinition = " enum FontName: String {\n"
fontsNames.forEach {
enumDefinition += " case \($0.fontNameSanitize) = \"\($0)\"\n"
}
enumDefinition += " }\n"
return enumDefinition
}
static func writeExtensionFile(fontsNames: [String], staticVar: Bool, extensionName: String, extensionFilePath: String) {
static func writeExtensionFile(fontsNames: [String],
staticVar: Bool,
extensionName: String,
extensionFilePath: String,
isSwiftUI: Bool) {
// Create extension content
let extensionContent = Self.getExtensionContent(fontsNames: fontsNames,
staticVar: staticVar,
extensionName: extensionName)
extensionName: extensionName,
isSwiftUI: isSwiftUI)
// Write content
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
@ -27,48 +43,36 @@ class FontExtensionGenerator {
}
}
static func getExtensionContent(fontsNames: [String], staticVar: Bool, extensionName: String) -> String {
static func getExtensionContent(fontsNames: [String],
staticVar: Bool,
extensionName: String,
isSwiftUI: Bool) -> String {
[
Self.getHeader(extensionClassname: extensionName),
Self.getHeader(extensionClassname: extensionName, isSwiftUI: isSwiftUI),
Self.getFontNameEnum(fontsNames: fontsNames),
Self.getFontMethods(fontsNames: fontsNames, staticVar: staticVar),
Self.getFontMethods(fontsNames: fontsNames, staticVar: staticVar, isSwiftUI: isSwiftUI),
Self.getFooter()
]
.joined(separator: "\n")
}
private static func getHeader(extensionClassname: String) -> String {
private static func getHeader(extensionClassname: String, isSwiftUI: Bool) -> String {
"""
// Generated by ResgenSwift.\(Fonts.toolName) \(ResgenSwiftVersion)
import UIKit
import \(isSwiftUI ? "SwiftUI" : "UIKit")
extension \(extensionClassname) {\n
"""
}
private static func getFontNameEnum(fontsNames: [String]) -> String {
var enumDefinition = " enum FontName: String {\n"
fontsNames.forEach {
enumDefinition += " case \($0.fontNameSanitize) = \"\($0)\"\n"
}
enumDefinition += " }\n"
return enumDefinition
}
private static func getFontMethods(fontsNames: [FontName], staticVar: Bool) -> String {
private static func getFontMethods(fontsNames: [FontName], staticVar: Bool, isSwiftUI: Bool) -> String {
let pragma = " // MARK: - Getter"
var propertiesOrMethods: [String] = fontsNames
.unique()
.map {
if staticVar {
return $0.staticProperty
} else {
return $0.method
}
$0.getProperty(isStatic: staticVar, isSwiftUI: isSwiftUI)
}
propertiesOrMethods.insert(pragma, at: 0)
@ -78,6 +82,7 @@ class FontExtensionGenerator {
private static func getFooter() -> String {
"""
}
"""
}
}

View File

@ -14,19 +14,33 @@ extension FontName {
self.removeCharacters(from: "[]+-_")
}
var method: String {
"""
func getProperty(isStatic: Bool, isSwiftUI: Bool) -> String {
if isSwiftUI {
if isStatic {
return """
static let \(fontNameSanitize): ((_ size: CGFloat) -> Font) = { size in
Font.custom(FontName.\(fontNameSanitize).rawValue, size: size)
}
"""
}
return """
func \(fontNameSanitize)(withSize size: CGFloat) -> Font {
Font.custom(FontName.\(fontNameSanitize).rawValue, size: size)
}
"""
}
// UIKit
if isStatic {
return """
static let \(fontNameSanitize): ((_ size: CGFloat) -> UIFont) = { size in
UIFont(name: FontName.\(fontNameSanitize).rawValue, size: size)!
}
"""
}
return """
func \(fontNameSanitize)(withSize size: CGFloat) -> UIFont {
UIFont(name: FontName.\(fontNameSanitize).rawValue, size: size)!
}
"""
}
var staticProperty: String {
"""
static let \(fontNameSanitize): ((_ size: CGFloat) -> UIFont) = { size in
UIFont(name: FontName.\(fontNameSanitize).rawValue, size: size)!
}
"""
}
}