Add checker class to check if generation of font are required + Split CLIToolCore in multiple file (one by class)
This commit is contained in:
parent
e8545955f6
commit
780efc8817
@ -1,4 +1,4 @@
|
|||||||
// Generated from ColorToolCore at 2021-12-20 15:27:15 +0000
|
// Generated from ColorToolCore at 2021-12-20 15:34:55 +0000
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
63
SampleFiles/Fonts/Generated/R2Font+Font.swift
Normal file
63
SampleFiles/Fonts/Generated/R2Font+Font.swift
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Lato/Lato-Italic.ttf Lato/Lato-LightItalic.ttf Lato/Lato-Thin.ttf Lato/Lato-Bold.ttf Lato/Lato-Black.ttf Lato/Lato-Regular.ttf Lato/Lato-BlackItalic.ttf Lato/Lato-BoldItalic.ttf Lato/Lato-Light.ttf Lato/Lato-ThinItalic.ttf
|
||||||
|
// Generated from FontToolCore
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension R2Font {
|
||||||
|
|
||||||
|
enum FontName: String {
|
||||||
|
case LatoItalic = "Lato-Italic"
|
||||||
|
case LatoLightItalic = "Lato-LightItalic"
|
||||||
|
case LatoHairline = "Lato-Hairline"
|
||||||
|
case LatoBold = "Lato-Bold"
|
||||||
|
case LatoBlack = "Lato-Black"
|
||||||
|
case LatoRegular = "Lato-Regular"
|
||||||
|
case LatoBlackItalic = "Lato-BlackItalic"
|
||||||
|
case LatoBoldItalic = "Lato-BoldItalic"
|
||||||
|
case LatoLight = "Lato-Light"
|
||||||
|
case LatoHairlineItalic = "Lato-HairlineItalic"
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Getter
|
||||||
|
|
||||||
|
func LatoItalic(withSize size: CGFloat) -> UIFont {
|
||||||
|
UIFont(name: FontName.LatoItalic.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
func LatoLightItalic(withSize size: CGFloat) -> UIFont {
|
||||||
|
UIFont(name: FontName.LatoLightItalic.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
func LatoHairline(withSize size: CGFloat) -> UIFont {
|
||||||
|
UIFont(name: FontName.LatoHairline.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
func LatoBold(withSize size: CGFloat) -> UIFont {
|
||||||
|
UIFont(name: FontName.LatoBold.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
func LatoBlack(withSize size: CGFloat) -> UIFont {
|
||||||
|
UIFont(name: FontName.LatoBlack.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
func LatoRegular(withSize size: CGFloat) -> UIFont {
|
||||||
|
UIFont(name: FontName.LatoRegular.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
func LatoBlackItalic(withSize size: CGFloat) -> UIFont {
|
||||||
|
UIFont(name: FontName.LatoBlackItalic.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
func LatoBoldItalic(withSize size: CGFloat) -> UIFont {
|
||||||
|
UIFont(name: FontName.LatoBoldItalic.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
func LatoLight(withSize size: CGFloat) -> UIFont {
|
||||||
|
UIFont(name: FontName.LatoLight.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
func LatoHairlineItalic(withSize size: CGFloat) -> UIFont {
|
||||||
|
UIFont(name: FontName.LatoHairlineItalic.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
63
SampleFiles/Fonts/Generated/UIFont+Font.swift
Normal file
63
SampleFiles/Fonts/Generated/UIFont+Font.swift
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Lato/Lato-Italic.ttf Lato/Lato-LightItalic.ttf Lato/Lato-Thin.ttf Lato/Lato-Bold.ttf Lato/Lato-Black.ttf Lato/Lato-Regular.ttf Lato/Lato-BlackItalic.ttf Lato/Lato-BoldItalic.ttf Lato/Lato-Light.ttf Lato/Lato-ThinItalic.ttf
|
||||||
|
// Generated from FontToolCore
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension UIFont {
|
||||||
|
|
||||||
|
enum FontName: String {
|
||||||
|
case LatoItalic = "Lato-Italic"
|
||||||
|
case LatoLightItalic = "Lato-LightItalic"
|
||||||
|
case LatoHairline = "Lato-Hairline"
|
||||||
|
case LatoBold = "Lato-Bold"
|
||||||
|
case LatoBlack = "Lato-Black"
|
||||||
|
case LatoRegular = "Lato-Regular"
|
||||||
|
case LatoBlackItalic = "Lato-BlackItalic"
|
||||||
|
case LatoBoldItalic = "Lato-BoldItalic"
|
||||||
|
case LatoLight = "Lato-Light"
|
||||||
|
case LatoHairlineItalic = "Lato-HairlineItalic"
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Getter
|
||||||
|
|
||||||
|
static let LatoItalic: ((_ size: CGFloat) -> UIFont) = { size in
|
||||||
|
UIFont(name: FontName.LatoItalic.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
static let LatoLightItalic: ((_ size: CGFloat) -> UIFont) = { size in
|
||||||
|
UIFont(name: FontName.LatoLightItalic.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
static let LatoHairline: ((_ size: CGFloat) -> UIFont) = { size in
|
||||||
|
UIFont(name: FontName.LatoHairline.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
static let LatoBold: ((_ size: CGFloat) -> UIFont) = { size in
|
||||||
|
UIFont(name: FontName.LatoBold.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
static let LatoBlack: ((_ size: CGFloat) -> UIFont) = { size in
|
||||||
|
UIFont(name: FontName.LatoBlack.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
static let LatoRegular: ((_ size: CGFloat) -> UIFont) = { size in
|
||||||
|
UIFont(name: FontName.LatoRegular.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
static let LatoBlackItalic: ((_ size: CGFloat) -> UIFont) = { size in
|
||||||
|
UIFont(name: FontName.LatoBlackItalic.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
static let LatoBoldItalic: ((_ size: CGFloat) -> UIFont) = { size in
|
||||||
|
UIFont(name: FontName.LatoBoldItalic.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
static let LatoLight: ((_ size: CGFloat) -> UIFont) = { size in
|
||||||
|
UIFont(name: FontName.LatoLight.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
static let LatoHairlineItalic: ((_ size: CGFloat) -> UIFont) = { size in
|
||||||
|
UIFont(name: FontName.LatoHairlineItalic.rawValue, size: size)!
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,35 +1,12 @@
|
|||||||
//
|
//
|
||||||
// CLIToolCore.swift
|
// GeneratorChecker.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 13/12/2021.
|
// Created by Thibaut Schmitt on 22/12/2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public class Shell {
|
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
public static func shell(_ args: String...) -> (terminationStatus: Int32, output: String?) {
|
|
||||||
let task = Process()
|
|
||||||
task.launchPath = "/usr/bin/env"
|
|
||||||
task.arguments = args
|
|
||||||
|
|
||||||
let pipe = Pipe()
|
|
||||||
task.standardOutput = pipe
|
|
||||||
task.launch()
|
|
||||||
task.waitUntilExit()
|
|
||||||
|
|
||||||
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
|
||||||
|
|
||||||
guard let output: String = String(data: data, encoding: .utf8) else {
|
|
||||||
return (terminationStatus: task.terminationStatus, output: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (terminationStatus: task.terminationStatus, output: output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GeneratorChecker {
|
public class GeneratorChecker {
|
||||||
|
|
||||||
/// Return `true` if inputFile is newer than extensionFile, otherwise `false`
|
/// Return `true` if inputFile is newer than extensionFile, otherwise `false`
|
31
Sources/CLIToolCore/Shell.swift
Normal file
31
Sources/CLIToolCore/Shell.swift
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// File.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 22/12/2021.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class Shell {
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
public static func shell(_ args: String...) -> (terminationStatus: Int32, output: String?) {
|
||||||
|
let task = Process()
|
||||||
|
task.launchPath = "/usr/bin/env"
|
||||||
|
task.arguments = args
|
||||||
|
|
||||||
|
let pipe = Pipe()
|
||||||
|
task.standardOutput = pipe
|
||||||
|
task.launch()
|
||||||
|
task.waitUntilExit()
|
||||||
|
|
||||||
|
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
||||||
|
|
||||||
|
guard let output: String = String(data: data, encoding: .utf8) else {
|
||||||
|
return (terminationStatus: task.terminationStatus, output: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (terminationStatus: task.terminationStatus, output: output)
|
||||||
|
}
|
||||||
|
}
|
@ -40,7 +40,7 @@ struct ColorTool: ParsableCommand {
|
|||||||
var extensionSuffix: String = ""
|
var extensionSuffix: String = ""
|
||||||
|
|
||||||
var colorStyle: ColorStyle { ColorStyle(rawValue: style) ?? .all }
|
var colorStyle: ColorStyle { ColorStyle(rawValue: style) ?? .all }
|
||||||
var extensionFileName: String { "\(extensionName)+Font\(extensionSuffix).swift" }
|
var extensionFileName: String { "\(extensionName)+Color\(extensionSuffix).swift" }
|
||||||
var extensionFilePath: String { "\(extensionOutputPath)/\(extensionFileName)" }
|
var extensionFilePath: String { "\(extensionOutputPath)/\(extensionFileName)" }
|
||||||
|
|
||||||
public func run() throws {
|
public func run() throws {
|
||||||
|
@ -11,8 +11,8 @@ class FontToolContentGenerator {
|
|||||||
|
|
||||||
static func getExtensionHeader(fontsNames: [String]) -> String {
|
static func getExtensionHeader(fontsNames: [String]) -> String {
|
||||||
"""
|
"""
|
||||||
// Generated from FontToolCore
|
|
||||||
// \(fontsNames.joined(separator: " "))
|
// \(fontsNames.joined(separator: " "))
|
||||||
|
// Generated from FontToolCore
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import Foundation
|
|||||||
import CLIToolCore
|
import CLIToolCore
|
||||||
|
|
||||||
class FontToolHelper {
|
class FontToolHelper {
|
||||||
static func getFontsData(fromInputFolder inputFolder: String) -> (fontsNames: [String], fontsFileNames: [String]) {
|
static func getFontsFilenames(fromInputFolder inputFolder: String) -> [String] {
|
||||||
// Get a enumerator for all files
|
// Get a enumerator for all files
|
||||||
let fileManager = FileManager()
|
let fileManager = FileManager()
|
||||||
|
|
||||||
@ -28,10 +28,12 @@ class FontToolHelper {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get font name (font name and font file name can be different)
|
return fontsFileNames
|
||||||
let fontsNames = fontsFileNames.compactMap { getFontName(atPath: "\(inputFolder)/\($0)") }
|
}
|
||||||
|
|
||||||
return (fontsNames: fontsNames, fontsFileNames: 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 {
|
private static func getFontName(atPath path: String) -> String {
|
||||||
|
49
Sources/FontToolCore/GeneratorFontChecker.swift
Normal file
49
Sources/FontToolCore/GeneratorFontChecker.swift
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// GeneratorFontCheck.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 22/12/2021.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class GeneratorFontChecker {
|
||||||
|
|
||||||
|
/// Will check if first line contains exactly all font filenames and nothinf more
|
||||||
|
static func shouldGenerate(force: Bool, inputFilenames: [String], extensionFilePath: String) -> Bool {
|
||||||
|
guard force == false else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
let fileManager = FileManager()
|
||||||
|
guard fileManager.fileExists(atPath: extensionFilePath) else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
let extensionFileContent = try! String(contentsOfFile: extensionFilePath, encoding: .utf8)
|
||||||
|
|
||||||
|
guard let extensionComparableLine = extensionFileContent.components(separatedBy: .newlines).first else {
|
||||||
|
// First line to compare unavailable -> force generation
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
let extensionFontNames: [String] = extensionComparableLine
|
||||||
|
.split(separator: " ")
|
||||||
|
.dropFirst()
|
||||||
|
.map { String($0) }
|
||||||
|
|
||||||
|
// If count is different, some fonts has been added or removed
|
||||||
|
if inputFilenames.count != extensionFontNames.count {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same number of elements, check if all fonts to generate has been already generated in extension
|
||||||
|
for inputFile in inputFilenames {
|
||||||
|
if extensionFontNames.contains(inputFile) == false {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,9 @@ import ArgumentParser
|
|||||||
struct FontTool: ParsableCommand {
|
struct FontTool: ParsableCommand {
|
||||||
static let defaultExtensionName = "UIFont"
|
static let defaultExtensionName = "UIFont"
|
||||||
|
|
||||||
|
@Flag(name: .customShort("f"), help: "Should force generation")
|
||||||
|
var forceGeneration = false
|
||||||
|
|
||||||
@Argument(help: "Input folder where fonts to generate are.")
|
@Argument(help: "Input folder where fonts to generate are.")
|
||||||
var inputFolder: String
|
var inputFolder: String
|
||||||
|
|
||||||
@ -26,15 +29,31 @@ struct FontTool: ParsableCommand {
|
|||||||
@Option(help: "Extension name. If not specified, it will generate an UIFont extension")
|
@Option(help: "Extension name. If not specified, it will generate an UIFont extension")
|
||||||
var extensionName: String = Self.defaultExtensionName
|
var extensionName: String = Self.defaultExtensionName
|
||||||
|
|
||||||
|
var extensionFileName: String { "\(extensionName)+Font.swift" }
|
||||||
|
var extensionFilePath: String { "\(extensionOutputPath)/\(extensionFileName)" }
|
||||||
|
|
||||||
public func run() throws {
|
public func run() throws {
|
||||||
print("[FontTool] Starting fonts generation")
|
print("[FontTool] Starting fonts generation")
|
||||||
|
|
||||||
let fontsData = FontToolHelper.getFontsData(fromInputFolder: inputFolder)
|
|
||||||
|
|
||||||
let extensionHeader = FontToolContentGenerator.getExtensionHeader(fontsNames: fontsData.fontsNames)
|
let fontsFilenames = FontToolHelper.getFontsFilenames(fromInputFolder: inputFolder)
|
||||||
|
|
||||||
|
// Check if needed to regenerate
|
||||||
|
guard GeneratorFontChecker.shouldGenerate(force: forceGeneration, inputFilenames: fontsFilenames, extensionFilePath: extensionFilePath) else {
|
||||||
|
print("[FontTool] Fonts are already up to date :) ")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
print("[FontTool] Will generate fonts")
|
||||||
|
|
||||||
|
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 \(extensionName) {\n"
|
let extensionDefinitionOpening = "extension \(extensionName) {\n"
|
||||||
let extensionFontsNamesEnum = FontToolContentGenerator.getFontNameEnum(fontsNames: fontsData.fontsNames)
|
let extensionFontsNamesEnum = FontToolContentGenerator.getFontNameEnum(fontsNames: fontsNames)
|
||||||
let extensionFontsMethods = FontToolContentGenerator.getFontMethods(fontsNames: fontsData.fontsNames, isUIFontExtension: isUIFontExtension())
|
let extensionFontsMethods = FontToolContentGenerator.getFontMethods(fontsNames: fontsNames, isUIFontExtension: isUIFontExtension())
|
||||||
let extensionDefinitionClosing = "}"
|
let extensionDefinitionClosing = "}"
|
||||||
|
|
||||||
generateExtensionFile(extensionHeader,
|
generateExtensionFile(extensionHeader,
|
||||||
@ -44,15 +63,12 @@ struct FontTool: ParsableCommand {
|
|||||||
extensionDefinitionClosing)
|
extensionDefinitionClosing)
|
||||||
|
|
||||||
print("Info.plist information:")
|
print("Info.plist information:")
|
||||||
print("\(generatePlistUIAppFonts(fontsNames: fontsData.fontsNames))")
|
print("\(generatePlistUIAppFonts(fontsNames: fontsNames))")
|
||||||
|
|
||||||
print("[FontTool] Fonts generated")
|
print("[FontTool] Fonts generated")
|
||||||
}
|
}
|
||||||
|
|
||||||
private func generateExtensionFile(_ args: String...) {
|
private func generateExtensionFile(_ args: String...) {
|
||||||
// Create output path
|
|
||||||
let extensionFilePath = "\(extensionOutputPath)/\(extensionName)+Font.swift"
|
|
||||||
|
|
||||||
// Create file if not exists
|
// Create file if not exists
|
||||||
let fileManager = FileManager()
|
let fileManager = FileManager()
|
||||||
if fileManager.fileExists(atPath: extensionFilePath) == false {
|
if fileManager.fileExists(atPath: extensionFilePath) == false {
|
||||||
@ -86,3 +102,13 @@ struct FontTool: ParsableCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FontTool.main()
|
FontTool.main()
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
1. R2Font extension
|
||||||
|
swift run -c release FontToolCore ./SampleFiles/Fonts --extension-output-path ./SampleFiles/Fonts/Generated --extension-name R2Font
|
||||||
|
|
||||||
|
1. UIFont defualt extension (will gen static property)
|
||||||
|
swift run -c release FontToolCore ./SampleFiles/Fonts --extension-output-path ./SampleFiles/Fonts/Generated
|
||||||
|
|
||||||
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user