Bugs fixes, Lint fixes, Refactoring
Some checks failed
gitea-openium/resgen.swift/pipeline/head There was a failure building this commit

This commit is contained in:
2022-08-29 13:38:46 +02:00
parent e3f90e0d48
commit a54a264447
35 changed files with 652 additions and 401 deletions

View File

@ -1,42 +0,0 @@
//
// ColorExtensionGenerator.swift
//
//
// Created by Thibaut Schmitt on 20/12/2021.
//
import Foundation
import ToolCore
struct ColorExtensionGenerator {
let colors: [GenColor]
let extensionClassname: String
let isUIColorExtension: Bool
func getHeader() -> String {
"""
// Generated by ResgenSwift.ColorToolCore \(ResgenSwiftVersion)
import UIKit
extension \(extensionClassname) {\n
"""
}
func getFooter() -> String {
"""
}
"""
}
func getProperties() -> String {
colors.map {
if extensionClassname == ColorTool.defaultExtensionName {
return $0.getColorStaticProperty()
}
return $0.getColorProperty()
}
.joined(separator: "\n\n")
}
}

View File

@ -16,7 +16,7 @@ struct ColorToolOptions: ParsableArguments {
var inputFile: String
@Option(help: "Color style to generate: light for light colors only, or all for dark and light colors")
var style: String
fileprivate var style: String
@Option(help: "Path of xcassets where to generate colors", transform: { $0.replaceTiltWithHomeDirectoryPath() })
var xcassetsPath: String
@ -30,3 +30,9 @@ struct ColorToolOptions: ParsableArguments {
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+ColorsMyApp.swift")
var extensionSuffix: String = ""
}
extension ColorToolOptions {
var colorStyle: ColorStyle {
ColorStyle(rawValue: style) ?? .all
}
}

View File

@ -0,0 +1,67 @@
//
// ColorExtensionGenerator.swift
//
//
// Created by Thibaut Schmitt on 20/12/2021.
//
import Foundation
import ToolCore
struct ColorExtensionGenerator {
let colors: [ParsedColor]
let extensionClassname: String
static func writeExtensionFile(colors: [ParsedColor], staticVar: Bool, extensionName: String, extensionFilePath: String) {
// Create file if not exists
let fileManager = FileManager()
if fileManager.fileExists(atPath: extensionFilePath) == false {
Shell.shell("touch", "\(extensionFilePath)")
}
// Create extension content
let extensionContent = [
Self.getHeader(extensionClassname: extensionName),
Self.getProperties(for: colors, withStaticVar: staticVar),
Self.getFooter()
]
.joined(separator: "\n")
// Write content
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
do {
try extensionContent.write(to: extensionFilePathURL, atomically: true, encoding: .utf8)
} catch (let error) {
let error = ColorToolError.writeExtension(extensionFilePath, error.localizedDescription)
print(error.localizedDescription)
ColorTool.exit(withError: error)
}
}
private static func getHeader(extensionClassname: String) -> String {
"""
// Generated by ResgenSwift.\(ColorTool.toolName) \(ResgenSwiftVersion)
import UIKit
extension \(extensionClassname) {\n
"""
}
private static func getFooter() -> String {
"""
}
"""
}
private static func getProperties(for colors: [ParsedColor], withStaticVar staticVar: Bool) -> String {
colors.map {
if staticVar {
return $0.getColorStaticProperty()
}
return $0.getColorProperty()
}
.joined(separator: "\n\n")
}
}

View File

@ -10,17 +10,14 @@ import ToolCore
struct ColorXcassetHelper {
let xcassetsPath: String
let colors: [GenColor]
func generateXcassetColors() {
static func generateXcassetColors(colors: [ParsedColor], to xcassetsPath: String) {
colors.forEach {
generateColorSetAssets(from: $0)
Self.generateColorSetAssets(from: $0, to: xcassetsPath)
}
}
// Generate ColorSet in XCAssets file
private func generateColorSetAssets(from color: GenColor) {
private static func generateColorSetAssets(from color: ParsedColor, to xcassetsPath: String) {
// Create ColorSet
let colorSetPath = "\(xcassetsPath)/Colors/\(color.name).colorset"
Shell.shell("mkdir", "-p", "\(colorSetPath)")

View File

@ -0,0 +1,13 @@
//
// File.swift
//
//
// Created by Thibaut Schmitt on 29/08/2022.
//
import Foundation
enum ColorStyle: String, Decodable {
case light
case all
}

View File

@ -1,5 +1,5 @@
//
// GenColor.swift
// ParsedColor.swift
//
//
// Created by Thibaut Schmitt on 20/12/2021.
@ -7,7 +7,7 @@
import Foundation
struct GenColor {
struct ParsedColor {
let name: String
let light: String
let dark: String

View File

@ -0,0 +1,49 @@
//
// File.swift
//
//
// Created by Thibaut Schmitt on 29/08/2022.
//
import Foundation
class ColorFileParser {
static func parse(_ inputFile: String, colorStyle: ColorStyle) -> [ParsedColor] {
// Get content of input file
let inputFileContent = try! String(contentsOfFile: inputFile, encoding: .utf8)
let colorsByLines = inputFileContent.components(separatedBy: CharacterSet.newlines)
// Iterate on each line of input file
return colorsByLines.enumerated().compactMap { lineNumber, colorLine in
// Required format:
// colorName="#RGB/#ARGB", colorName "#RGB/#ARGB", colorName "#RGB/#ARGB" "#RGB/#ARGB"
let colorLineCleanedUp = colorLine
.removeTrailingWhitespace()
.replacingOccurrences(of: "=", with: "") // Keep compat with current file format
guard colorLineCleanedUp.hasPrefix("#") == false, colorLineCleanedUp.isEmpty == false else {
print("[\(ColorTool.toolName)] ⚠️ BadFormat or empty line (line number: \(lineNumber + 1)). Skip this line")
return nil
}
let colorContent = colorLineCleanedUp.split(separator: " ")
guard colorContent.count >= 2 else {
let error = ColorToolError.badFormat(colorLine)
print(error.localizedDescription)
ColorTool.exit(withError: error)
}
switch colorStyle {
case .light:
return ParsedColor(name: String(colorContent[0]), light: String(colorContent[1]), dark: String(colorContent[1]))
case .all:
if colorContent.count == 3 {
return ParsedColor(name: String(colorContent[0]), light: String(colorContent[1]), dark: String(colorContent[2]))
}
return ParsedColor(name: String(colorContent[0]), light: String(colorContent[1]), dark: String(colorContent[1]))
}
}
}
}

View File

@ -9,134 +9,101 @@ import Foundation
import ToolCore
import ArgumentParser
enum ColorStyle: String, Decodable {
case light
case all
}
struct ColorTool: ParsableCommand {
// MARK: - CommandConfiguration
static var configuration = CommandConfiguration(
abstract: "A utility for generate colors assets and their getters.",
version: "0.1.0"
)
// MARK: - Static
static let toolName = "ColorTool"
static let defaultExtensionName = "UIColor"
static let assetsColorsFolderName = "Colors"
// MARK: - Properties
var extensionFileName: String {
if options.extensionSuffix.isEmpty == false {
return "\(options.extensionName)+\(options.extensionSuffix).swift"
}
return "\(options.extensionName).swift"
}
var extensionFilePath: String { "\(options.extensionOutputPath)/\(extensionFileName)" }
var generateStaticVariable: Bool {
options.extensionName == Self.defaultExtensionName
}
// MARK: - Command options
@OptionGroup var options: ColorToolOptions
var colorStyle: ColorStyle { ColorStyle(rawValue: options.style) ?? .all }
var extensionFileName: String { "\(options.extensionName)+\(options.extensionSuffix).swift" }
var extensionFilePath: String { "\(options.extensionOutputPath)/\(extensionFileName)" }
// MARK: - Run
public func run() throws {
print("[ColorTool] Starting colors generation")
print("[ColorTool] Will use inputFile \(options.inputFile) to generate \(colorStyle) colors in xcassets \(options.xcassetsPath)")
print("[ColorTool] Extension will be \(extensionFilePath)")
print("[\(Self.toolName)] Starting colors generation")
print("[\(Self.toolName)] Will use inputFile \(options.inputFile) to generate \(options.colorStyle) colors in xcassets \(options.xcassetsPath)")
// Check requirements
guard checkRequirements() else { return }
print("[\(Self.toolName)] Will generate colors")
// Delete current colors
deleteCurrentColors()
// Get colors to generate
let parsedColors = ColorFileParser.parse(options.inputFile,
colorStyle: options.colorStyle)
// Generate all colors in xcassets
ColorXcassetHelper.generateXcassetColors(colors: parsedColors,
to: options.xcassetsPath)
// Generate extension
ColorExtensionGenerator.writeExtensionFile(colors: parsedColors,
staticVar: generateStaticVariable,
extensionName: options.extensionName,
extensionFilePath: extensionFilePath)
print("[\(Self.toolName)] Colors generated")
}
// MARK: - Requirements
private func checkRequirements() -> Bool {
let fileManager = FileManager()
guard fileManager.fileExists(atPath: options.xcassetsPath) else {
let error = ColorToolError.fileNotExists(options.xcassetsPath)
print(error.localizedDescription)
ColorTool.exit(withError: error)
}
// Check if input file exists
guard fileManager.fileExists(atPath: options.inputFile) else {
let error = ColorToolError.fileNotExists(options.inputFile)
print(error.localizedDescription)
ColorTool.exit(withError: error)
}
// Check if needed to regenerate
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration, inputFilePath: options.inputFile, extensionFilePath: extensionFilePath) else {
print("[ColorTool] Colors are already up to date :) ")
return
}
print("[ColorTool] Will generate colors")
// Delete current colors
Shell.shell("rm", "-rf", "\(options.xcassetsPath)/Colors/*")
// Get colors
let colorsToGen = getColorsGen()
// Generate all colors in xcassets
let colorAssetHelper = ColorXcassetHelper(xcassetsPath: options.xcassetsPath, colors: colorsToGen)
colorAssetHelper.generateXcassetColors()
// Generate extension
let extensionGenerator = ColorExtensionGenerator(colors: colorsToGen,
extensionClassname: options.extensionName,
isUIColorExtension: isUIColorExtension())
let extensionHeader = extensionGenerator.getHeader()
let extensionProperties = extensionGenerator.getProperties()
let extensionFooter = extensionGenerator.getFooter()
generateExtensionFile(extensionHeader, extensionProperties, extensionFooter)
print("[ColorTool] Colors 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)
do {
try extensionContent.write(to: extensionFilePathURL, atomically: true, encoding: .utf8)
} catch (let error) {
let error = ColorToolError.writeExtension(extensionFilePath, error.localizedDescription)
// Check if xcassets file exists
guard fileManager.fileExists(atPath: options.xcassetsPath) else {
let error = ColorToolError.fileNotExists(options.xcassetsPath)
print(error.localizedDescription)
ColorTool.exit(withError: error)
}
}
private func getColorsGen() -> [GenColor] {
// Get content of input file
let inputFileContent = try! String(contentsOfFile: options.inputFile, encoding: .utf8)
let colorsByLines = inputFileContent.components(separatedBy: CharacterSet.newlines)
// Iterate on each line of input file
return colorsByLines.enumerated().compactMap { lineNumber, colorLine in
// Required format:
// colorName="#RGB/#ARGB", colorName "#RGB/#ARGB", colorName "#RGB/#ARGB" "#RGB/#ARGB"
let colorLineCleanedUp = colorLine
.removeTrailingWhitespace()
.replacingOccurrences(of: "=", with: "") // Keep compat with current file format
guard colorLineCleanedUp.hasPrefix("#") == false, colorLineCleanedUp.isEmpty == false else {
print("[ColorTool] ⚠️ BadFormat or empty line (line number: \(lineNumber + 1)). Skip this line")
return nil
}
let colorContent = colorLineCleanedUp.split(separator: " ")
guard colorContent.count >= 2 else {
let error = ColorToolError.badFormat(colorLine)
print(error.localizedDescription)
ColorTool.exit(withError: error)
}
switch colorStyle {
case .light:
return GenColor(name: String(colorContent[0]), light: String(colorContent[1]), dark: String(colorContent[1]))
case .all:
if colorContent.count == 3 {
return GenColor(name: String(colorContent[0]), light: String(colorContent[1]), dark: String(colorContent[2]))
}
return GenColor(name: String(colorContent[0]), light: String(colorContent[1]), dark: String(colorContent[1]))
}
// Check if needed to regenerate
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration, inputFilePath: options.inputFile, extensionFilePath: extensionFilePath) else {
print("[\(Self.toolName)] Colors are already up to date :) ")
return false
}
return true
}
// MARK: - Helpers
private func isUIColorExtension() -> Bool {
options.extensionName == Self.defaultExtensionName
private func deleteCurrentColors() {
Shell.shell("rm", "-rf", "\(options.xcassetsPath)/Colors/*")
}
}