Refactor + Bugs fixes on Strings + Gestion de la génération des images

This commit is contained in:
2022-02-14 14:02:49 +01:00
parent 11a40305dd
commit 5dd2340a11
76 changed files with 1878 additions and 704 deletions

View File

@ -0,0 +1,26 @@
//
// FontOptions.swift
//
//
// Created by Thibaut Schmitt on 17/01/2022.
//
import Foundation
import ArgumentParser
struct FontOptions: ParsableArguments {
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
var forceGeneration = false
@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: "Extension name. If not specified, it will generate an UIFont extension. Using default extension name will generate static property.")
var extensionName: String = FontTool.defaultExtensionName
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+FontsMyApp.swift")
var extensionSuffix: String = ""
}

View File

@ -0,0 +1,58 @@
//
// FontToolContentGenerator.swift
//
//
// Created by Thibaut Schmitt on 13/12/2021.
//
import Foundation
class FontToolContentGenerator {
static func getExtensionHeader(fontsNames: [String]) -> String {
"""
// Generated from FontToolCore
import UIKit
"""
}
static func getFontNameEnum(fontsNames: [String]) -> String {
var enumDefinition = "\tenum FontName: String {\n"
fontsNames.forEach {
//debugPrint("Name: \($0.removeCharacters(from: "[]+-_"))")
enumDefinition += "\t\tcase \($0.removeCharacters(from: "[]+-_")) = \"\($0)\"\n"
}
enumDefinition += "\t}\n"
return enumDefinition
}
static func getFontMethods(fontsNames: [String], isUIFontExtension: Bool) -> String {
var methods = "\t// MARK: - Getter\n"
fontsNames
.unique()
.forEach {
let fontNameSanitize = $0.removeCharacters(from: "[]+-_")
if isUIFontExtension {
methods += """
\n\tstatic let \(fontNameSanitize): ((_ size: CGFloat) -> UIFont) = { size in
\tUIFont(name: FontName.\(fontNameSanitize).rawValue, size: size)!
\t}\n
"""
} else {
methods += """
\n\tfunc \(fontNameSanitize)(withSize size: CGFloat) -> UIFont {
\tUIFont(name: FontName.\(fontNameSanitize).rawValue, size: size)!
\t}\n
"""
}
}
return methods
}
}

View File

@ -0,0 +1,27 @@
//
// FontToolError.swift
//
//
// Created by Thibaut Schmitt on 13/12/2021.
//
import Foundation
enum FontToolError: Error {
case fcScan(String, Int32, String?)
case inputFolderNotFound(String)
case fileNotExists(String)
var localizedDescription: String {
switch self {
case .fcScan(let path, let code, let output):
return "error:[FontTool] Error while getting fontName (fc-scan --format %{postscriptname} \(path). fc-scan exit with \(code) and output is: \(output ?? "no output")"
case .inputFolderNotFound(let inputFolder):
return " error:[FontTool] Input folder not found: \(inputFolder)"
case .fileNotExists(let filename):
return " error:[FontTool] File \(filename) does not exists"
}
}
}

View File

@ -0,0 +1,53 @@
//
// FontToolHelper.swift
//
//
// Created by Thibaut Schmitt on 13/12/2021.
//
import Foundation
import CLIToolCore
class FontToolHelper {
static func getFontsFilenames(fromInputFolder inputFolder: String) -> [String] {
// Get a enumerator for all files
let fileManager = FileManager()
guard fileManager.fileExists(atPath: inputFolder) else {
let error = FontToolError.inputFolderNotFound(inputFolder)
print(error.localizedDescription)
FontTool.exit(withError: error)
}
let enumerator: FileManager.DirectoryEnumerator = fileManager.enumerator(atPath: inputFolder)!
// Filters font files
let fontsFileNames: [String] = (enumerator.allObjects as! [String])
.filter {
if $0.hasSuffix(".ttf") || $0.hasSuffix(".otf") {
return true
}
return false
}
return fontsFileNames
}
static func getFontsNames(fontsFileNames: [String]) -> [String] {
// Get font name (font name and font file name can be different)
fontsFileNames.compactMap { getFontName(atPath: $0) }
}
private static func getFontName(atPath path: String) -> String {
//print("fc-scan --format %{postscriptname} \(path)")
// Get real font name
let task = Shell.shell("fc-scan", "--format", "%{postscriptname}", path)
guard let fontName = task.output, task.terminationStatus == 0 else {
let error = FontToolError.fcScan(path, task.terminationStatus, task.output)
print(error.localizedDescription)
FontTool.exit(withError: error)
}
return fontName
}
}

117
Sources/FontTool/main.swift Normal file
View File

@ -0,0 +1,117 @@
//
// FontTool.swift
//
//
// Created by Thibaut Schmitt on 13/12/2021.
//
import Foundation
import CLIToolCore
import ArgumentParser
struct FontTool: ParsableCommand {
static var configuration = CommandConfiguration(abstract: "Generate fonts plist info and extension to access fonts easily.")
static let defaultExtensionName = "UIFont"
@OptionGroup var options: FontOptions
var extensionFileName: String { "\(options.extensionName)options.+Font\(options.extensionSuffix).swift" }
var extensionFilePath: String { "\(options.extensionOutputPath)/\(extensionFileName)" }
public func run() throws {
print("[FontTool] Starting fonts generation")
// Check requirements
let fileManager = FileManager()
guard fileManager.fileExists(atPath: options.inputFile) else {
let error = FontToolError.fileNotExists(options.inputFile)
print(error.localizedDescription)
FontTool.exit(withError: error)
}
// Check if needed to regenerate
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration, inputFilePath: options.inputFile, extensionFilePath: extensionFilePath) else {
print("[FontTool] Fonts are already up to date :) ")
return
}
print("[FontTool] Will generate fonts")
// Get fonts to generate
let fontsToGenerate = getFontsToGenerate()
let inputFolder = URL(fileURLWithPath: options.inputFile).deletingLastPathComponent().relativePath
let fontsFilenames = FontToolHelper
.getFontsFilenames(fromInputFolder: inputFolder)
.filter { fontNameWithPath in
let fontName = URL(fileURLWithPath: fontNameWithPath)
.deletingPathExtension()
.lastPathComponent
if fontsToGenerate.contains(fontName) {
return true
}
return false
}
let fontsFilesnamesWithPath = fontsFilenames.map { "\(inputFolder)/\($0)" }
let fontsNames = FontToolHelper.getFontsNames(fontsFileNames: fontsFilesnamesWithPath)
// Adding fontsFilenames to header (ex: path/to/font.ttf) to make check of regeneration faster
let extensionHeader = FontToolContentGenerator.getExtensionHeader(fontsNames: fontsFilenames)
let extensionDefinitionOpening = "extension \(options.extensionName) {\n"
let extensionFontsNamesEnum = FontToolContentGenerator.getFontNameEnum(fontsNames: fontsNames)
let extensionFontsMethods = FontToolContentGenerator.getFontMethods(fontsNames: fontsNames, isUIFontExtension: isUIFontExtension())
let extensionDefinitionClosing = "}"
generateExtensionFile(extensionHeader,
extensionDefinitionOpening,
extensionFontsNamesEnum,
extensionFontsMethods,
extensionDefinitionClosing)
print("Info.plist information:")
print("\(generatePlistUIAppFonts(fontsNames: fontsNames))")
print("[FontTool] Fonts generated")
}
private func generateExtensionFile(_ args: String...) {
// Create file if not exists
let fileManager = FileManager()
if fileManager.fileExists(atPath: extensionFilePath) == false {
Shell.shell("touch", "\(extensionFilePath)")
}
// Create extension content
let extensionContent = args.joined(separator: "\n")
// Write content
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
try! extensionContent.write(to: extensionFilePathURL, atomically: true, encoding: .utf8)
}
private func generatePlistUIAppFonts(fontsNames: [String]) -> String {
var plistData = "<key>UIAppFonts</key>\n\t<array>\n"
fontsNames
.compactMap { $0 }
.forEach {
plistData += "\t\t<string>\($0)</string>\n"
}
plistData += "\t</array>\n*/"
return plistData
}
// MARK: - Helpers
private func getFontsToGenerate() -> [String] {
let inputFileContent = try! String(contentsOfFile: options.inputFile, encoding: .utf8)
return inputFileContent.components(separatedBy: CharacterSet.newlines)
}
private func isUIFontExtension() -> Bool {
options.extensionName == Self.defaultExtensionName
}
}
FontTool.main()