feat(RES-34): Fix plist font filename (#14)
All checks were successful
gitea-openium/resgen.swift/pipeline/head This commit looks good
All checks were successful
gitea-openium/resgen.swift/pipeline/head This commit looks good
Reviewed-on: #14
This commit is contained in:
@ -7,7 +7,10 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable force_unwrapping
|
||||
|
||||
extension FileManager {
|
||||
|
||||
func getAllRegularFileIn(directory: String) -> [String] {
|
||||
var files = [String]()
|
||||
guard let enumerator = self.enumerator(at: URL(string: directory)!, includingPropertiesForKeys: [.isRegularFileKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) else {
|
||||
@ -15,7 +18,7 @@ extension FileManager {
|
||||
print(error.description)
|
||||
Images.exit(withError: error)
|
||||
}
|
||||
|
||||
|
||||
for case let fileURL as URL in enumerator {
|
||||
do {
|
||||
let fileAttributes = try fileURL.resourceValues(forKeys: [.isRegularFileKey])
|
||||
@ -30,7 +33,7 @@ extension FileManager {
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
|
||||
func getAllImageSetFolderIn(directory: String) -> [String] {
|
||||
var files = [String]()
|
||||
guard let enumerator = self.enumerator(at: URL(string: directory)!, includingPropertiesForKeys: [.isDirectoryKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) else {
|
||||
@ -38,7 +41,7 @@ extension FileManager {
|
||||
print(error.description)
|
||||
Images.exit(withError: error)
|
||||
}
|
||||
|
||||
|
||||
for case let fileURL as URL in enumerator {
|
||||
do {
|
||||
let fileAttributes = try fileURL.resourceValues(forKeys: [.isDirectoryKey])
|
||||
|
@ -5,42 +5,48 @@
|
||||
// Created by Thibaut Schmitt on 14/02/2022.
|
||||
//
|
||||
|
||||
import ToolCore
|
||||
import Foundation
|
||||
import ToolCore
|
||||
|
||||
enum ImageExtensionGenerator {
|
||||
|
||||
class ImageExtensionGenerator {
|
||||
|
||||
// MARK: - UIKit
|
||||
|
||||
static func generateExtensionFile(images: [ParsedImage],
|
||||
staticVar: Bool,
|
||||
inputFilename: String,
|
||||
extensionName: String,
|
||||
extensionFilePath: String,
|
||||
isSwiftUI: Bool) {
|
||||
|
||||
static func generateExtensionFile(
|
||||
images: [ParsedImage],
|
||||
staticVar: Bool,
|
||||
inputFilename: String,
|
||||
extensionName: String,
|
||||
extensionFilePath: String,
|
||||
isSwiftUI: Bool
|
||||
) {
|
||||
// Create extension conten1t
|
||||
let extensionContent = Self.getExtensionContent(images: images,
|
||||
staticVar: staticVar,
|
||||
extensionName: extensionName,
|
||||
inputFilename: inputFilename,
|
||||
isSwiftUI: isSwiftUI)
|
||||
|
||||
let extensionContent = Self.getExtensionContent(
|
||||
images: images,
|
||||
staticVar: staticVar,
|
||||
extensionName: extensionName,
|
||||
inputFilename: inputFilename,
|
||||
isSwiftUI: isSwiftUI
|
||||
)
|
||||
|
||||
// Write content
|
||||
let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath)
|
||||
do {
|
||||
try extensionContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8)
|
||||
} catch let error {
|
||||
} catch {
|
||||
let error = ImagesError.writeFile(extensionFilePath, error.localizedDescription)
|
||||
print(error.description)
|
||||
Images.exit(withError: error)
|
||||
}
|
||||
}
|
||||
|
||||
static func getExtensionContent(images: [ParsedImage],
|
||||
staticVar: Bool,
|
||||
extensionName: String,
|
||||
inputFilename: String,
|
||||
isSwiftUI: Bool) -> String {
|
||||
|
||||
static func getExtensionContent(
|
||||
images: [ParsedImage],
|
||||
staticVar: Bool,
|
||||
extensionName: String,
|
||||
inputFilename: String,
|
||||
isSwiftUI: Bool
|
||||
) -> String {
|
||||
[
|
||||
Self.getHeader(inputFilename: inputFilename, extensionClassname: extensionName, isSwiftUI: isSwiftUI),
|
||||
Self.getProperties(images: images, staticVar: staticVar, isSwiftUI: isSwiftUI),
|
||||
@ -48,30 +54,36 @@ class ImageExtensionGenerator {
|
||||
]
|
||||
.joined(separator: "\n")
|
||||
}
|
||||
|
||||
private static func getHeader(inputFilename: String,
|
||||
extensionClassname: String,
|
||||
isSwiftUI: Bool) -> String {
|
||||
|
||||
private static func getHeader(
|
||||
inputFilename: String,
|
||||
extensionClassname: String,
|
||||
isSwiftUI: Bool
|
||||
) -> String {
|
||||
"""
|
||||
// Generated by ResgenSwift.\(Images.toolName) \(ResgenSwiftVersion)
|
||||
// Images from \(inputFilename)
|
||||
|
||||
|
||||
import \(isSwiftUI ? "SwiftUI" : "UIKit")
|
||||
|
||||
|
||||
extension \(extensionClassname) {
|
||||
"""
|
||||
}
|
||||
|
||||
private static func getProperties(images: [ParsedImage], staticVar: Bool, isSwiftUI: Bool) -> String {
|
||||
|
||||
private static func getProperties(
|
||||
images: [ParsedImage],
|
||||
staticVar: Bool,
|
||||
isSwiftUI: Bool
|
||||
) -> String {
|
||||
images
|
||||
.map { "\n\($0.getImageProperty(isStatic: staticVar, isSwiftUI: isSwiftUI))" }
|
||||
.joined(separator: "\n")
|
||||
}
|
||||
|
||||
|
||||
private static func getFooter() -> String {
|
||||
"""
|
||||
}
|
||||
|
||||
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// XcassetsGenerator.swift
|
||||
//
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
@ -9,31 +9,34 @@ import Foundation
|
||||
import ToolCore
|
||||
|
||||
enum OutputImageExtension: String {
|
||||
|
||||
case png
|
||||
case svg
|
||||
}
|
||||
|
||||
class XcassetsGenerator {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
let forceGeneration: Bool
|
||||
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
|
||||
init(forceGeneration: Bool) {
|
||||
self.forceGeneration = forceGeneration
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Assets generation
|
||||
|
||||
|
||||
func generateXcassets(inputPath: String, imagesToGenerate: [ParsedImage], xcassetsPath: String) {
|
||||
let fileManager = FileManager()
|
||||
let svgConverter = Images.getSvgConverterPath()
|
||||
let allSubFiles = fileManager.getAllRegularFileIn(directory: inputPath)
|
||||
|
||||
|
||||
var generatedAssetsPaths = [String]()
|
||||
|
||||
|
||||
// Generate new assets
|
||||
imagesToGenerate.forEach { parsedImage in
|
||||
imagesToGenerate.forEach { parsedImage in // swiftlint:disable:this closure_body_length
|
||||
// Get image path
|
||||
let imageData: (path: String, ext: String) = {
|
||||
for subfile in allSubFiles {
|
||||
@ -54,14 +57,14 @@ class XcassetsGenerator {
|
||||
print(error.description)
|
||||
Images.exit(withError: error)
|
||||
}()
|
||||
|
||||
|
||||
// Create imageset folder name
|
||||
let imagesetName = "\(parsedImage.name).imageset"
|
||||
let imagesetPath = "\(xcassetsPath)/\(imagesetName)"
|
||||
|
||||
|
||||
// Store managed images path
|
||||
generatedAssetsPaths.append(imagesetName)
|
||||
|
||||
|
||||
// Generate output images path
|
||||
let output1x = "\(imagesetPath)/\(parsedImage.name).\(OutputImageExtension.png.rawValue)"
|
||||
let output2x = "\(imagesetPath)/\(parsedImage.name)@2x.\(OutputImageExtension.png.rawValue)"
|
||||
@ -79,12 +82,14 @@ class XcassetsGenerator {
|
||||
print("\(parsedImage.name) -> Not regenerating")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Create imageset folder
|
||||
if fileManager.fileExists(atPath: imagesetPath) == false {
|
||||
do {
|
||||
try fileManager.createDirectory(atPath: imagesetPath,
|
||||
withIntermediateDirectories: true)
|
||||
try fileManager.createDirectory(
|
||||
atPath: imagesetPath,
|
||||
withIntermediateDirectories: true
|
||||
)
|
||||
} catch {
|
||||
let error = ImagesError.createAssetFolder(imagesetPath)
|
||||
print(error.description)
|
||||
@ -124,9 +129,7 @@ class XcassetsGenerator {
|
||||
Shell.shell(command1x)
|
||||
Shell.shell(command2x)
|
||||
Shell.shell(command3x)
|
||||
|
||||
} else {
|
||||
|
||||
let output = "\(imagesetPath)/\(parsedImage.name).\(OutputImageExtension.svg.rawValue)"
|
||||
let tempURL = URL(fileURLWithPath: output)
|
||||
|
||||
@ -143,47 +146,69 @@ class XcassetsGenerator {
|
||||
// convert path/to/image.png -resize 200x300 path/to/output.png
|
||||
// convert path/to/image.png -resize 200x path/to/output.png
|
||||
// convert path/to/image.png -resize x300 path/to/output.png
|
||||
Shell.shell(["convert", "\(imageData.path)",
|
||||
"-resize", "\(convertArguments.x1.width ?? "")x\(convertArguments.x1.height ?? "")",
|
||||
output1x])
|
||||
Shell.shell(["convert", "\(imageData.path)",
|
||||
"-resize", "\(convertArguments.x2.width ?? "")x\(convertArguments.x2.height ?? "")",
|
||||
output2x])
|
||||
Shell.shell(["convert", "\(imageData.path)",
|
||||
"-resize", "\(convertArguments.x3.width ?? "")x\(convertArguments.x3.height ?? "")",
|
||||
output3x])
|
||||
Shell.shell(
|
||||
[
|
||||
"convert",
|
||||
"\(imageData.path)",
|
||||
"-resize",
|
||||
"\(convertArguments.x1.width ?? "")x\(convertArguments.x1.height ?? "")",
|
||||
output1x
|
||||
]
|
||||
)
|
||||
Shell.shell(
|
||||
[
|
||||
"convert",
|
||||
"\(imageData.path)",
|
||||
"-resize",
|
||||
"\(convertArguments.x2.width ?? "")x\(convertArguments.x2.height ?? "")",
|
||||
output2x
|
||||
]
|
||||
)
|
||||
Shell.shell(
|
||||
[
|
||||
"convert",
|
||||
"\(imageData.path)",
|
||||
"-resize",
|
||||
"\(convertArguments.x3.width ?? "")x\(convertArguments.x3.height ?? "")",
|
||||
output3x
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// Write Content.json
|
||||
guard let imagesetContentJson = parsedImage.generateContentJson(isVector: imageData.ext == "svg") else { return }
|
||||
let contentJsonFilePath = "\(imagesetPath)/Contents.json"
|
||||
|
||||
|
||||
let contentJsonFilePathURL = URL(fileURLWithPath: contentJsonFilePath)
|
||||
try! imagesetContentJson.write(to: contentJsonFilePathURL, atomically: false, encoding: .utf8)
|
||||
|
||||
try! imagesetContentJson.write( // swiftlint:disable:this force_try
|
||||
to: contentJsonFilePathURL,
|
||||
atomically: false,
|
||||
encoding: .utf8
|
||||
)
|
||||
|
||||
print("\(parsedImage.name) -> Generated")
|
||||
}
|
||||
|
||||
|
||||
// Success info
|
||||
let generatedAssetsCount = generatedAssetsPaths.count
|
||||
print("Images generated: \(generatedAssetsCount)")
|
||||
|
||||
|
||||
// Delete old assets
|
||||
let allImagesetName = Set(fileManager.getAllImageSetFolderIn(directory: xcassetsPath))
|
||||
let allImagesetName = Set(fileManager.getAllImageSetFolderIn(directory: xcassetsPath))
|
||||
let imagesetToRemove = allImagesetName.subtracting(Set(generatedAssetsPaths))
|
||||
|
||||
|
||||
imagesetToRemove.forEach {
|
||||
print("Will remove: \($0)")
|
||||
}
|
||||
|
||||
|
||||
imagesetToRemove.forEach { itemToRemove in
|
||||
try! fileManager.removeItem(atPath: "\(xcassetsPath)/\(itemToRemove)")
|
||||
try! fileManager.removeItem(atPath: "\(xcassetsPath)/\(itemToRemove)") // swiftlint:disable:this force_try
|
||||
}
|
||||
print("Removed \(imagesetToRemove.count) images")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Helpers: SVG command
|
||||
|
||||
|
||||
private func addConvertArgument(command: inout [String], convertArgument: ConvertArgument) {
|
||||
if let width = convertArgument.width, width.isEmpty == false {
|
||||
command.append("-w")
|
||||
@ -194,14 +219,14 @@ class XcassetsGenerator {
|
||||
command.append("\(height)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Helpers: bypass generation
|
||||
|
||||
|
||||
private func shouldGenerate(inputImagePath: String, xcassetImagePath: String, needToGenerateForSvg: Bool) -> Bool {
|
||||
if forceGeneration || needToGenerateForSvg {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
return GeneratorChecker.isFile(inputImagePath, moreRecenThan: xcassetImagePath)
|
||||
}
|
||||
}
|
||||
|
@ -1,123 +1,131 @@
|
||||
//
|
||||
// Images.swift
|
||||
//
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
|
||||
import ToolCore
|
||||
import Foundation
|
||||
import ArgumentParser
|
||||
import Foundation
|
||||
import ToolCore
|
||||
|
||||
struct Images: ParsableCommand {
|
||||
|
||||
|
||||
// MARK: - CommandConfiguration
|
||||
|
||||
|
||||
static var configuration = CommandConfiguration(
|
||||
abstract: "A utility for generate images and an extension to access them easily.",
|
||||
version: ResgenSwiftVersion
|
||||
)
|
||||
|
||||
|
||||
// MARK: - Static
|
||||
|
||||
|
||||
static let toolName = "Images"
|
||||
static let defaultExtensionName = "Image"
|
||||
static let defaultExtensionNameUIKit = "UIImage"
|
||||
|
||||
|
||||
// MARK: - Command Options
|
||||
|
||||
|
||||
@OptionGroup var options: ImagesOptions
|
||||
|
||||
|
||||
// MARK: - Run
|
||||
|
||||
|
||||
mutating func run() {
|
||||
print("[\(Self.toolName)] Starting images generation")
|
||||
print("[\(Self.toolName)] Will use inputFile \(options.inputFile) to generate images in xcassets \(options.xcassetsPath)")
|
||||
|
||||
|
||||
// Check requirements
|
||||
guard checkRequirements() else { return }
|
||||
|
||||
|
||||
print("[\(Self.toolName)] Will generate images")
|
||||
|
||||
|
||||
// Parse input file
|
||||
let imagesToGenerate = ImageFileParser.parse(options.inputFile, platform: PlatormTag.ios)
|
||||
|
||||
|
||||
// Generate xcassets files
|
||||
let inputFolder = URL(fileURLWithPath: options.inputFile)
|
||||
.deletingLastPathComponent()
|
||||
.relativePath
|
||||
|
||||
|
||||
let xcassetsGenerator = XcassetsGenerator(forceGeneration: options.forceExecutionAndGeneration)
|
||||
xcassetsGenerator.generateXcassets(inputPath: inputFolder,
|
||||
imagesToGenerate: imagesToGenerate,
|
||||
xcassetsPath: options.xcassetsPath)
|
||||
|
||||
xcassetsGenerator.generateXcassets(
|
||||
inputPath: inputFolder,
|
||||
imagesToGenerate: imagesToGenerate,
|
||||
xcassetsPath: options.xcassetsPath
|
||||
)
|
||||
|
||||
// Generate extension
|
||||
ImageExtensionGenerator.generateExtensionFile(images: imagesToGenerate,
|
||||
staticVar: options.staticMembers,
|
||||
inputFilename: options.inputFilenameWithoutExt,
|
||||
extensionName: options.extensionName,
|
||||
extensionFilePath: options.extensionFilePath,
|
||||
isSwiftUI: true)
|
||||
|
||||
ImageExtensionGenerator.generateExtensionFile(images: imagesToGenerate,
|
||||
staticVar: options.staticMembers,
|
||||
inputFilename: options.inputFilenameWithoutExt,
|
||||
extensionName: options.extensionNameUIKit,
|
||||
extensionFilePath: options.extensionFilePathUIKit,
|
||||
isSwiftUI: false)
|
||||
|
||||
ImageExtensionGenerator.generateExtensionFile(
|
||||
images: imagesToGenerate,
|
||||
staticVar: options.staticMembers,
|
||||
inputFilename: options.inputFilenameWithoutExt,
|
||||
extensionName: options.extensionName,
|
||||
extensionFilePath: options.extensionFilePath,
|
||||
isSwiftUI: true
|
||||
)
|
||||
|
||||
ImageExtensionGenerator.generateExtensionFile(
|
||||
images: imagesToGenerate,
|
||||
staticVar: options.staticMembers,
|
||||
inputFilename: options.inputFilenameWithoutExt,
|
||||
extensionName: options.extensionNameUIKit,
|
||||
extensionFilePath: options.extensionFilePathUIKit,
|
||||
isSwiftUI: false
|
||||
)
|
||||
|
||||
print("[\(Self.toolName)] Images generated")
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Requirements
|
||||
|
||||
|
||||
private func checkRequirements() -> Bool {
|
||||
guard options.forceExecutionAndGeneration == false else {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
let fileManager = FileManager()
|
||||
|
||||
// Input file
|
||||
guard fileManager.fileExists(atPath: options.inputFile) else {
|
||||
let error = ImagesError.fileNotExists(options.inputFile)
|
||||
print(error.description)
|
||||
Images.exit(withError: error)
|
||||
Self.exit(withError: error)
|
||||
}
|
||||
|
||||
// RSVG-Converter
|
||||
_ = Images.getSvgConverterPath()
|
||||
_ = Self.getSvgConverterPath()
|
||||
|
||||
// Extension for UIKit and SwiftUI should have different name
|
||||
guard options.extensionName != options.extensionNameUIKit else {
|
||||
let error = ImagesError.extensionNamesCollision(options.extensionName)
|
||||
print(error.description)
|
||||
Images.exit(withError: error)
|
||||
Self.exit(withError: error)
|
||||
}
|
||||
|
||||
|
||||
// Check if needed to regenerate
|
||||
guard GeneratorChecker.shouldGenerate(force: options.forceExecution,
|
||||
inputFilePath: options.inputFile,
|
||||
extensionFilePath: options.extensionFilePath) else {
|
||||
guard GeneratorChecker.shouldGenerate(
|
||||
force: options.forceExecution,
|
||||
inputFilePath: options.inputFile,
|
||||
extensionFilePath: options.extensionFilePath
|
||||
) else {
|
||||
print("[\(Self.toolName)] Images are already up to date :) ")
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
|
||||
@discardableResult
|
||||
static func getSvgConverterPath() -> String {
|
||||
let taskSvgConverter = Shell.shell(["which", "rsvg-convert"])
|
||||
if taskSvgConverter.terminationStatus == 0 {
|
||||
return taskSvgConverter.output!.removeCharacters(from: CharacterSet.whitespacesAndNewlines)
|
||||
return taskSvgConverter.output!.removeCharacters(from: CharacterSet.whitespacesAndNewlines) // swiftlint:disable:this force_unwrapping
|
||||
}
|
||||
|
||||
|
||||
let error = ImagesError.rsvgConvertNotFound
|
||||
print(error.description)
|
||||
Images.exit(withError: error)
|
||||
Self.exit(withError: error)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ImagesError.swift
|
||||
//
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
@ -8,6 +8,7 @@
|
||||
import Foundation
|
||||
|
||||
enum ImagesError: Error {
|
||||
|
||||
case extensionNamesCollision(String)
|
||||
case inputFolderNotFound(String)
|
||||
case fileNotExists(String)
|
||||
@ -17,33 +18,33 @@ enum ImagesError: Error {
|
||||
case writeFile(String, String)
|
||||
case createAssetFolder(String)
|
||||
case unknown(String)
|
||||
|
||||
|
||||
var description: 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 .inputFolderNotFound(let inputFolder):
|
||||
return "error: [\(Images.toolName)] Input folder not found: \(inputFolder)"
|
||||
|
||||
|
||||
case .fileNotExists(let filename):
|
||||
return "error: [\(Images.toolName)] File \(filename) does not exists"
|
||||
|
||||
|
||||
case .unknownImageExtension(let filename):
|
||||
return "error: [\(Images.toolName)] File \(filename) have an unhandled file extension. Cannot generate image."
|
||||
|
||||
case .getFileAttributed(let filename, let errorDescription):
|
||||
|
||||
case let .getFileAttributed(filename, errorDescription):
|
||||
return "error: [\(Images.toolName)] Getting file attributes of \(filename) failed with error: \(errorDescription)"
|
||||
|
||||
|
||||
case .rsvgConvertNotFound:
|
||||
return "error: [\(Images.toolName)] Can't find rsvg-convert (can be installed with 'brew remove imagemagick && brew install librsvg')"
|
||||
|
||||
case .writeFile(let subErrorDescription, let filename):
|
||||
|
||||
case let .writeFile(subErrorDescription, filename):
|
||||
return "error: [\(Images.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)"
|
||||
|
||||
case .createAssetFolder(let folder):
|
||||
return "error: [\(Colors.toolName)] An error occured while creating folder `\(folder)`"
|
||||
|
||||
|
||||
case .unknown(let errorDescription):
|
||||
return "error: [\(Images.toolName)] Unknown error: \(errorDescription)"
|
||||
}
|
||||
|
@ -1,38 +1,41 @@
|
||||
//
|
||||
// ImagiumOptions.swift
|
||||
//
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ArgumentParser
|
||||
import Foundation
|
||||
|
||||
// swiftlint:disable no_grouping_extension
|
||||
|
||||
struct ImagesOptions: ParsableArguments {
|
||||
|
||||
@Flag(name: .customShort("f"), help: "Should force script execution")
|
||||
var forceExecution = false
|
||||
|
||||
|
||||
@Flag(name: .customShort("F"), help: "Regenerate all images")
|
||||
var forceExecutionAndGeneration = false
|
||||
|
||||
|
||||
@Argument(help: "Input files where strings ared defined.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
||||
var inputFile: String
|
||||
|
||||
|
||||
@Option(help: "Xcassets path where to generate images.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
||||
var xcassetsPath: String
|
||||
|
||||
|
||||
@Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
||||
var extensionOutputPath: String
|
||||
|
||||
|
||||
@Option(help: "Tell if it will generate static properties or not")
|
||||
var staticMembers: Bool = false
|
||||
|
||||
|
||||
@Option(help: "Extension name. If not specified, it will generate an Image extension.")
|
||||
var extensionName: String = Images.defaultExtensionName
|
||||
|
||||
|
||||
@Option(help: "Extension name. If not specified, it will generate an UIImage extension.")
|
||||
var extensionNameUIKit: String = Images.defaultExtensionNameUIKit
|
||||
|
||||
|
||||
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+Image{extensionSuffix}.swift")
|
||||
var extensionSuffix: String?
|
||||
}
|
||||
@ -40,35 +43,35 @@ struct ImagesOptions: ParsableArguments {
|
||||
// MARK: - Computed var
|
||||
|
||||
extension ImagesOptions {
|
||||
|
||||
|
||||
// MARK: - SwiftUI
|
||||
|
||||
|
||||
var extensionFileName: String {
|
||||
if let extensionSuffix = extensionSuffix {
|
||||
if let extensionSuffix {
|
||||
return "\(extensionName)+\(extensionSuffix).swift"
|
||||
}
|
||||
return "\(extensionName).swift"
|
||||
}
|
||||
|
||||
|
||||
var extensionFilePath: String {
|
||||
"\(extensionOutputPath)/\(extensionFileName)"
|
||||
}
|
||||
|
||||
|
||||
// MARK: - UIKit
|
||||
|
||||
|
||||
var extensionFileNameUIKit: String {
|
||||
if let extensionSuffix = extensionSuffix {
|
||||
if let extensionSuffix {
|
||||
return "\(extensionNameUIKit)+\(extensionSuffix).swift"
|
||||
}
|
||||
return "\(extensionNameUIKit).swift"
|
||||
}
|
||||
|
||||
|
||||
var extensionFilePathUIKit: String {
|
||||
"\(extensionOutputPath)/\(extensionFileNameUIKit)"
|
||||
}
|
||||
|
||||
|
||||
// MARK: -
|
||||
|
||||
|
||||
var inputFilenameWithoutExt: String {
|
||||
URL(fileURLWithPath: inputFile)
|
||||
.deletingPathExtension()
|
||||
|
@ -8,6 +8,7 @@
|
||||
import Foundation
|
||||
|
||||
struct ConvertArgument {
|
||||
|
||||
let width: String?
|
||||
let height: String?
|
||||
}
|
||||
|
@ -8,11 +8,13 @@
|
||||
import Foundation
|
||||
|
||||
enum TemplateRenderingIntent: String, Codable {
|
||||
|
||||
case template
|
||||
case original
|
||||
}
|
||||
|
||||
struct AssetContent: Codable, Equatable {
|
||||
|
||||
let images: [AssetImageDescription]
|
||||
let info: AssetInfo
|
||||
let properties: AssetProperties?
|
||||
@ -27,16 +29,17 @@ struct AssetContent: Codable, Equatable {
|
||||
self.properties = properties
|
||||
}
|
||||
|
||||
static func == (lhs: AssetContent, rhs: AssetContent) -> Bool {
|
||||
static func == (lhs: Self, rhs: Self) -> Bool {
|
||||
guard lhs.images.count == rhs.images.count else { return false }
|
||||
let lhsImages = lhs.images.sorted(by: { $0.filename < $1.filename })
|
||||
let rhsImages = rhs.images.sorted(by: { $0.filename < $1.filename })
|
||||
let lhsImages = lhs.images.sorted { $0.filename < $1.filename }
|
||||
let rhsImages = rhs.images.sorted { $0.filename < $1.filename }
|
||||
|
||||
return lhsImages == rhsImages
|
||||
}
|
||||
}
|
||||
|
||||
struct AssetImageDescription: Codable, Equatable {
|
||||
|
||||
let idiom: String
|
||||
let scale: String?
|
||||
let filename: String
|
||||
@ -53,11 +56,13 @@ struct AssetImageDescription: Codable, Equatable {
|
||||
}
|
||||
|
||||
struct AssetInfo: Codable, Equatable {
|
||||
|
||||
let version: Int
|
||||
let author: String
|
||||
}
|
||||
|
||||
struct AssetProperties: Codable, Equatable {
|
||||
|
||||
let preservesVectorRepresentation: Bool
|
||||
let templateRenderingIntent: TemplateRenderingIntent?
|
||||
|
||||
@ -70,6 +75,7 @@ struct AssetProperties: Codable, Equatable {
|
||||
}
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
|
||||
case preservesVectorRepresentation = "preserves-vector-representation"
|
||||
case templateRenderingIntent = "template-rendering-intent"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// ParsedImage.swift
|
||||
//
|
||||
//
|
||||
//
|
||||
// Created by Thibaut Schmitt on 24/01/2022.
|
||||
//
|
||||
@ -8,10 +8,14 @@
|
||||
import Foundation
|
||||
|
||||
enum ImageExtension: String {
|
||||
|
||||
case png
|
||||
}
|
||||
|
||||
struct ParsedImage {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
let name: String
|
||||
let tags: String
|
||||
let width: Int
|
||||
@ -33,34 +37,34 @@ struct ParsedImage {
|
||||
}
|
||||
|
||||
// MARK: - Convert
|
||||
|
||||
var convertArguments: (x1: ConvertArgument, x2: ConvertArgument, x3: ConvertArgument) {
|
||||
|
||||
var convertArguments: (x1: ConvertArgument, x2: ConvertArgument, x3: ConvertArgument) { // swiftlint:disable:this large_tuple
|
||||
var width1x = ""
|
||||
var height1x = ""
|
||||
var width2x = ""
|
||||
var height2x = ""
|
||||
var width3x = ""
|
||||
var height3x = ""
|
||||
|
||||
|
||||
if width != -1 {
|
||||
width1x = "\(width)"
|
||||
width2x = "\(width * 2)"
|
||||
width3x = "\(width * 3)"
|
||||
}
|
||||
|
||||
|
||||
if height != -1 {
|
||||
height1x = "\(height)"
|
||||
height2x = "\(height * 2)"
|
||||
height3x = "\(height * 3)"
|
||||
}
|
||||
|
||||
|
||||
return (x1: ConvertArgument(width: width1x, height: height1x),
|
||||
x2: ConvertArgument(width: width2x, height: height2x),
|
||||
x3: ConvertArgument(width: width3x, height: height3x))
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Assets
|
||||
|
||||
|
||||
func generateContentJson(isVector: Bool) -> String? {
|
||||
let encoder = JSONEncoder()
|
||||
encoder.outputFormatting = .prettyPrinted
|
||||
@ -77,9 +81,8 @@ struct ParsedImage {
|
||||
}
|
||||
|
||||
func generateImageContent(isVector: Bool) -> AssetContent {
|
||||
|
||||
if !imageExtensions.contains(.png) && isVector {
|
||||
//Generate svg
|
||||
// Generate svg
|
||||
return AssetContent(
|
||||
images: [
|
||||
AssetImageDescription(
|
||||
@ -97,7 +100,7 @@ struct ParsedImage {
|
||||
)
|
||||
)
|
||||
} else {
|
||||
//Generate png
|
||||
// Generate png
|
||||
return AssetContent(
|
||||
images: [
|
||||
AssetImageDescription(
|
||||
@ -125,17 +128,17 @@ struct ParsedImage {
|
||||
}
|
||||
|
||||
// MARK: - Extension property
|
||||
|
||||
|
||||
func getImageProperty(isStatic: Bool, isSwiftUI: Bool) -> String {
|
||||
if isSwiftUI {
|
||||
return """
|
||||
\(isStatic ? "static ": "")var \(name): Image {
|
||||
\(isStatic ? "static " : "")var \(name): Image {
|
||||
Image("\(name)")
|
||||
}
|
||||
"""
|
||||
}
|
||||
return """
|
||||
\(isStatic ? "static ": "")var \(name): UIImage {
|
||||
\(isStatic ? "static " : "")var \(name): UIImage {
|
||||
UIImage(named: "\(name)")!
|
||||
}
|
||||
"""
|
||||
|
@ -8,6 +8,7 @@
|
||||
import Foundation
|
||||
|
||||
enum PlatormTag: String {
|
||||
|
||||
case droid = "d"
|
||||
case ios = "i"
|
||||
}
|
||||
|
@ -7,36 +7,36 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
class ImageFileParser {
|
||||
|
||||
enum ImageFileParser {
|
||||
|
||||
static func parse(_ inputFile: String, platform: PlatormTag) -> [ParsedImage] {
|
||||
let inputFileContent = try! String(contentsOfFile: inputFile, encoding: .utf8)
|
||||
let inputFileContent = try! String(contentsOfFile: inputFile, encoding: .utf8) // swiftlint:disable:this force_try
|
||||
let stringsByLines = inputFileContent.components(separatedBy: .newlines)
|
||||
|
||||
|
||||
return Self.parseLines(stringsByLines, platform: platform)
|
||||
}
|
||||
|
||||
|
||||
static func parseLines(_ lines: [String], platform: PlatormTag) -> [ParsedImage] {
|
||||
var imagesToGenerate = [ParsedImage]()
|
||||
|
||||
|
||||
lines.forEach {
|
||||
guard $0.removeLeadingTrailingWhitespace().isEmpty == false, $0.first != "#" else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let splittedLine = $0.split(separator: " ")
|
||||
|
||||
|
||||
let width: Int = {
|
||||
if splittedLine[2] == "?" {
|
||||
return -1
|
||||
}
|
||||
return Int(splittedLine[2])!
|
||||
return Int(splittedLine[2])! // swiftlint:disable:this force_unwrapping
|
||||
}()
|
||||
let height: Int = {
|
||||
if splittedLine[3] == "?" {
|
||||
return -1
|
||||
}
|
||||
return Int(splittedLine[3])!
|
||||
return Int(splittedLine[3])! // swiftlint:disable:this force_unwrapping
|
||||
}()
|
||||
|
||||
var imageExtensions: [ImageExtension] = []
|
||||
|
Reference in New Issue
Block a user