// // 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.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 = "UIAppFonts\n\t\n" fontsNames .compactMap { $0 } .forEach { plistData += "\t\t\($0)\n" } plistData += "\t\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()