Refactor in one unique command with subcommand + add a new command to generate ressources from a configuration file
Some checks failed
gitea-openium/resgen.swift/pipeline/head There was a failure building this commit
Some checks failed
gitea-openium/resgen.swift/pipeline/head There was a failure building this commit
This commit is contained in:
@ -160,6 +160,20 @@
|
|||||||
ReferencedContainer = "container:">
|
ReferencedContainer = "container:">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildActionEntry>
|
</BuildActionEntry>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "ColorTool"
|
||||||
|
BuildableName = "ColorTool"
|
||||||
|
BlueprintName = "ColorTool"
|
||||||
|
ReferencedContainer = "container:">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
</BuildActionEntries>
|
</BuildActionEntries>
|
||||||
</BuildAction>
|
</BuildAction>
|
||||||
<TestAction
|
<TestAction
|
||||||
|
@ -34,6 +34,34 @@
|
|||||||
ReferencedContainer = "container:">
|
ReferencedContainer = "container:">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildActionEntry>
|
</BuildActionEntry>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "ToolCore"
|
||||||
|
BuildableName = "ToolCore"
|
||||||
|
BlueprintName = "ToolCore"
|
||||||
|
ReferencedContainer = "container:">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "ResgenSwift_ResgenSwift"
|
||||||
|
BuildableName = "ResgenSwift_ResgenSwift"
|
||||||
|
BlueprintName = "ResgenSwift_ResgenSwift"
|
||||||
|
ReferencedContainer = "container:">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
</BuildActionEntries>
|
</BuildActionEntries>
|
||||||
</BuildAction>
|
</BuildAction>
|
||||||
<TestAction
|
<TestAction
|
||||||
|
@ -9,6 +9,15 @@
|
|||||||
"revision": "e1465042f195f374b94f915ba8ca49de24300a0d",
|
"revision": "e1465042f195f374b94f915ba8ca49de24300a0d",
|
||||||
"version": "1.0.2"
|
"version": "1.0.2"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "Yams",
|
||||||
|
"repositoryURL": "https://github.com/jpsim/Yams.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "01835dc202670b5bb90d07f3eae41867e9ed29f6",
|
||||||
|
"version": "5.0.1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -1,56 +1,67 @@
|
|||||||
// swift-tools-version:5.3
|
// swift-tools-version:5.6
|
||||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||||
|
|
||||||
import PackageDescription
|
import PackageDescription
|
||||||
|
|
||||||
let package = Package(
|
let package = Package(
|
||||||
name: "ResgenSwift",
|
name: "ResgenSwift",
|
||||||
platforms: [.macOS(.v10_12)],
|
platforms: [.macOS(.v12)],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
// Dependencies declare other packages that this package depends on.
|
// Dependencies declare other packages that this package depends on.
|
||||||
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0")
|
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"),
|
||||||
|
.package(url: "https://github.com/jpsim/Yams.git", from: "5.0.1")
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||||
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
||||||
.target(
|
.executableTarget(
|
||||||
name: "ResgenSwift",
|
name: "ResgenSwift",
|
||||||
dependencies: ["FontTool", "ColorTool", "Strings", "Imagium"]
|
|
||||||
),
|
|
||||||
.target(
|
|
||||||
name: "FontTool",
|
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"ToolCore",
|
"ToolCore",
|
||||||
.product(name: "ArgumentParser", package: "swift-argument-parser")
|
.product(name: "ArgumentParser", package: "swift-argument-parser"),
|
||||||
]
|
"Yams"
|
||||||
),
|
|
||||||
.target(
|
|
||||||
name: "ColorTool",
|
|
||||||
dependencies: [
|
|
||||||
"ToolCore",
|
|
||||||
.product(name: "ArgumentParser", package: "swift-argument-parser")
|
|
||||||
]
|
|
||||||
),
|
|
||||||
.target(
|
|
||||||
name: "Strings",
|
|
||||||
dependencies: [
|
|
||||||
"ToolCore",
|
|
||||||
.product(name: "ArgumentParser", package: "swift-argument-parser")
|
|
||||||
],
|
|
||||||
sources: ["."] // Force include all subdirectories
|
|
||||||
),
|
|
||||||
.target(
|
|
||||||
name: "Imagium",
|
|
||||||
dependencies: [
|
|
||||||
"ToolCore",
|
|
||||||
.product(name: "ArgumentParser", package: "swift-argument-parser")
|
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// .executableTarget(
|
||||||
|
// name: "FontTool",
|
||||||
|
// dependencies: [
|
||||||
|
// "ToolCore",
|
||||||
|
// .product(name: "ArgumentParser", package: "swift-argument-parser")
|
||||||
|
// ]
|
||||||
|
// ),
|
||||||
|
//
|
||||||
|
// .executableTarget(
|
||||||
|
// name: "ColorTool",
|
||||||
|
// dependencies: [
|
||||||
|
// "ToolCore",
|
||||||
|
// .product(name: "ArgumentParser", package: "swift-argument-parser")
|
||||||
|
// ]
|
||||||
|
// ),
|
||||||
|
//
|
||||||
|
// .executableTarget(
|
||||||
|
// name: "Strings",
|
||||||
|
// dependencies: [
|
||||||
|
// "ToolCore",
|
||||||
|
// .product(name: "ArgumentParser", package: "swift-argument-parser")
|
||||||
|
// ],
|
||||||
|
// sources: ["."] // Force include all subdirectories
|
||||||
|
// ),
|
||||||
|
//
|
||||||
|
// .executableTarget(
|
||||||
|
// name: "Imagium",
|
||||||
|
// dependencies: [
|
||||||
|
// "ToolCore",
|
||||||
|
// .product(name: "ArgumentParser", package: "swift-argument-parser")
|
||||||
|
// ]
|
||||||
|
// ),
|
||||||
|
|
||||||
// Helper targets
|
// Helper targets
|
||||||
.target(name: "ToolCore"),
|
.target(name: "ToolCore"),
|
||||||
|
|
||||||
// Test targets
|
// Test targets
|
||||||
.testTarget(
|
// .testTarget(
|
||||||
name: "ResgenSwiftTests",
|
// name: "ResgenSwiftTests",
|
||||||
dependencies: ["ResgenSwift"]),
|
// dependencies: ["ResgenSwift"]),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
@ -121,7 +121,7 @@ swift run -c release Strings tags $FORCE_FLAG "./Tags/tags.txt" \
|
|||||||
5. `--extension-name` *(optional)* : name of class to add the extension
|
5. `--extension-name` *(optional)* : name of class to add the extension
|
||||||
6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppTags+GreatApp.swift`)
|
6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppTags+GreatApp.swift`)
|
||||||
|
|
||||||
> ⚠️ If extension name is not set or is `Tags`, it will generate static property on `Tags`. This class may not exists in your project, just create an empty class named `Tags` is necessary.
|
> ⚠️ If extension name is not set or is `Tags`, it will generate static property on `Tags`. `Tags` is a typealias of `String`.
|
||||||
|
|
||||||
# Images
|
# Images
|
||||||
|
|
||||||
@ -148,4 +148,4 @@ swift run -c release Imagium $FORCE_FLAG "./Images/images.txt" \
|
|||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
[ ] Allow static variable generation on custom extension
|
[ ] Allow static variable generation on custom extension
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
//
|
|
||||||
// ColorToolError.swift
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Created by Thibaut Schmitt on 20/12/2021.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
enum ColorToolError: Error {
|
|
||||||
case badFormat(String)
|
|
||||||
case writeAsset(String)
|
|
||||||
case writeExtension(String, String)
|
|
||||||
case fileNotExists(String)
|
|
||||||
case badColorDefinition(String, String)
|
|
||||||
|
|
||||||
var description: String {
|
|
||||||
switch self {
|
|
||||||
case .badFormat(let info):
|
|
||||||
return "error:[ColorTool] Bad line format: \(info). Accepted format are: colorName=\"#RGB/#ARGB\"; colorName \"#RGB/#ARGB\"; colorName \"#RGB/#ARGB\" \"#RGB/#ARGB\""
|
|
||||||
|
|
||||||
case .writeAsset(let info):
|
|
||||||
return "error:[ColorTool] An error occured while writing color in Xcasset: \(info)"
|
|
||||||
|
|
||||||
case .writeExtension(let filename, let info):
|
|
||||||
return "error:[ColorTool] An error occured while writing extension in \(filename): \(info)"
|
|
||||||
|
|
||||||
case .fileNotExists(let filename):
|
|
||||||
return "error:[ColorTool] File \(filename) does not exists"
|
|
||||||
|
|
||||||
case .badColorDefinition(let lightColor, let darkColor):
|
|
||||||
return "error:[ColorTool]One of these two colors has invalid synthax: -\(lightColor)- or -\(darkColor)-"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
//
|
|
||||||
// ImagiumError.swift
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Created by Thibaut Schmitt on 24/01/2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
enum ImagiumError: Error {
|
|
||||||
case inputFolderNotFound(String)
|
|
||||||
case fileNotExists(String)
|
|
||||||
case unknownImageExtension(String)
|
|
||||||
case getFileAttributed(String, String)
|
|
||||||
case rsvgConvertNotFound
|
|
||||||
case writeFile(String, String)
|
|
||||||
case unknown(String)
|
|
||||||
|
|
||||||
var localizedDescription: String {
|
|
||||||
switch self {
|
|
||||||
case .inputFolderNotFound(let inputFolder):
|
|
||||||
return " error:[\(Imagium.toolName)] Input folder not found: \(inputFolder)"
|
|
||||||
|
|
||||||
case .fileNotExists(let filename):
|
|
||||||
return " error:[\(Imagium.toolName)] File \(filename) does not exists"
|
|
||||||
|
|
||||||
case .unknownImageExtension(let filename):
|
|
||||||
return " error:[\(Imagium.toolName)] File \(filename) have an unhandled file extension. Cannot generate image."
|
|
||||||
|
|
||||||
case .getFileAttributed(let filename, let errorDescription):
|
|
||||||
return " error:[\(Imagium.toolName)] Getting file attributes of \(filename) failed with error: \(errorDescription)"
|
|
||||||
|
|
||||||
case .rsvgConvertNotFound:
|
|
||||||
return " error:[\(Imagium.toolName)] Can't find rsvg-convert (can be installed with 'brew remove imagemagick && brew install imagemagick --with-librsvg')"
|
|
||||||
|
|
||||||
case .writeFile(let subErrorDescription, let filename):
|
|
||||||
return " error:[\(Imagium.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)"
|
|
||||||
|
|
||||||
case .unknown(let errorDescription):
|
|
||||||
return " error:[\(Imagium.toolName)] Unknown error: \(errorDescription)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,7 +9,7 @@ import ToolCore
|
|||||||
import Foundation
|
import Foundation
|
||||||
import ArgumentParser
|
import ArgumentParser
|
||||||
|
|
||||||
struct ColorTool: ParsableCommand {
|
struct Colors: ParsableCommand {
|
||||||
|
|
||||||
// MARK: - CommandConfiguration
|
// MARK: - CommandConfiguration
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ struct ColorTool: ParsableCommand {
|
|||||||
|
|
||||||
// MARK: - Static
|
// MARK: - Static
|
||||||
|
|
||||||
static let toolName = "ColorTool"
|
static let toolName = "Color"
|
||||||
static let defaultExtensionName = "UIColor"
|
static let defaultExtensionName = "UIColor"
|
||||||
static let assetsColorsFolderName = "Colors"
|
static let assetsColorsFolderName = "Colors"
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ struct ColorTool: ParsableCommand {
|
|||||||
|
|
||||||
// MARK: - Command options
|
// MARK: - Command options
|
||||||
|
|
||||||
@OptionGroup var options: ColorToolOptions
|
@OptionGroup var options: ColorsToolOptions
|
||||||
|
|
||||||
// MARK: - Run
|
// MARK: - Run
|
||||||
|
|
||||||
@ -79,16 +79,16 @@ struct ColorTool: ParsableCommand {
|
|||||||
|
|
||||||
// Check if input file exists
|
// Check if input file exists
|
||||||
guard fileManager.fileExists(atPath: options.inputFile) else {
|
guard fileManager.fileExists(atPath: options.inputFile) else {
|
||||||
let error = ColorToolError.fileNotExists(options.inputFile)
|
let error = ColorsToolError.fileNotExists(options.inputFile)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
ColorTool.exit(withError: error)
|
Colors.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if xcassets file exists
|
// Check if xcassets file exists
|
||||||
guard fileManager.fileExists(atPath: options.xcassetsPath) else {
|
guard fileManager.fileExists(atPath: options.xcassetsPath) else {
|
||||||
let error = ColorToolError.fileNotExists(options.xcassetsPath)
|
let error = ColorsToolError.fileNotExists(options.xcassetsPath)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
ColorTool.exit(withError: error)
|
Colors.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if needed to regenerate
|
// Check if needed to regenerate
|
||||||
@ -107,8 +107,6 @@ struct ColorTool: ParsableCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorTool.main()
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Command samples:
|
Command samples:
|
||||||
|
|
35
Sources/ResgenSwift/Colors/ColorsToolError.swift
Normal file
35
Sources/ResgenSwift/Colors/ColorsToolError.swift
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// ColorsToolError.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 20/12/2021.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum ColorsToolError: Error {
|
||||||
|
case badFormat(String)
|
||||||
|
case writeAsset(String)
|
||||||
|
case writeExtension(String, String)
|
||||||
|
case fileNotExists(String)
|
||||||
|
case badColorDefinition(String, String)
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
switch self {
|
||||||
|
case .badFormat(let info):
|
||||||
|
return "error:[\(Colors.toolName)] Bad line format: \(info). Accepted format are: colorName=\"#RGB/#ARGB\"; colorName \"#RGB/#ARGB\"; colorName \"#RGB/#ARGB\" \"#RGB/#ARGB\""
|
||||||
|
|
||||||
|
case .writeAsset(let info):
|
||||||
|
return "error:[\(Colors.toolName)] An error occured while writing color in Xcasset: \(info)"
|
||||||
|
|
||||||
|
case .writeExtension(let filename, let info):
|
||||||
|
return "error:[\(Colors.toolName)] An error occured while writing extension in \(filename): \(info)"
|
||||||
|
|
||||||
|
case .fileNotExists(let filename):
|
||||||
|
return "error:[\(Colors.toolName)] File \(filename) does not exists"
|
||||||
|
|
||||||
|
case .badColorDefinition(let lightColor, let darkColor):
|
||||||
|
return "error:[\(Colors.toolName)]One of these two colors has invalid synthax: -\(lightColor)- or -\(darkColor)-"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// ColorToolOptions.swift
|
// ColorsToolOptions.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 17/01/2022.
|
// Created by Thibaut Schmitt on 17/01/2022.
|
||||||
@ -8,7 +8,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import ArgumentParser
|
import ArgumentParser
|
||||||
|
|
||||||
struct ColorToolOptions: ParsableArguments {
|
struct ColorsToolOptions: ParsableArguments {
|
||||||
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
||||||
var forceGeneration = false
|
var forceGeneration = false
|
||||||
|
|
||||||
@ -25,13 +25,13 @@ struct ColorToolOptions: ParsableArguments {
|
|||||||
var extensionOutputPath: String
|
var extensionOutputPath: String
|
||||||
|
|
||||||
@Option(help: "Extension name. If not specified, it will generate an UIColor extension. Using default extension name will generate static property.")
|
@Option(help: "Extension name. If not specified, it will generate an UIColor extension. Using default extension name will generate static property.")
|
||||||
var extensionName: String = ColorTool.defaultExtensionName
|
var extensionName: String = Colors.defaultExtensionName
|
||||||
|
|
||||||
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+ColorsMyApp.swift")
|
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+ColorsMyApp.swift")
|
||||||
var extensionSuffix: String = ""
|
var extensionSuffix: String = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ColorToolOptions {
|
extension ColorsToolOptions {
|
||||||
var colorStyle: ColorStyle {
|
var colorStyle: ColorStyle {
|
||||||
ColorStyle(rawValue: style) ?? .all
|
ColorStyle(rawValue: style) ?? .all
|
||||||
}
|
}
|
@ -33,15 +33,15 @@ struct ColorExtensionGenerator {
|
|||||||
do {
|
do {
|
||||||
try extensionContent.write(to: extensionFilePathURL, atomically: true, encoding: .utf8)
|
try extensionContent.write(to: extensionFilePathURL, atomically: true, encoding: .utf8)
|
||||||
} catch (let error) {
|
} catch (let error) {
|
||||||
let error = ColorToolError.writeExtension(extensionFilePath, error.localizedDescription)
|
let error = ColorsToolError.writeExtension(extensionFilePath, error.localizedDescription)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
ColorTool.exit(withError: error)
|
Colors.exit(withError: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getHeader(extensionClassname: String) -> String {
|
private static func getHeader(extensionClassname: String) -> String {
|
||||||
"""
|
"""
|
||||||
// Generated by ResgenSwift.\(ColorTool.toolName) \(ResgenSwiftVersion)
|
// Generated by ResgenSwift.\(Colors.toolName) \(ResgenSwiftVersion)
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
@ -31,9 +31,9 @@ struct ColorXcassetHelper {
|
|||||||
do {
|
do {
|
||||||
try color.contentsJSON().write(to: contentsJsonPathURL, atomically: true, encoding: .utf8)
|
try color.contentsJSON().write(to: contentsJsonPathURL, atomically: true, encoding: .utf8)
|
||||||
} catch (let error) {
|
} catch (let error) {
|
||||||
let error = ColorToolError.writeAsset(error.localizedDescription)
|
let error = ColorsToolError.writeAsset(error.localizedDescription)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
ColorTool.exit(withError: error)
|
Colors.exit(withError: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// File.swift
|
// ColorStyle.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 29/08/2022.
|
// Created by Thibaut Schmitt on 29/08/2022.
|
@ -25,9 +25,9 @@ struct ParsedColor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
guard allComponents.contains(true) == false else {
|
guard allComponents.contains(true) == false else {
|
||||||
let error = ColorToolError.badColorDefinition(light, dark)
|
let error = ColorsToolError.badColorDefinition(light, dark)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
ColorTool.exit(withError: error)
|
Colors.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return """
|
return """
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// File.swift
|
// ColorFileParser.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 29/08/2022.
|
// Created by Thibaut Schmitt on 29/08/2022.
|
||||||
@ -22,16 +22,16 @@ class ColorFileParser {
|
|||||||
.replacingOccurrences(of: "=", with: "") // Keep compat with current file format
|
.replacingOccurrences(of: "=", with: "") // Keep compat with current file format
|
||||||
|
|
||||||
guard colorLineCleanedUp.hasPrefix("#") == false, colorLineCleanedUp.isEmpty == false else {
|
guard colorLineCleanedUp.hasPrefix("#") == false, colorLineCleanedUp.isEmpty == false else {
|
||||||
print("[\(ColorTool.toolName)] ⚠️ BadFormat or empty line (line number: \(lineNumber + 1)). Skip this line")
|
print("[\(Colors.toolName)] ⚠️ BadFormat or empty line (line number: \(lineNumber + 1)). Skip this line")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
let colorContent = colorLineCleanedUp.split(separator: " ")
|
let colorContent = colorLineCleanedUp.split(separator: " ")
|
||||||
|
|
||||||
guard colorContent.count >= 2 else {
|
guard colorContent.count >= 2 else {
|
||||||
let error = ColorToolError.badFormat(colorLine)
|
let error = ColorsToolError.badFormat(colorLine)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
ColorTool.exit(withError: error)
|
Colors.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch colorStyle {
|
switch colorStyle {
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// FontOptions.swift
|
// FontsOptions.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 17/01/2022.
|
// Created by Thibaut Schmitt on 17/01/2022.
|
||||||
@ -8,7 +8,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import ArgumentParser
|
import ArgumentParser
|
||||||
|
|
||||||
struct FontOptions: ParsableArguments {
|
struct FontsOptions: ParsableArguments {
|
||||||
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
||||||
var forceGeneration = false
|
var forceGeneration = false
|
||||||
|
|
||||||
@ -19,8 +19,25 @@ struct FontOptions: ParsableArguments {
|
|||||||
var extensionOutputPath: String
|
var extensionOutputPath: String
|
||||||
|
|
||||||
@Option(help: "Extension name. If not specified, it will generate an UIFont extension. Using default extension name will generate static property.")
|
@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
|
var extensionName: String = Fonts.defaultExtensionName
|
||||||
|
|
||||||
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+FontsMyApp.swift")
|
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+FontsMyApp.swift")
|
||||||
var extensionSuffix: String = ""
|
var extensionSuffix: String = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension FontsOptions {
|
||||||
|
var extensionFileName: String {
|
||||||
|
if extensionSuffix.isEmpty == false {
|
||||||
|
return "\(extensionName)+\(extensionSuffix).swift"
|
||||||
|
}
|
||||||
|
return "\(extensionName).swift"
|
||||||
|
}
|
||||||
|
|
||||||
|
var extensionFilePath: String {
|
||||||
|
"\(extensionOutputPath)/\(extensionFileName)"
|
||||||
|
}
|
||||||
|
|
||||||
|
var generateStaticVariable: Bool {
|
||||||
|
extensionName == Fonts.defaultExtensionName
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// FontTool.swift
|
// Fonts.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 13/12/2021.
|
// Created by Thibaut Schmitt on 13/12/2021.
|
||||||
@ -9,7 +9,7 @@ import ToolCore
|
|||||||
import Foundation
|
import Foundation
|
||||||
import ArgumentParser
|
import ArgumentParser
|
||||||
|
|
||||||
struct FontTool: ParsableCommand {
|
struct Fonts: ParsableCommand {
|
||||||
|
|
||||||
// MARK: - CommandConfiguration
|
// MARK: - CommandConfiguration
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ struct FontTool: ParsableCommand {
|
|||||||
|
|
||||||
// MARK: - Static
|
// MARK: - Static
|
||||||
|
|
||||||
static let toolName = "FontTool"
|
static let toolName = "Fonts"
|
||||||
static let defaultExtensionName = "UIFont"
|
static let defaultExtensionName = "UIFont"
|
||||||
|
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
@ -38,7 +38,7 @@ struct FontTool: ParsableCommand {
|
|||||||
|
|
||||||
// MARK: - Command Options
|
// MARK: - Command Options
|
||||||
|
|
||||||
@OptionGroup var options: FontOptions
|
@OptionGroup var options: FontsOptions
|
||||||
|
|
||||||
// MARK: - Run
|
// MARK: - Run
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ struct FontTool: ParsableCommand {
|
|||||||
|
|
||||||
// Get real font names
|
// Get real font names
|
||||||
let inputFolder = URL(fileURLWithPath: options.inputFile).deletingLastPathComponent().relativePath
|
let inputFolder = URL(fileURLWithPath: options.inputFile).deletingLastPathComponent().relativePath
|
||||||
let fontsNames = FontToolHelper.getFontPostScriptName(for: fontsToGenerate,
|
let fontsNames = FontsToolHelper.getFontPostScriptName(for: fontsToGenerate,
|
||||||
inputFolder: inputFolder)
|
inputFolder: inputFolder)
|
||||||
|
|
||||||
// Generate extension
|
// Generate extension
|
||||||
@ -77,9 +77,9 @@ struct FontTool: ParsableCommand {
|
|||||||
|
|
||||||
// Check input file exists
|
// Check input file exists
|
||||||
guard fileManager.fileExists(atPath: options.inputFile) else {
|
guard fileManager.fileExists(atPath: options.inputFile) else {
|
||||||
let error = FontToolError.fileNotExists(options.inputFile)
|
let error = FontsToolError.fileNotExists(options.inputFile)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
FontTool.exit(withError: error)
|
Fonts.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if needed to regenerate
|
// Check if needed to regenerate
|
||||||
@ -91,5 +91,3 @@ struct FontTool: ParsableCommand {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FontTool.main()
|
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// FontToolError.swift
|
// FontsToolError.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 13/12/2021.
|
// Created by Thibaut Schmitt on 13/12/2021.
|
||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum FontToolError: Error {
|
enum FontsToolError: Error {
|
||||||
case fcScan(String, Int32, String?)
|
case fcScan(String, Int32, String?)
|
||||||
case inputFolderNotFound(String)
|
case inputFolderNotFound(String)
|
||||||
case fileNotExists(String)
|
case fileNotExists(String)
|
||||||
@ -16,16 +16,16 @@ enum FontToolError: Error {
|
|||||||
var localizedDescription: String {
|
var localizedDescription: String {
|
||||||
switch self {
|
switch self {
|
||||||
case .fcScan(let path, let code, let output):
|
case .fcScan(let path, let code, let output):
|
||||||
return "error:[\(FontTool.toolName)] Error while getting fontName (fc-scan --format %{postscriptname} \(path). fc-scan exit with \(code) and output is: \(output ?? "no output")"
|
return "error:[\(Fonts.toolName)] Error while getting fontName (fc-scan --format %{postscriptname} \(path). fc-scan exit with \(code) and output is: \(output ?? "no output")"
|
||||||
|
|
||||||
case .inputFolderNotFound(let inputFolder):
|
case .inputFolderNotFound(let inputFolder):
|
||||||
return " error:[\(FontTool.toolName)] Input folder not found: \(inputFolder)"
|
return " error:[\(Fonts.toolName)] Input folder not found: \(inputFolder)"
|
||||||
|
|
||||||
case .fileNotExists(let filename):
|
case .fileNotExists(let filename):
|
||||||
return " error:[\(FontTool.toolName)] File \(filename) does not exists"
|
return " error:[\(Fonts.toolName)] File \(filename) does not exists"
|
||||||
|
|
||||||
case .writeExtension(let filename, let info):
|
case .writeExtension(let filename, let info):
|
||||||
return "error:[\(FontTool.toolName)] An error occured while writing extension in \(filename): \(info)"
|
return "error:[\(Fonts.toolName)] An error occured while writing extension in \(filename): \(info)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// FontToolHelper.swift
|
// FontsToolHelper.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 13/12/2021.
|
// Created by Thibaut Schmitt on 13/12/2021.
|
||||||
@ -8,7 +8,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import ToolCore
|
import ToolCore
|
||||||
|
|
||||||
class FontToolHelper {
|
class FontsToolHelper {
|
||||||
|
|
||||||
static func getFontPostScriptName(for fonts: [String], inputFolder: String) -> [FontName] {
|
static func getFontPostScriptName(for fonts: [String], inputFolder: String) -> [FontName] {
|
||||||
let fontsFilenames = Self.getFontsFilenames(fromInputFolder: inputFolder)
|
let fontsFilenames = Self.getFontsFilenames(fromInputFolder: inputFolder)
|
||||||
@ -38,9 +38,9 @@ class FontToolHelper {
|
|||||||
// Get a enumerator for all files
|
// Get a enumerator for all files
|
||||||
let fileManager = FileManager()
|
let fileManager = FileManager()
|
||||||
guard fileManager.fileExists(atPath: inputFolder) else {
|
guard fileManager.fileExists(atPath: inputFolder) else {
|
||||||
let error = FontToolError.inputFolderNotFound(inputFolder)
|
let error = FontsToolError.inputFolderNotFound(inputFolder)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
FontTool.exit(withError: error)
|
Fonts.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
let enumerator: FileManager.DirectoryEnumerator = fileManager.enumerator(atPath: inputFolder)!
|
let enumerator: FileManager.DirectoryEnumerator = fileManager.enumerator(atPath: inputFolder)!
|
||||||
@ -63,9 +63,9 @@ class FontToolHelper {
|
|||||||
let task = Shell.shell("fc-scan", "--format", "%{postscriptname}", path)
|
let task = Shell.shell("fc-scan", "--format", "%{postscriptname}", path)
|
||||||
|
|
||||||
guard let fontName = task.output, task.terminationStatus == 0 else {
|
guard let fontName = task.output, task.terminationStatus == 0 else {
|
||||||
let error = FontToolError.fcScan(path, task.terminationStatus, task.output)
|
let error = FontsToolError.fcScan(path, task.terminationStatus, task.output)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
FontTool.exit(withError: error)
|
Fonts.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fontName
|
return fontName
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// File.swift
|
// FontPlistGenerator.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 29/08/2022.
|
// Created by Thibaut Schmitt on 29/08/2022.
|
@ -31,15 +31,15 @@ class FontExtensionGenerator {
|
|||||||
do {
|
do {
|
||||||
try extensionContent.write(to: extensionFilePathURL, atomically: true, encoding: .utf8)
|
try extensionContent.write(to: extensionFilePathURL, atomically: true, encoding: .utf8)
|
||||||
} catch (let error) {
|
} catch (let error) {
|
||||||
let error = FontToolError.writeExtension(extensionFilePath, error.localizedDescription)
|
let error = FontsToolError.writeExtension(extensionFilePath, error.localizedDescription)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
FontTool.exit(withError: error)
|
Fonts.exit(withError: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getHeader(extensionClassname: String) -> String {
|
private static func getHeader(extensionClassname: String) -> String {
|
||||||
"""
|
"""
|
||||||
// Generated by ResgenSwift.\(FontTool.toolName) \(ResgenSwiftVersion)
|
// Generated by ResgenSwift.\(Fonts.toolName) \(ResgenSwiftVersion)
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@ -48,18 +48,18 @@ class FontExtensionGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static func getFontNameEnum(fontsNames: [String]) -> String {
|
private static func getFontNameEnum(fontsNames: [String]) -> String {
|
||||||
var enumDefinition = "\tenum FontName: String {\n"
|
var enumDefinition = " enum FontName: String {\n"
|
||||||
|
|
||||||
fontsNames.forEach {
|
fontsNames.forEach {
|
||||||
enumDefinition += "\t\tcase \($0.removeCharacters(from: "[]+-_")) = \"\($0)\"\n"
|
enumDefinition += " case \($0.removeCharacters(from: "[]+-_")) = \"\($0)\"\n"
|
||||||
}
|
}
|
||||||
enumDefinition += "\t}\n"
|
enumDefinition += " }\n"
|
||||||
|
|
||||||
return enumDefinition
|
return enumDefinition
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getFontMethods(fontsNames: [FontName], staticVar: Bool) -> String {
|
private static func getFontMethods(fontsNames: [FontName], staticVar: Bool) -> String {
|
||||||
let pragma = "\t// MARK: - Getter"
|
let pragma = " // MARK: - Getter"
|
||||||
|
|
||||||
var propertiesOrMethods: [String] = fontsNames
|
var propertiesOrMethods: [String] = fontsNames
|
||||||
.unique()
|
.unique()
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// File.swift
|
// FontName.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 29/08/2022.
|
// Created by Thibaut Schmitt on 29/08/2022.
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// File.swift
|
// FontFileParser.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 29/08/2022.
|
// Created by Thibaut Schmitt on 29/08/2022.
|
51
Sources/ResgenSwift/Generate/Generate.swift
Normal file
51
Sources/ResgenSwift/Generate/Generate.swift
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
//
|
||||||
|
// Generate.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ToolCore
|
||||||
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
|
struct Generate: ParsableCommand {
|
||||||
|
|
||||||
|
// MARK: - CommandConfiguration
|
||||||
|
|
||||||
|
static var configuration = CommandConfiguration(
|
||||||
|
abstract: "A utility to generate ressources based on a configuration file",
|
||||||
|
version: ResgenSwiftVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
// MARK: - Static
|
||||||
|
|
||||||
|
static let toolName = "Generate"
|
||||||
|
|
||||||
|
// MARK: - Command Options
|
||||||
|
|
||||||
|
@OptionGroup var options: GenerateOptions
|
||||||
|
|
||||||
|
// MARK: - Run
|
||||||
|
|
||||||
|
public func run() throws {
|
||||||
|
print("[\(Self.toolName)] Starting Resgen with configuration: \(options.configurationFile)")
|
||||||
|
|
||||||
|
// Parse
|
||||||
|
let configuration = ConfigurationFileParser.parse(options.configurationFile)
|
||||||
|
print("Found configurations :")
|
||||||
|
print(" - \(configuration.colors.count) colors configuration")
|
||||||
|
print(" - \(configuration.fonts.count) fonts configuration")
|
||||||
|
print(" - \(configuration.images.count) images configuration")
|
||||||
|
print(" - \(configuration.strings.count) strings configuration")
|
||||||
|
print(" - \(configuration.tags.count) tags configuration")
|
||||||
|
print()
|
||||||
|
// Execute commands
|
||||||
|
configuration.runnableConfigurations
|
||||||
|
.forEach {
|
||||||
|
$0.run(force: options.forceGeneration)
|
||||||
|
}
|
||||||
|
|
||||||
|
print("[\(Self.toolName)] Resgen ended")
|
||||||
|
}
|
||||||
|
}
|
30
Sources/ResgenSwift/Generate/GenerateError.swift
Normal file
30
Sources/ResgenSwift/Generate/GenerateError.swift
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// ResgenSwiftError.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum GenerateError: Error {
|
||||||
|
case fileNotExists(String)
|
||||||
|
case invalidConfigurationFile(String)
|
||||||
|
case commandError([String], String)
|
||||||
|
|
||||||
|
var localizedDescription: String {
|
||||||
|
switch self {
|
||||||
|
case .fileNotExists(let filename):
|
||||||
|
return " error:[\(Generate.toolName)] File \(filename) does not exists"
|
||||||
|
|
||||||
|
case .invalidConfigurationFile(let filename):
|
||||||
|
return " error:[\(Generate.toolName)] File \(filename) is not a valid configuration file"
|
||||||
|
|
||||||
|
case .commandError(let command, let terminationStatus):
|
||||||
|
let readableCommand = command
|
||||||
|
.map { $0 }
|
||||||
|
.joined(separator: " ")
|
||||||
|
return "error:[\(Generate.toolName)] An error occured while running command '\(readableCommand)'. Command terminate with status code: \(terminationStatus)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
Sources/ResgenSwift/Generate/GenerateOptions.swift
Normal file
19
Sources/ResgenSwift/Generate/GenerateOptions.swift
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// GenerateOptions.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
|
struct GenerateOptions: ParsableArguments {
|
||||||
|
@Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation")
|
||||||
|
var forceGeneration = false
|
||||||
|
|
||||||
|
@Argument(help: "Configuration file.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
||||||
|
var configurationFile: String
|
||||||
|
}
|
140
Sources/ResgenSwift/Generate/Model/ConfigurationFile.swift
Normal file
140
Sources/ResgenSwift/Generate/Model/ConfigurationFile.swift
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
//
|
||||||
|
// ConfigurationFile.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct ConfigurationFile: Codable, CustomDebugStringConvertible {
|
||||||
|
var colors: [ColorsConfiguration]
|
||||||
|
var fonts: [FontsConfiguration]
|
||||||
|
var images: [ImagesConfiguration]
|
||||||
|
var strings: [StringsConfiguration]
|
||||||
|
var tags: [TagsConfiguration]
|
||||||
|
|
||||||
|
var runnableConfigurations: [Runnable] {
|
||||||
|
let runnables: [[Runnable]] = [colors, fonts, images, strings, tags]
|
||||||
|
return Array(runnables.joined())
|
||||||
|
}
|
||||||
|
|
||||||
|
var debugDescription: String {
|
||||||
|
"""
|
||||||
|
\(colors)
|
||||||
|
-----------
|
||||||
|
-----------
|
||||||
|
\(fonts)
|
||||||
|
-----------
|
||||||
|
-----------
|
||||||
|
\(images)
|
||||||
|
-----------
|
||||||
|
-----------
|
||||||
|
\(strings)
|
||||||
|
-----------
|
||||||
|
-----------
|
||||||
|
\(tags)
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ColorsConfiguration: Codable, CustomDebugStringConvertible {
|
||||||
|
let inputFile: String
|
||||||
|
let style: String
|
||||||
|
let xcassetsPath: String
|
||||||
|
let extensionOutputPath: String
|
||||||
|
let extensionName: String?
|
||||||
|
let extensionSuffix: String?
|
||||||
|
|
||||||
|
var debugDescription: String {
|
||||||
|
"""
|
||||||
|
Colors configuration:
|
||||||
|
- Input file: \(inputFile)
|
||||||
|
- Style: \(style)
|
||||||
|
- Xcassets path: \(xcassetsPath)
|
||||||
|
- Extension output path: \(extensionOutputPath)
|
||||||
|
- Extension name: \(extensionName ?? "-")
|
||||||
|
- Extension suffix: \(extensionSuffix ?? "-")
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FontsConfiguration: Codable, CustomDebugStringConvertible {
|
||||||
|
let inputFile: String
|
||||||
|
let extensionOutputPath: String
|
||||||
|
let extensionName: String?
|
||||||
|
let extensionSuffix: String?
|
||||||
|
|
||||||
|
var debugDescription: String {
|
||||||
|
"""
|
||||||
|
Fonts configuration:
|
||||||
|
- Input file: \(inputFile)
|
||||||
|
- Extension output path: \(extensionOutputPath)
|
||||||
|
- Extension name: \(extensionName ?? "-")
|
||||||
|
- Extension suffix: \(extensionSuffix ?? "-")
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ImagesConfiguration: Codable, CustomDebugStringConvertible {
|
||||||
|
let inputFile: String
|
||||||
|
let xcassetsPath: String
|
||||||
|
let extensionOutputPath: String
|
||||||
|
let extensionName: String?
|
||||||
|
let extensionSuffix: String?
|
||||||
|
|
||||||
|
var debugDescription: String {
|
||||||
|
"""
|
||||||
|
Images configuration:
|
||||||
|
- Input file: \(inputFile)
|
||||||
|
- Xcassets path: \(xcassetsPath)
|
||||||
|
- Extension output path: \(extensionOutputPath)
|
||||||
|
- Extension name: \(extensionName ?? "-")
|
||||||
|
- Extension suffix: \(extensionSuffix ?? "-")
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StringsConfiguration: Codable, CustomDebugStringConvertible {
|
||||||
|
let inputFile: String
|
||||||
|
let outputPath: String
|
||||||
|
let langs: String
|
||||||
|
let defaultLang: String
|
||||||
|
let extensionOutputPath: String
|
||||||
|
let extensionName: String?
|
||||||
|
let extensionSuffix: String?
|
||||||
|
|
||||||
|
var debugDescription: String {
|
||||||
|
"""
|
||||||
|
Strings configuration:
|
||||||
|
- Input file: \(inputFile)
|
||||||
|
- Output path: \(outputPath)
|
||||||
|
- Langs: \(langs)
|
||||||
|
- Default lang: \(defaultLang)
|
||||||
|
- Extension output path: \(extensionOutputPath)
|
||||||
|
- Extension name: \(extensionName ?? "-")
|
||||||
|
- Extension suffix: \(extensionSuffix ?? "-")
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TagsConfiguration: Codable, CustomDebugStringConvertible {
|
||||||
|
let inputFile: String
|
||||||
|
let lang: String
|
||||||
|
let extensionOutputPath: String
|
||||||
|
let extensionName: String?
|
||||||
|
let extensionSuffix: String?
|
||||||
|
|
||||||
|
var debugDescription: String {
|
||||||
|
"""
|
||||||
|
Tags configuration:
|
||||||
|
- Input file: \(inputFile)
|
||||||
|
- Lang: \(lang)
|
||||||
|
- Extension output path: \(extensionOutputPath)
|
||||||
|
- Extension name: \(extensionName ?? "-")
|
||||||
|
- Extension suffix: \(extensionSuffix ?? "-")
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// ConfigurationFileParser.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Yams
|
||||||
|
|
||||||
|
class ConfigurationFileParser {
|
||||||
|
static func parse(_ configurationFile: String) -> ConfigurationFile {
|
||||||
|
guard let data = FileManager().contents(atPath: configurationFile) else {
|
||||||
|
let error = GenerateError.fileNotExists(configurationFile)
|
||||||
|
print(error.localizedDescription)
|
||||||
|
Generate.exit(withError: error)
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let configuration = try? YAMLDecoder().decode(ConfigurationFile.self, from: data) else {
|
||||||
|
let error = GenerateError.invalidConfigurationFile(configurationFile)
|
||||||
|
print(error.localizedDescription)
|
||||||
|
Generate.exit(withError: error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return configuration
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// ColorsConfiguration+ShellCommandable.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension ColorsConfiguration: Runnable {
|
||||||
|
func run(force: Bool) {
|
||||||
|
var args = [String]()
|
||||||
|
|
||||||
|
if force {
|
||||||
|
args += ["-f"]
|
||||||
|
}
|
||||||
|
|
||||||
|
args += [
|
||||||
|
inputFile,
|
||||||
|
"--style",
|
||||||
|
style,
|
||||||
|
"--xcassets-path",
|
||||||
|
xcassetsPath,
|
||||||
|
"--extension-output-path",
|
||||||
|
extensionOutputPath
|
||||||
|
]
|
||||||
|
|
||||||
|
if let extensionName = extensionName {
|
||||||
|
args += [
|
||||||
|
"--extension-name",
|
||||||
|
extensionName
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if let extensionSuffix = extensionSuffix {
|
||||||
|
args += [
|
||||||
|
"--extension-suffix",
|
||||||
|
extensionSuffix
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Colors.main(args)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// FontsConfiguration+ShellCommandable.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension FontsConfiguration: Runnable {
|
||||||
|
func run(force: Bool) {
|
||||||
|
var args = [String]()
|
||||||
|
|
||||||
|
if force {
|
||||||
|
args += ["-f"]
|
||||||
|
}
|
||||||
|
|
||||||
|
args += [
|
||||||
|
inputFile,
|
||||||
|
"--extension-output-path",
|
||||||
|
extensionOutputPath
|
||||||
|
]
|
||||||
|
|
||||||
|
if let extensionName = extensionName {
|
||||||
|
args += [
|
||||||
|
"--extension-name",
|
||||||
|
extensionName
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if let extensionSuffix = extensionSuffix {
|
||||||
|
args += [
|
||||||
|
"--extension-suffix",
|
||||||
|
extensionSuffix
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Fonts.main(args)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// ImagesConfiguration+ShellCommandable.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension ImagesConfiguration: Runnable {
|
||||||
|
func run(force: Bool) {
|
||||||
|
var args = [String]()
|
||||||
|
|
||||||
|
if force {
|
||||||
|
args += ["-f"]
|
||||||
|
}
|
||||||
|
|
||||||
|
args += [
|
||||||
|
inputFile,
|
||||||
|
"--xcassets-path",
|
||||||
|
xcassetsPath,
|
||||||
|
"--extension-output-path",
|
||||||
|
extensionOutputPath
|
||||||
|
]
|
||||||
|
|
||||||
|
if let extensionName = extensionName {
|
||||||
|
args += [
|
||||||
|
"--extension-name",
|
||||||
|
extensionName
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if let extensionSuffix = extensionSuffix {
|
||||||
|
args += [
|
||||||
|
"--extension-suffix",
|
||||||
|
extensionSuffix
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Images.main(args)
|
||||||
|
}
|
||||||
|
}
|
13
Sources/ResgenSwift/Generate/ShellCommandable/Runnable.swift
Normal file
13
Sources/ResgenSwift/Generate/ShellCommandable/Runnable.swift
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// ShellCommandable.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
protocol Runnable {
|
||||||
|
func run(force: Bool)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// StringsConfiguration+ShellCommandable.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension StringsConfiguration: Runnable {
|
||||||
|
func run(force: Bool) {
|
||||||
|
var args = [String]()
|
||||||
|
|
||||||
|
if force {
|
||||||
|
args += ["-f"]
|
||||||
|
}
|
||||||
|
|
||||||
|
args += [
|
||||||
|
inputFile,
|
||||||
|
"--output-path",
|
||||||
|
outputPath,
|
||||||
|
"--langs",
|
||||||
|
langs,
|
||||||
|
"--default-lang",
|
||||||
|
defaultLang,
|
||||||
|
"--extension-output-path",
|
||||||
|
extensionOutputPath
|
||||||
|
]
|
||||||
|
|
||||||
|
if let extensionName = extensionName {
|
||||||
|
args += [
|
||||||
|
"--extension-name",
|
||||||
|
extensionName
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if let extensionSuffix = extensionSuffix {
|
||||||
|
args += [
|
||||||
|
"--extension-suffix",
|
||||||
|
extensionSuffix
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Stringium.main(args)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// TagsConfiguration+ShellCommandable.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 30/08/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension TagsConfiguration: Runnable {
|
||||||
|
func run(force: Bool) {
|
||||||
|
var args = [String]()
|
||||||
|
|
||||||
|
if force {
|
||||||
|
args += ["-f"]
|
||||||
|
}
|
||||||
|
|
||||||
|
args += [
|
||||||
|
inputFile,
|
||||||
|
"--lang",
|
||||||
|
lang,
|
||||||
|
"--extension-output-path",
|
||||||
|
extensionOutputPath
|
||||||
|
]
|
||||||
|
|
||||||
|
if let extensionName = extensionName {
|
||||||
|
args += [
|
||||||
|
"--extension-name",
|
||||||
|
extensionName
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if let extensionSuffix = extensionSuffix {
|
||||||
|
args += [
|
||||||
|
"--extension-suffix",
|
||||||
|
extensionSuffix
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Tags.main(args)
|
||||||
|
}
|
||||||
|
}
|
@ -11,9 +11,9 @@ extension FileManager {
|
|||||||
func getAllRegularFileIn(directory: String) -> [String] {
|
func getAllRegularFileIn(directory: String) -> [String] {
|
||||||
var files = [String]()
|
var files = [String]()
|
||||||
guard let enumerator = self.enumerator(at: URL(string: directory)!, includingPropertiesForKeys: [.isRegularFileKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) else {
|
guard let enumerator = self.enumerator(at: URL(string: directory)!, includingPropertiesForKeys: [.isRegularFileKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) else {
|
||||||
let error = ImagiumError.unknown("Cannot enumerate file in \(directory)")
|
let error = ImagesError.unknown("Cannot enumerate file in \(directory)")
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
Imagium.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
for case let fileURL as URL in enumerator {
|
for case let fileURL as URL in enumerator {
|
||||||
@ -23,9 +23,9 @@ extension FileManager {
|
|||||||
files.append(fileURL.relativePath)
|
files.append(fileURL.relativePath)
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
let error = ImagiumError.getFileAttributed(fileURL.relativePath, error.localizedDescription)
|
let error = ImagesError.getFileAttributed(fileURL.relativePath, error.localizedDescription)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
Imagium.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return files
|
return files
|
||||||
@ -34,9 +34,9 @@ extension FileManager {
|
|||||||
func getAllImageSetFolderIn(directory: String) -> [String] {
|
func getAllImageSetFolderIn(directory: String) -> [String] {
|
||||||
var files = [String]()
|
var files = [String]()
|
||||||
guard let enumerator = self.enumerator(at: URL(string: directory)!, includingPropertiesForKeys: [.isDirectoryKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) else {
|
guard let enumerator = self.enumerator(at: URL(string: directory)!, includingPropertiesForKeys: [.isDirectoryKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) else {
|
||||||
let error = ImagiumError.unknown("Cannot enumerate imageset directory in \(directory)")
|
let error = ImagesError.unknown("Cannot enumerate imageset directory in \(directory)")
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
Imagium.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
for case let fileURL as URL in enumerator {
|
for case let fileURL as URL in enumerator {
|
||||||
@ -46,9 +46,9 @@ extension FileManager {
|
|||||||
files.append(fileURL.lastPathComponent)
|
files.append(fileURL.lastPathComponent)
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
let error = ImagiumError.getFileAttributed(fileURL.relativePath, error.localizedDescription)
|
let error = ImagesError.getFileAttributed(fileURL.relativePath, error.localizedDescription)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
Imagium.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return files
|
return files
|
@ -58,9 +58,9 @@ class ImageExtensionGenerator {
|
|||||||
do {
|
do {
|
||||||
try extensionContent.write(to: extensionFilePathURL, atomically: true, encoding: .utf8)
|
try extensionContent.write(to: extensionFilePathURL, atomically: true, encoding: .utf8)
|
||||||
} catch (let error) {
|
} catch (let error) {
|
||||||
let error = ImagiumError.writeFile(extensionFilePath, error.localizedDescription)
|
let error = ImagesError.writeFile(extensionFilePath, error.localizedDescription)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
Imagium.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// File.swift
|
// XcassetsGenerator.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 24/01/2022.
|
// Created by Thibaut Schmitt on 24/01/2022.
|
||||||
@ -24,7 +24,7 @@ class XcassetsGenerator {
|
|||||||
|
|
||||||
func generateXcassets(inputPath: String, imagesToGenerate: [ParsedImage], xcassetsPath: String) {
|
func generateXcassets(inputPath: String, imagesToGenerate: [ParsedImage], xcassetsPath: String) {
|
||||||
let fileManager = FileManager()
|
let fileManager = FileManager()
|
||||||
let svgConverter = Imagium.getSvgConverterPath()
|
let svgConverter = Images.getSvgConverterPath()
|
||||||
let allSubFiles = fileManager.getAllRegularFileIn(directory: inputPath)
|
let allSubFiles = fileManager.getAllRegularFileIn(directory: inputPath)
|
||||||
|
|
||||||
var generatedAssetsPaths = [String]()
|
var generatedAssetsPaths = [String]()
|
||||||
@ -47,9 +47,9 @@ class XcassetsGenerator {
|
|||||||
return (subfile, "jepg")
|
return (subfile, "jepg")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let error = ImagiumError.unknownImageExtension(parsedImage.name)
|
let error = ImagesError.unknownImageExtension(parsedImage.name)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
Imagium.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Create imageset folder
|
// Create imageset folder
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Imagium.swift
|
// Images.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 24/01/2022.
|
// Created by Thibaut Schmitt on 24/01/2022.
|
||||||
@ -9,7 +9,7 @@ import ToolCore
|
|||||||
import Foundation
|
import Foundation
|
||||||
import ArgumentParser
|
import ArgumentParser
|
||||||
|
|
||||||
struct Imagium: ParsableCommand {
|
struct Images: ParsableCommand {
|
||||||
|
|
||||||
// MARK: - CommandConfiguration
|
// MARK: - CommandConfiguration
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ struct Imagium: ParsableCommand {
|
|||||||
|
|
||||||
// MARK: - Static
|
// MARK: - Static
|
||||||
|
|
||||||
static let toolName = "Imagium"
|
static let toolName = "Images"
|
||||||
static let defaultExtensionName = "UIImage"
|
static let defaultExtensionName = "UIImage"
|
||||||
|
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
@ -35,7 +35,7 @@ struct Imagium: ParsableCommand {
|
|||||||
|
|
||||||
// MARK: - Command Options
|
// MARK: - Command Options
|
||||||
|
|
||||||
@OptionGroup var options: ImagiumOptions
|
@OptionGroup var options: ImagesOptions
|
||||||
|
|
||||||
// MARK: - Run
|
// MARK: - Run
|
||||||
|
|
||||||
@ -81,13 +81,13 @@ struct Imagium: ParsableCommand {
|
|||||||
|
|
||||||
// Input file
|
// Input file
|
||||||
guard fileManager.fileExists(atPath: options.inputFile) else {
|
guard fileManager.fileExists(atPath: options.inputFile) else {
|
||||||
let error = ImagiumError.fileNotExists(options.inputFile)
|
let error = ImagesError.fileNotExists(options.inputFile)
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
Imagium.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RSVG-Converter
|
// RSVG-Converter
|
||||||
_ = Imagium.getSvgConverterPath()
|
_ = Images.getSvgConverterPath()
|
||||||
|
|
||||||
// Check if needed to regenerate
|
// Check if needed to regenerate
|
||||||
guard GeneratorChecker.shouldGenerate(force: options.forceExecution, inputFilePath: options.inputFile, extensionFilePath: extensionFilePath) else {
|
guard GeneratorChecker.shouldGenerate(force: options.forceExecution, inputFilePath: options.inputFile, extensionFilePath: extensionFilePath) else {
|
||||||
@ -107,10 +107,8 @@ struct Imagium: ParsableCommand {
|
|||||||
return taskSvgConverter.output!.removeCharacters(from: CharacterSet.whitespacesAndNewlines)
|
return taskSvgConverter.output!.removeCharacters(from: CharacterSet.whitespacesAndNewlines)
|
||||||
}
|
}
|
||||||
|
|
||||||
let error = ImagiumError.rsvgConvertNotFound
|
let error = ImagesError.rsvgConvertNotFound
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
Imagium.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Imagium.main()
|
|
43
Sources/ResgenSwift/Images/ImagesError.swift
Normal file
43
Sources/ResgenSwift/Images/ImagesError.swift
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// ImagesError.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 24/01/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum ImagesError: Error {
|
||||||
|
case inputFolderNotFound(String)
|
||||||
|
case fileNotExists(String)
|
||||||
|
case unknownImageExtension(String)
|
||||||
|
case getFileAttributed(String, String)
|
||||||
|
case rsvgConvertNotFound
|
||||||
|
case writeFile(String, String)
|
||||||
|
case unknown(String)
|
||||||
|
|
||||||
|
var localizedDescription: String {
|
||||||
|
switch self {
|
||||||
|
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):
|
||||||
|
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 imagemagick --with-librsvg')"
|
||||||
|
|
||||||
|
case .writeFile(let subErrorDescription, let filename):
|
||||||
|
return " error:[\(Images.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)"
|
||||||
|
|
||||||
|
case .unknown(let errorDescription):
|
||||||
|
return " error:[\(Images.toolName)] Unknown error: \(errorDescription)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import ArgumentParser
|
import ArgumentParser
|
||||||
|
|
||||||
struct ImagiumOptions: ParsableArguments {
|
struct ImagesOptions: ParsableArguments {
|
||||||
@Flag(name: .customShort("f"), help: "Should force script execution")
|
@Flag(name: .customShort("f"), help: "Should force script execution")
|
||||||
var forceExecution = false
|
var forceExecution = false
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ struct ImagiumOptions: ParsableArguments {
|
|||||||
var extensionOutputPath: String
|
var extensionOutputPath: String
|
||||||
|
|
||||||
@Option(help: "Extension name. If not specified, it will generate an UIImage extension. Using default extension name will generate static property.")
|
@Option(help: "Extension name. If not specified, it will generate an UIImage extension. Using default extension name will generate static property.")
|
||||||
var extensionName: String = Imagium.defaultExtensionName
|
var extensionName: String = Images.defaultExtensionName
|
||||||
|
|
||||||
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+Image{extensionSuffix}.swift")
|
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+Image{extensionSuffix}.swift")
|
||||||
var extensionSuffix: String = ""
|
var extensionSuffix: String = ""
|
@ -11,7 +11,7 @@ import CoreVideo
|
|||||||
|
|
||||||
class TagsGenerator {
|
class TagsGenerator {
|
||||||
static func writeExtensionFiles(sections: [Section], lang: String, tags: [String], staticVar: Bool, extensionName: String, extensionFilePath: String) {
|
static func writeExtensionFiles(sections: [Section], lang: String, tags: [String], staticVar: Bool, extensionName: String, extensionFilePath: String) {
|
||||||
let extensionHeader = Self.getHeader(extensionClassname: extensionName)
|
let extensionHeader = Self.getHeader(extensionClassname: extensionName, staticVar: staticVar)
|
||||||
let extensionFooter = Self.getFooter()
|
let extensionFooter = Self.getFooter()
|
||||||
|
|
||||||
let extensionContent: String = {
|
let extensionContent: String = {
|
||||||
@ -22,7 +22,7 @@ class TagsGenerator {
|
|||||||
return // Go to next section
|
return // Go to next section
|
||||||
}
|
}
|
||||||
|
|
||||||
content += "\n\t// MARK: - \(section.name)"
|
content += "\n // MARK: - \(section.name)"
|
||||||
section.definitions.forEach { definition in
|
section.definitions.forEach { definition in
|
||||||
if staticVar {
|
if staticVar {
|
||||||
content += "\n\n\(definition.getStaticProperty(forLang: lang))"
|
content += "\n\n\(definition.getStaticProperty(forLang: lang))"
|
||||||
@ -55,21 +55,19 @@ class TagsGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getHeader(extensionClassname: String) -> String {
|
private static func getHeader(extensionClassname: String, staticVar: Bool) -> String {
|
||||||
"""
|
"""
|
||||||
// Generated by ResgenSwift.Strings.Tags \(ResgenSwiftVersion)
|
// Generated by ResgenSwift.Strings.Tags \(ResgenSwiftVersion)
|
||||||
|
|
||||||
// typelias Tags = String
|
\(staticVar ? "typelias Tags = String\n\n" : "")import UIKit
|
||||||
|
|
||||||
import UIKit
|
extension \(extensionClassname) {
|
||||||
|
"""
|
||||||
extension \(extensionClassname) {
|
|
||||||
"""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getFooter() -> String {
|
private static func getFooter() -> String {
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -27,8 +27,8 @@ struct Stringium: ParsableCommand {
|
|||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
|
|
||||||
var extensionFileName: String {
|
var extensionFileName: String {
|
||||||
if options.extensionSuffix.isEmpty == false {
|
if let extensionSuffix = options.extensionSuffix {
|
||||||
return "\(options.extensionName)+\(options.extensionSuffix).swift"
|
return "\(options.extensionName)+\(extensionSuffix).swift"
|
||||||
}
|
}
|
||||||
return "\(options.extensionName).swift"
|
return "\(options.extensionName).swift"
|
||||||
}
|
}
|
||||||
@ -47,8 +47,6 @@ struct Stringium: ParsableCommand {
|
|||||||
|
|
||||||
// MARK: - Command options
|
// MARK: - Command options
|
||||||
|
|
||||||
// The `@OptionGroup` attribute includes the flags, options, and
|
|
||||||
// arguments defined by another `ParsableArguments` type.
|
|
||||||
@OptionGroup var options: StringiumOptions
|
@OptionGroup var options: StringiumOptions
|
||||||
|
|
||||||
// MARK: - Run
|
// MARK: - Run
|
@ -34,7 +34,7 @@ struct StringiumOptions: ParsableArguments {
|
|||||||
var extensionName: String = Stringium.defaultExtensionName
|
var extensionName: String = Stringium.defaultExtensionName
|
||||||
|
|
||||||
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+{extensionSuffix}.swift")
|
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+{extensionSuffix}.swift")
|
||||||
var extensionSuffix: String = ""
|
var extensionSuffix: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
extension StringiumOptions {
|
extension StringiumOptions {
|
@ -26,5 +26,5 @@ struct Strings: ParsableCommand {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Strings.main()
|
//Strings.main()
|
||||||
|
|
@ -28,8 +28,8 @@ struct Tags: ParsableCommand {
|
|||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
|
|
||||||
var extensionFileName: String {
|
var extensionFileName: String {
|
||||||
if options.extensionSuffix.isEmpty == false {
|
if let extensionSuffix = options.extensionSuffix {
|
||||||
return "\(options.extensionName)+\(options.extensionSuffix).swift"
|
return "\(options.extensionName)+\(extensionSuffix).swift"
|
||||||
}
|
}
|
||||||
return "\(options.extensionName).swift"
|
return "\(options.extensionName).swift"
|
||||||
}
|
}
|
||||||
@ -40,8 +40,6 @@ struct Tags: ParsableCommand {
|
|||||||
|
|
||||||
// MARK: - Command Options
|
// MARK: - Command Options
|
||||||
|
|
||||||
// The `@OptionGroup` attribute includes the flags, options, and
|
|
||||||
// arguments defined by another `ParsableArguments` type.
|
|
||||||
@OptionGroup var options: TagsOptions
|
@OptionGroup var options: TagsOptions
|
||||||
|
|
||||||
// MARK: - Run
|
// MARK: - Run
|
@ -25,5 +25,5 @@ struct TagsOptions: ParsableArguments {
|
|||||||
var extensionName: String = Tags.defaultExtensionName
|
var extensionName: String = Tags.defaultExtensionName
|
||||||
|
|
||||||
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+Tag{extensionSuffix}.swift")
|
@Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+Tag{extensionSuffix}.swift")
|
||||||
var extensionSuffix: String = ""
|
var extensionSuffix: String?
|
||||||
}
|
}
|
@ -33,8 +33,6 @@ struct Twine: ParsableCommand {
|
|||||||
|
|
||||||
// MARK: - Command Options
|
// MARK: - Command Options
|
||||||
|
|
||||||
// The `@OptionGroup` attribute includes the flags, options, and
|
|
||||||
// arguments defined by another `ParsableArguments` type.
|
|
||||||
@OptionGroup var options: TwineOptions
|
@OptionGroup var options: TwineOptions
|
||||||
|
|
||||||
// MARK: - Run
|
// MARK: - Run
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// File.swift
|
// TwineOptions.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Thibaut Schmitt on 10/01/2022.
|
// Created by Thibaut Schmitt on 10/01/2022.
|
@ -1 +1,35 @@
|
|||||||
print("Welcome ResgenSwift")
|
//
|
||||||
|
// ResgenSwift.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Thibaut Schmitt on 13/12/2021.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ToolCore
|
||||||
|
import Foundation
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
|
struct ResgenSwift: ParsableCommand {
|
||||||
|
|
||||||
|
static var configuration = CommandConfiguration(
|
||||||
|
abstract: "A utility for generate ressources.",
|
||||||
|
version: ResgenSwiftVersion,
|
||||||
|
|
||||||
|
// Pass an array to `subcommands` to set up a nested tree of subcommands.
|
||||||
|
// With language support for type-level introspection, this could be
|
||||||
|
// provided by automatically finding nested `ParsableCommand` types.
|
||||||
|
subcommands: [
|
||||||
|
Colors.self,
|
||||||
|
Fonts.self,
|
||||||
|
Images.self,
|
||||||
|
Strings.self,
|
||||||
|
Generate.self
|
||||||
|
]
|
||||||
|
|
||||||
|
// A default subcommand, when provided, is automatically selected if a
|
||||||
|
// subcommand is not given on the command line.
|
||||||
|
//defaultSubcommand: Twine.self
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ResgenSwift.main()
|
||||||
|
@ -10,14 +10,14 @@ import Foundation
|
|||||||
public class Shell {
|
public class Shell {
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
public static func shell(_ args: String...) -> (terminationStatus: Int32, output: String?) {
|
public static func shell(launchPath: String = "/usr/bin/env", _ args: String...) -> (terminationStatus: Int32, output: String?) {
|
||||||
let task = Process()
|
let task = Process()
|
||||||
task.launchPath = "/usr/bin/env"
|
task.launchPath = launchPath
|
||||||
task.arguments = args
|
task.arguments = args
|
||||||
|
|
||||||
let pipe = Pipe()
|
let pipe = Pipe()
|
||||||
task.standardOutput = pipe
|
task.standardOutput = pipe
|
||||||
task.launch()
|
try? task.run()
|
||||||
task.waitUntilExit()
|
task.waitUntilExit()
|
||||||
|
|
||||||
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
||||||
@ -30,9 +30,9 @@ public class Shell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
public static func shell(_ args: [String]) -> (terminationStatus: Int32, output: String?) {
|
public static func shell(launchPath: String = "/usr/bin/env", _ args: [String]) -> (terminationStatus: Int32, output: String?) {
|
||||||
let task = Process()
|
let task = Process()
|
||||||
task.launchPath = "/usr/bin/env"
|
task.launchPath = launchPath
|
||||||
task.arguments = args
|
task.arguments = args
|
||||||
|
|
||||||
let pipe = Pipe()
|
let pipe = Pipe()
|
||||||
|
Reference in New Issue
Block a user