Add new Flag to every command to choose if we want to generate static members or not
Some checks failed
gitea-openium/resgen.swift/pipeline/head There was a failure building this commit

This commit is contained in:
2022-08-31 15:18:44 +02:00
parent 264c221604
commit 3d60513c08
24 changed files with 323 additions and 144 deletions

140
README.md
View File

@ -4,7 +4,7 @@ ResgenSwift is a package, fully written in Swift, to help you automatize ressour
> 🧐 For all commands, see samples files in `SampleFiles` > 🧐 For all commands, see samples files in `SampleFiles`
# Fonts ## Fonts
Font generator generates an extension of `UIFont` (or a custom class). It also prints `UIAppFonts` to put in your project `.plist`. Font generator generates an extension of `UIFont` (or a custom class). It also prints `UIAppFonts` to put in your project `.plist`.
iOS required to use the **real name** of the font, this name can be different from its filename. To get the **real name**, it uses `fc-scan`. iOS required to use the **real name** of the font, this name can be different from its filename. To get the **real name**, it uses `fc-scan`.
@ -15,7 +15,8 @@ iOS required to use the **real name** of the font, this name can be different fr
swift run -c release FontTool $FORCE_FLAG "./Fonts/fonts.txt" \ swift run -c release FontTool $FORCE_FLAG "./Fonts/fonts.txt" \
--extension-output-path "./Fonts/Generated" \ --extension-output-path "./Fonts/Generated" \
--extension-name "AppFont" \ --extension-name "AppFont" \
--extension-suffix "GreatApp" --extension-suffix "GreatApp" \
--static-members true
``` ```
**Parameters** **Parameters**
@ -25,11 +26,10 @@ swift run -c release FontTool $FORCE_FLAG "./Fonts/fonts.txt" \
3. `--extension-output-path`: path where to generate generated extension 3. `--extension-output-path`: path where to generate generated extension
4. `--extension-name` *(optional)* : name of thee class to add the extension 4. `--extension-name` *(optional)* : name of thee class to add the extension
5. `--extension-suffix` *(optional)* : additional text which is added to the filename (ex: `AppFont+GreatApp.swift`) 5. `--extension-suffix` *(optional)* : additional text which is added to the filename (ex: `AppFont+GreatApp.swift`)
6. `--static-members` *(optional)*: generate static properties or not
> ⚠️ If extension name is not set or is `UIFont`, it will generate static property on `UIFont` instead of method in your custom class.
# Colors ## Colors
Colors generator generates an extension of `UIColor` (or a custom class) along with colorsets in specified xcassets. Colors generator generates an extension of `UIColor` (or a custom class) along with colorsets in specified xcassets.
@ -39,7 +39,8 @@ swift run -c release ColorTool $FORCE_FLAG "./Colors/colors.txt" \
--xcassets-path "./Colors/colors.xcassets" \ --xcassets-path "./Colors/colors.xcassets" \
--extension-output-path "./Colors/Generated/" \ --extension-output-path "./Colors/Generated/" \
--extension-name "AppColor" \ --extension-name "AppColor" \
--extension-suffix "GreatApp" --extension-suffix "GreatApp" \
--static-members true
``` ```
**Parameters** **Parameters**
@ -50,15 +51,14 @@ swift run -c release ColorTool $FORCE_FLAG "./Colors/colors.txt" \
4. `--extension-output-path`: path where to generate generated extension 4. `--extension-output-path`: path where to generate generated extension
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: `AppColor+GreatApp.swift`) 6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppColor+GreatApp.swift`)
7. `--static-members` *(optional)*: generate static properties or not
> ⚠️ If extension name is not set or is `UIColor`, it will generate static property on `UIColor`.
## Strings
# Strings
Strings command allows to generate `strings` files along with extensions to access those strings easily. It can do it 2 ways: Twine and Stringium. It is not recommended to use Twine except on legacy projects or while migrating to ResgenSwift, because it use https://github.com/openium/twine. Using Stringium is recommended because it does not required external dependency and allow more customisation. Strings command allows to generate `strings` files along with extensions to access those strings easily. It can do it 2 ways: Twine and Stringium. It is not recommended to use Twine except on legacy projects or while migrating to ResgenSwift, because it use https://github.com/openium/twine. Using Stringium is recommended because it does not required external dependency and allow more customisation.
## Twine (not recommended) ### Twine (not recommended)
``` ```
swift run -c release Strings twine $FORCE_FLAG "./Twine/strings.txt" \ swift run -c release Strings twine $FORCE_FLAG "./Twine/strings.txt" \
@ -76,7 +76,7 @@ swift run -c release Strings twine $FORCE_FLAG "./Twine/strings.txt" \
4. `--default-lang`: default lang that will be in `Base.lproj`. It must be in `langs` as well 4. `--default-lang`: default lang that will be in `Base.lproj`. It must be in `langs` as well
4. `--extension-output-path`: path where to generate generated extension 4. `--extension-output-path`: path where to generate generated extension
## Stringium (recommended) ### Stringium (recommended)
``` ```
swift run -c release Strings stringium $FORCE_FLAG "./Strings/strings.txt" \ swift run -c release Strings stringium $FORCE_FLAG "./Strings/strings.txt" \
@ -85,7 +85,8 @@ swift run -c release Strings stringium $FORCE_FLAG "./Strings/strings.txt" \
--default-lang "en" \ --default-lang "en" \
--extension-output-path "./Strings/Generated" \ --extension-output-path "./Strings/Generated" \
--extension-name "AppString" \ --extension-name "AppString" \
--extension-suffix "GreatApp" --extension-suffix "GreatApp" \
--static-members true
``` ```
**Parameters** **Parameters**
@ -97,10 +98,10 @@ swift run -c release Strings stringium $FORCE_FLAG "./Strings/strings.txt" \
4. `--extension-output-path`: path where to generate generated extension 4. `--extension-output-path`: path where to generate generated extension
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: `AppString+GreatApp.swift`) 6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppString+GreatApp.swift`)
7. `--static-members` *(optional)*: generate static properties or not
> ⚠️ If extension name is not set or is `String`, it will generate static property on `String`.
# Tags ## Tags
Tags is also a subcommand of `Strings`. Input files are formatted the same way. Tags will generate properties which return exactly what is specified in the input file. It was designed to be used for analytics purpose and to be shared with any other platform to have the same analytics keys. Tags is also a subcommand of `Strings`. Input files are formatted the same way. Tags will generate properties which return exactly what is specified in the input file. It was designed to be used for analytics purpose and to be shared with any other platform to have the same analytics keys.
@ -109,7 +110,8 @@ swift run -c release Strings tags $FORCE_FLAG "./Tags/tags.txt" \
--lang "ium" \ --lang "ium" \
--extension-output-path "./Tags/Generated" \ --extension-output-path "./Tags/Generated" \
--extension-name "AppTags" \ --extension-name "AppTags" \
--extension-suffix "GreatApp" --extension-suffix "GreatApp" \
--static-members true
``` ```
**Parameters** **Parameters**
@ -120,10 +122,11 @@ swift run -c release Strings tags $FORCE_FLAG "./Tags/tags.txt" \
4. `--extension-output-path`: path where to generate generated extension 4. `--extension-output-path`: path where to generate generated extension
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`)
7. `--static-members` *(optional)*: generate static properties or not
> ⚠️ If extension name is not set or is `Tags`, it will generate static property on `Tags`. `Tags` is a typealias of `String`. > ⚠️ If extension name is not set or is `Tags`, it will generate the following typaloas `typealias Tags = String`.
# Images ## Images
Images generator will generate images assets along with extensions to access those images easily. Images generator will generate images assets along with extensions to access those images easily.
@ -132,7 +135,8 @@ swift run -c release Imagium $FORCE_FLAG "./Images/images.txt" \
--xcassets-path "./Images/app.xcassets" \ --xcassets-path "./Images/app.xcassets" \
--extension-output-path "./Images/Generated" \ --extension-output-path "./Images/Generated" \
--extension-name "AppImage" \ --extension-name "AppImage" \
--extension-suffix "GreatApp" --extension-suffix "GreatApp" \
--static-members true
``` ```
**Parameters** **Parameters**
@ -143,9 +147,103 @@ swift run -c release Imagium $FORCE_FLAG "./Images/images.txt" \
4. `--extension-output-path`: path where to generate generated extension 4. `--extension-output-path`: path where to generate generated extension
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: `AppImage+GreatApp.swift`) 6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppImage+GreatApp.swift`)
7. `--static-members` *(optional)*: generate static properties or not
> ⚠️ If extension name is not set or is `UIImage`, it will generate static property on `UIImage`.
# TODO ## All at once
Another command exists to generate all ressources at the same time: `generate`. It use the following commands: `Fonts`, `Colors`, `Strings/Stringium`, `Strings/Tags`, `Images`.
All parameters can be specified in a configuration file in `Yaml`:
> Order of configuration types does not matter. Order them to fit your needs.
```yaml
---
colors:
-
inputFile: String
style: [light/all]
xcassetsPath: String
extensionOutputPath: String
extensionName: String?
extensionSuffix: String?
staticMembers: Bool?
fonts:
-
inputFile: String
extensionOutputPath: String
extensionName: String?
extensionSuffix: String?
staticMembers: Bool?
images:
-
inputFile: String
xcassetsPath: String
extensionOutputPath: String
extensionName: String?
extensionSuffix: String?
staticMembers: Bool?
strings:
-
inputFile: String
outputPath: String
langs: String
defaultLang: String
extensionOutputPath: String
extensionName: String?
extensionSuffix: String?
staticMembers: Bool?
tags:
-
inputFile: String
lang: String
extensionOutputPath: String
extensionName: String?
extensionSuffix: String?
staticMembers: Bool?
```
### Multiple configurations
In some case, you may need to have 2 colors files in your projects. You will need 2 colors configurations. Every configuration type is an array and can contains as many configurations as you need.
Sample for 2 colors configurations:
```yaml
...
colors:
-
inputFile: String
style: [light/all]
xcassetsPath: String
extensionOutputPath: String
extensionName: String?
extensionSuffix: String?
staticMembers: Bool?
-
inputFile: String
style: [light/all]
xcassetsPath: String
extensionOutputPath: String
extensionName: String?
extensionSuffix: String?
staticMembers: Bool?
...
```
### No configuration
In some case, you may not need to generate tags. You must specified `tags` as an empty array :
```yaml
...
tags: []
...
```
[ ] Allow static variable generation on custom extension

View File

@ -24,19 +24,6 @@ struct Colors: ParsableCommand {
static let defaultExtensionName = "UIColor" static let defaultExtensionName = "UIColor"
static let assetsColorsFolderName = "Colors" static let assetsColorsFolderName = "Colors"
// MARK: - Properties
var extensionFileName: String {
if options.extensionSuffix.isEmpty == false {
return "\(options.extensionName)+\(options.extensionSuffix).swift"
}
return "\(options.extensionName).swift"
}
var extensionFilePath: String { "\(options.extensionOutputPath)/\(extensionFileName)" }
var generateStaticVariable: Bool {
options.extensionName == Self.defaultExtensionName
}
// MARK: - Command options // MARK: - Command options
@OptionGroup var options: ColorsToolOptions @OptionGroup var options: ColorsToolOptions
@ -65,9 +52,9 @@ struct Colors: ParsableCommand {
// Generate extension // Generate extension
ColorExtensionGenerator.writeExtensionFile(colors: parsedColors, ColorExtensionGenerator.writeExtensionFile(colors: parsedColors,
staticVar: generateStaticVariable, staticVar: options.staticMembers,
extensionName: options.extensionName, extensionName: options.extensionName,
extensionFilePath: extensionFilePath) extensionFilePath: options.extensionFilePath)
print("[\(Self.toolName)] Colors generated") print("[\(Self.toolName)] Colors generated")
} }
@ -92,7 +79,9 @@ struct Colors: ParsableCommand {
} }
// Check if needed to regenerate // Check if needed to regenerate
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration, inputFilePath: options.inputFile, extensionFilePath: extensionFilePath) else { guard GeneratorChecker.shouldGenerate(force: options.forceGeneration,
inputFilePath: options.inputFile,
extensionFilePath: options.extensionFilePath) else {
print("[\(Self.toolName)] Colors are already up to date :) ") print("[\(Self.toolName)] Colors are already up to date :) ")
return false return false
} }

View File

@ -24,15 +24,31 @@ struct ColorsToolOptions: ParsableArguments {
@Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
var extensionOutputPath: String 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 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 = Colors.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?
} }
// MARK: - Computed var
extension ColorsToolOptions { extension ColorsToolOptions {
var colorStyle: ColorStyle { var colorStyle: ColorStyle {
ColorStyle(rawValue: style) ?? .all ColorStyle(rawValue: style) ?? .all
} }
var extensionFileName: String {
if let extensionSuffix = extensionSuffix {
return "\(extensionName)+\(extensionSuffix).swift"
}
return "\(extensionName).swift"
}
var extensionFilePath: String {
"\(extensionOutputPath)/\(extensionFileName)"
}
} }

View File

@ -18,6 +18,7 @@ class ColorFileParser {
// Required format: // Required format:
// colorName="#RGB/#ARGB", colorName "#RGB/#ARGB", colorName "#RGB/#ARGB" "#RGB/#ARGB" // colorName="#RGB/#ARGB", colorName "#RGB/#ARGB", colorName "#RGB/#ARGB" "#RGB/#ARGB"
let colorLineCleanedUp = colorLine let colorLineCleanedUp = colorLine
.removeLeadingWhitespace()
.removeTrailingWhitespace() .removeTrailingWhitespace()
.replacingOccurrences(of: "=", with: "") // Keep compat with current file format .replacingOccurrences(of: "=", with: "") // Keep compat with current file format

View File

@ -18,6 +18,9 @@ struct FontsOptions: ParsableArguments {
@Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
var extensionOutputPath: String var extensionOutputPath: String
@Option(help: "Tell if it will generate static properties or methods")
var staticMembers: Bool = false
@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 = Fonts.defaultExtensionName var extensionName: String = Fonts.defaultExtensionName
@ -25,6 +28,8 @@ struct FontsOptions: ParsableArguments {
var extensionSuffix: String = "" var extensionSuffix: String = ""
} }
// MARK: - Computed var
extension FontsOptions { extension FontsOptions {
var extensionFileName: String { var extensionFileName: String {
if extensionSuffix.isEmpty == false { if extensionSuffix.isEmpty == false {
@ -36,8 +41,4 @@ extension FontsOptions {
var extensionFilePath: String { var extensionFilePath: String {
"\(extensionOutputPath)/\(extensionFileName)" "\(extensionOutputPath)/\(extensionFileName)"
} }
var generateStaticVariable: Bool {
extensionName == Fonts.defaultExtensionName
}
} }

View File

@ -23,19 +23,6 @@ struct Fonts: ParsableCommand {
static let toolName = "Fonts" static let toolName = "Fonts"
static let defaultExtensionName = "UIFont" static let defaultExtensionName = "UIFont"
// MARK: - Properties
var extensionFileName: String {
if options.extensionSuffix.isEmpty == false {
return "\(options.extensionName)+\(options.extensionSuffix).swift"
}
return "\(options.extensionName).swift"
}
var extensionFilePath: String { "\(options.extensionOutputPath)/\(extensionFileName)" }
var generateStaticVariable: Bool {
options.extensionName == Self.defaultExtensionName
}
// MARK: - Command Options // MARK: - Command Options
@OptionGroup var options: FontsOptions @OptionGroup var options: FontsOptions
@ -60,9 +47,9 @@ struct Fonts: ParsableCommand {
// Generate extension // Generate extension
FontExtensionGenerator.writeExtensionFile(fontsNames: fontsNames, FontExtensionGenerator.writeExtensionFile(fontsNames: fontsNames,
staticVar: generateStaticVariable, staticVar: options.staticMembers,
extensionName: options.extensionName, extensionName: options.extensionName,
extensionFilePath: extensionFilePath) extensionFilePath: options.extensionFilePath)
print("Info.plist information:") print("Info.plist information:")
print("\(FontPlistGenerator.generatePlistUIAppsFontContent(for: fontsNames))") print("\(FontPlistGenerator.generatePlistUIAppsFontContent(for: fontsNames))")
@ -83,7 +70,9 @@ struct Fonts: ParsableCommand {
} }
// Check if needed to regenerate // Check if needed to regenerate
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration, inputFilePath: options.inputFile, extensionFilePath: extensionFilePath) else { guard GeneratorChecker.shouldGenerate(force: options.forceGeneration,
inputFilePath: options.inputFile,
extensionFilePath: options.extensionFilePath) else {
print("[\(Self.toolName)] Fonts are already up to date :) ") print("[\(Self.toolName)] Fonts are already up to date :) ")
return false return false
} }

View File

@ -44,6 +44,7 @@ struct Generate: ParsableCommand {
configuration.runnableConfigurations configuration.runnableConfigurations
.forEach { .forEach {
$0.run(force: options.forceGeneration) $0.run(force: options.forceGeneration)
print("\n")
} }
print("[\(Self.toolName)] Resgen ended") print("[\(Self.toolName)] Resgen ended")

View File

@ -46,6 +46,14 @@ struct ColorsConfiguration: Codable, CustomDebugStringConvertible {
let extensionOutputPath: String let extensionOutputPath: String
let extensionName: String? let extensionName: String?
let extensionSuffix: String? let extensionSuffix: String?
private let staticMembers: Bool?
var staticMembersOptions: Bool {
if let staticMembers = staticMembers {
return staticMembers
}
return false
}
var debugDescription: String { var debugDescription: String {
""" """
@ -65,6 +73,14 @@ struct FontsConfiguration: Codable, CustomDebugStringConvertible {
let extensionOutputPath: String let extensionOutputPath: String
let extensionName: String? let extensionName: String?
let extensionSuffix: String? let extensionSuffix: String?
private let staticMembers: Bool?
var staticMembersOptions: Bool {
if let staticMembers = staticMembers {
return staticMembers
}
return false
}
var debugDescription: String { var debugDescription: String {
""" """
@ -83,6 +99,14 @@ struct ImagesConfiguration: Codable, CustomDebugStringConvertible {
let extensionOutputPath: String let extensionOutputPath: String
let extensionName: String? let extensionName: String?
let extensionSuffix: String? let extensionSuffix: String?
private let staticMembers: Bool?
var staticMembersOptions: Bool {
if let staticMembers = staticMembers {
return staticMembers
}
return false
}
var debugDescription: String { var debugDescription: String {
""" """
@ -104,6 +128,14 @@ struct StringsConfiguration: Codable, CustomDebugStringConvertible {
let extensionOutputPath: String let extensionOutputPath: String
let extensionName: String? let extensionName: String?
let extensionSuffix: String? let extensionSuffix: String?
private let staticMembers: Bool?
var staticMembersOptions: Bool {
if let staticMembers = staticMembers {
return staticMembers
}
return false
}
var debugDescription: String { var debugDescription: String {
""" """
@ -125,6 +157,14 @@ struct TagsConfiguration: Codable, CustomDebugStringConvertible {
let extensionOutputPath: String let extensionOutputPath: String
let extensionName: String? let extensionName: String?
let extensionSuffix: String? let extensionSuffix: String?
private let staticMembers: Bool?
var staticMembersOptions: Bool {
if let staticMembers = staticMembers {
return staticMembers
}
return false
}
var debugDescription: String { var debugDescription: String {
""" """

View File

@ -22,7 +22,9 @@ extension ColorsConfiguration: Runnable {
"--xcassets-path", "--xcassets-path",
xcassetsPath, xcassetsPath,
"--extension-output-path", "--extension-output-path",
extensionOutputPath extensionOutputPath,
"--static-members",
"\(staticMembersOptions)"
] ]
if let extensionName = extensionName { if let extensionName = extensionName {

View File

@ -18,7 +18,9 @@ extension FontsConfiguration: Runnable {
args += [ args += [
inputFile, inputFile,
"--extension-output-path", "--extension-output-path",
extensionOutputPath extensionOutputPath,
"--static-members",
"\(staticMembersOptions)"
] ]
if let extensionName = extensionName { if let extensionName = extensionName {

View File

@ -12,7 +12,7 @@ extension ImagesConfiguration: Runnable {
var args = [String]() var args = [String]()
if force { if force {
args += ["-f"] args += ["-F"] // Images has a -f and -F options
} }
args += [ args += [
@ -20,7 +20,9 @@ extension ImagesConfiguration: Runnable {
"--xcassets-path", "--xcassets-path",
xcassetsPath, xcassetsPath,
"--extension-output-path", "--extension-output-path",
extensionOutputPath extensionOutputPath,
"--static-members",
"\(staticMembersOptions)"
] ]
if let extensionName = extensionName { if let extensionName = extensionName {

View File

@ -24,7 +24,9 @@ extension StringsConfiguration: Runnable {
"--default-lang", "--default-lang",
defaultLang, defaultLang,
"--extension-output-path", "--extension-output-path",
extensionOutputPath extensionOutputPath,
"--static-members",
"\(staticMembersOptions)"
] ]
if let extensionName = extensionName { if let extensionName = extensionName {

View File

@ -20,7 +20,9 @@ extension TagsConfiguration: Runnable {
"--lang", "--lang",
lang, lang,
"--extension-output-path", "--extension-output-path",
extensionOutputPath extensionOutputPath,
"--static-members",
"\(staticMembersOptions)"
] ]
if let extensionName = extensionName { if let extensionName = extensionName {

View File

@ -148,7 +148,7 @@ class XcassetsGenerator {
// MARK: - Helpers: bypass generation // MARK: - Helpers: bypass generation
private func shouldBypassGeneration(for image: ParsedImage, xcassetImagePath: String) -> Bool { private func shouldBypassGeneration(for image: ParsedImage, xcassetImagePath: String) -> Bool {
guard forceGeneration == false else { if forceGeneration {
return false return false
} }

View File

@ -23,16 +23,6 @@ struct Images: ParsableCommand {
static let toolName = "Images" static let toolName = "Images"
static let defaultExtensionName = "UIImage" static let defaultExtensionName = "UIImage"
// MARK: - Properties
var extensionFileName: String { "\(options.extensionName)+\(options.extensionSuffix).swift" }
var extensionFilePath: String { "\(options.extensionOutputPath)/\(extensionFileName)" }
var inputFilenameWithoutExt: String {
URL(fileURLWithPath: options.inputFile)
.deletingPathExtension()
.lastPathComponent
}
// MARK: - Command Options // MARK: - Command Options
@OptionGroup var options: ImagesOptions @OptionGroup var options: ImagesOptions
@ -54,6 +44,7 @@ struct Images: ParsableCommand {
let inputFolder = URL(fileURLWithPath: options.inputFile) let inputFolder = URL(fileURLWithPath: options.inputFile)
.deletingLastPathComponent() .deletingLastPathComponent()
.relativePath .relativePath
let xcassetsGenerator = XcassetsGenerator(forceGeneration: options.forceExecutionAndGeneration) let xcassetsGenerator = XcassetsGenerator(forceGeneration: options.forceExecutionAndGeneration)
xcassetsGenerator.generateXcassets(inputPath: inputFolder, xcassetsGenerator.generateXcassets(inputPath: inputFolder,
imagesToGenerate: imagesToGenerate, imagesToGenerate: imagesToGenerate,
@ -61,10 +52,10 @@ struct Images: ParsableCommand {
// Generate extension // Generate extension
ImageExtensionGenerator.writeStringsFiles(images: imagesToGenerate, ImageExtensionGenerator.writeStringsFiles(images: imagesToGenerate,
staticVar: options.extensionName == Self.defaultExtensionName, staticVar: options.staticMembers,
inputFilename: inputFilenameWithoutExt, inputFilename: options.inputFilenameWithoutExt,
extensionName: options.extensionName, extensionName: options.extensionName,
extensionFilePath: extensionFilePath) extensionFilePath: options.extensionFilePath)
print("[\(Self.toolName)] Images generated") print("[\(Self.toolName)] Images generated")
@ -90,7 +81,9 @@ struct Images: ParsableCommand {
_ = Images.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: options.extensionFilePath) else {
print("[\(Self.toolName)] Images are already up to date :) ") print("[\(Self.toolName)] Images are already up to date :) ")
return false return false
} }

View File

@ -24,18 +24,33 @@ struct ImagesOptions: ParsableArguments {
@Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
var extensionOutputPath: String 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 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 = Images.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?
} }
// MARK: - Computed var
/* extension ImagesOptions {
swift run -c release Imagium $FORCE_FLAG "./Images/sampleImages.txt" \ var extensionFileName: String {
--xcassets-path "./Images/imagium.xcassets" \ if let extensionSuffix = extensionSuffix {
--extension-output-path "./Images/Generated" \ return "\(extensionName)+\(extensionSuffix).swift"
--extension-name "UIImage" \ }
--extension-suffix "GenAllScript" return "\(extensionName).swift"
*/ }
var extensionFilePath: String {
"\(extensionOutputPath)/\(extensionFileName)"
}
var inputFilenameWithoutExt: String {
URL(fileURLWithPath: inputFile)
.deletingPathExtension()
.lastPathComponent
}
}

View File

@ -98,7 +98,7 @@ class StringsFileGenerator {
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
guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else { guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else {
return // Go to next definition return // Go to next definition

View File

@ -24,27 +24,6 @@ struct Stringium: ParsableCommand {
static let defaultExtensionName = "String" static let defaultExtensionName = "String"
static let noTranslationTag: String = "notranslation" static let noTranslationTag: String = "notranslation"
// MARK: - Properties
var extensionFileName: String {
if let extensionSuffix = options.extensionSuffix {
return "\(options.extensionName)+\(extensionSuffix).swift"
}
return "\(options.extensionName).swift"
}
var extensionFilePath: String { "\(options.extensionOutputPath)/\(extensionFileName)" }
var inputFilenameWithoutExt: String {
URL(fileURLWithPath: options.inputFile)
.deletingPathExtension()
.lastPathComponent
}
var generateStaticVariable: Bool {
options.extensionName == Self.defaultExtensionName
}
// MARK: - Command options // MARK: - Command options
@OptionGroup var options: StringiumOptions @OptionGroup var options: StringiumOptions
@ -68,16 +47,16 @@ struct Stringium: ParsableCommand {
defaultLang: options.defaultLang, defaultLang: options.defaultLang,
tags: options.tags, tags: options.tags,
outputPath: options.stringsFileOutputPath, outputPath: options.stringsFileOutputPath,
inputFilenameWithoutExt: inputFilenameWithoutExt) inputFilenameWithoutExt: options.inputFilenameWithoutExt)
// Generate extension // Generate extension
StringsFileGenerator.writeExtensionFiles(sections: sections, StringsFileGenerator.writeExtensionFiles(sections: sections,
defaultLang: options.defaultLang, defaultLang: options.defaultLang,
tags: options.tags, tags: options.tags,
staticVar: generateStaticVariable, staticVar: options.staticMembers,
inputFilename: inputFilenameWithoutExt, inputFilename: options.inputFilenameWithoutExt,
extensionName: options.extensionName, extensionName: options.extensionName,
extensionFilePath: extensionFilePath) extensionFilePath: options.extensionFilePath)
print("[\(Self.toolName)] Strings generated") print("[\(Self.toolName)] Strings generated")
} }
@ -108,7 +87,9 @@ struct Stringium: ParsableCommand {
} }
// Check if needed to regenerate // Check if needed to regenerate
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration, inputFilePath: options.inputFile, extensionFilePath: extensionFilePath) else { guard GeneratorChecker.shouldGenerate(force: options.forceGeneration,
inputFilePath: options.inputFile,
extensionFilePath: options.extensionFilePath) else {
print("[\(Self.toolName)] Strings are already up to date :) ") print("[\(Self.toolName)] Strings are already up to date :) ")
return false return false
} }

View File

@ -30,6 +30,9 @@ struct StringiumOptions: ParsableArguments {
@Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
var extensionOutputPath: String 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 String extension. Using default extension name will generate static property.") @Option(help: "Extension name. If not specified, it will generate an String extension. Using default extension name will generate static property.")
var extensionName: String = Stringium.defaultExtensionName var extensionName: String = Stringium.defaultExtensionName
@ -37,6 +40,8 @@ struct StringiumOptions: ParsableArguments {
var extensionSuffix: String? var extensionSuffix: String?
} }
// MARK: - Private var getter
extension StringiumOptions { extension StringiumOptions {
var stringsFileOutputPath: String { var stringsFileOutputPath: String {
var outputPath = outputPathRaw var outputPath = outputPathRaw
@ -58,3 +63,24 @@ extension StringiumOptions {
.map { String($0) } .map { String($0) }
} }
} }
// MARK: - Computed var
extension StringiumOptions {
var extensionFileName: String {
if let extensionSuffix = extensionSuffix {
return "\(extensionName)+\(extensionSuffix).swift"
}
return "\(extensionName).swift"
}
var extensionFilePath: String {
"\(extensionOutputPath)/\(extensionFileName)"
}
var inputFilenameWithoutExt: String {
URL(fileURLWithPath: inputFile)
.deletingPathExtension()
.lastPathComponent
}
}

View File

@ -25,19 +25,6 @@ struct Tags: ParsableCommand {
static let defaultExtensionName = "Tags" static let defaultExtensionName = "Tags"
static let noTranslationTag: String = "notranslation" static let noTranslationTag: String = "notranslation"
// MARK: - Properties
var extensionFileName: String {
if let extensionSuffix = options.extensionSuffix {
return "\(options.extensionName)+\(extensionSuffix).swift"
}
return "\(options.extensionName).swift"
}
var extensionFilePath: String { "\(options.extensionOutputPath)/\(extensionFileName)" }
var generateStaticVariable: Bool {
options.extensionName == Self.defaultExtensionName
}
// MARK: - Command Options // MARK: - Command Options
@OptionGroup var options: TagsOptions @OptionGroup var options: TagsOptions
@ -59,9 +46,9 @@ struct Tags: ParsableCommand {
TagsGenerator.writeExtensionFiles(sections: sections, TagsGenerator.writeExtensionFiles(sections: sections,
lang: options.lang, lang: options.lang,
tags: ["ios", "iosonly", Self.noTranslationTag], tags: ["ios", "iosonly", Self.noTranslationTag],
staticVar: generateStaticVariable, staticVar: options.staticMembers,
extensionName: options.extensionName, extensionName: options.extensionName,
extensionFilePath: extensionFilePath) extensionFilePath: options.extensionFilePath)
print("[\(Self.toolName)] Tags generated") print("[\(Self.toolName)] Tags generated")
} }
@ -79,7 +66,9 @@ struct Tags: ParsableCommand {
} }
// Check if needed to regenerate // Check if needed to regenerate
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration, inputFilePath: options.inputFile, extensionFilePath: extensionFilePath) else { guard GeneratorChecker.shouldGenerate(force: options.forceGeneration,
inputFilePath: options.inputFile,
extensionFilePath: options.extensionFilePath) else {
print("[\(Self.toolName)] Tags are already up to date :) ") print("[\(Self.toolName)] Tags are already up to date :) ")
return false return false
} }

View File

@ -21,9 +21,27 @@ struct TagsOptions: ParsableArguments {
@Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
var extensionOutputPath: String 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 a Tag extension. Using default extension name will generate static property.") @Option(help: "Extension name. If not specified, it will generate a Tag extension. Using default extension name will generate static property.")
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?
} }
// MARK: - Computed var
extension TagsOptions {
var extensionFileName: String {
if let extensionSuffix = extensionSuffix {
return "\(extensionName)+\(extensionSuffix).swift"
}
return "\(extensionName).swift"
}
var extensionFilePath: String {
"\(extensionOutputPath)/\(extensionFileName)"
}
}

View File

@ -24,13 +24,6 @@ struct Twine: ParsableCommand {
static let defaultExtensionName = "String" static let defaultExtensionName = "String"
static let twineExecutable = "\(FileManager.default.homeDirectoryForCurrentUser.relativePath)/scripts/twine/twine" static let twineExecutable = "\(FileManager.default.homeDirectoryForCurrentUser.relativePath)/scripts/twine/twine"
// MARK: - Properties
var inputFilenameWithoutExt: String { URL(fileURLWithPath: options.inputFile)
.deletingPathExtension()
.lastPathComponent
}
// MARK: - Command Options // MARK: - Command Options
@OptionGroup var options: TwineOptions @OptionGroup var options: TwineOptions
@ -50,17 +43,16 @@ struct Twine: ParsableCommand {
Shell.shell(Self.twineExecutable, Shell.shell(Self.twineExecutable,
"generate-localization-file", options.inputFile, "generate-localization-file", options.inputFile,
"--lang", "\(lang)", "--lang", "\(lang)",
"\(options.outputPath)/\(lang).lproj/\(inputFilenameWithoutExt).strings", "\(options.outputPath)/\(lang).lproj/\(options.inputFilenameWithoutExt).strings",
"--tags=ios,iosonly,iosOnly") "--tags=ios,iosonly,iosOnly")
} }
// Generate extension // Generate extension
var extensionFilePath: String { "\(options.extensionOutputPath)/\(inputFilenameWithoutExt).swift" }
Shell.shell(Self.twineExecutable, Shell.shell(Self.twineExecutable,
"generate-localization-file", options.inputFile, "generate-localization-file", options.inputFile,
"--format", "apple-swift", "--format", "apple-swift",
"--lang", "\(options.defaultLang)", "--lang", "\(options.defaultLang)",
extensionFilePath, options.extensionFilePath,
"--tags=ios,iosonly,iosOnly") "--tags=ios,iosonly,iosOnly")
print("[\(Self.toolName)] Strings generated") print("[\(Self.toolName)] Strings generated")
@ -91,11 +83,10 @@ struct Twine: ParsableCommand {
Twine.exit(withError: error) Twine.exit(withError: error)
} }
// "R2String+" is hardcoded in Twine formatter
let extensionFilePathGenerated = "\(options.extensionOutputPath)/R2String+\(inputFilenameWithoutExt).swift"
// Check if needed to regenerate // Check if needed to regenerate
guard GeneratorChecker.shouldGenerate(force: options.forceGeneration, inputFilePath: options.inputFile, extensionFilePath: extensionFilePathGenerated) else { guard GeneratorChecker.shouldGenerate(force: options.forceGeneration,
inputFilePath: options.inputFile,
extensionFilePath: options.extensionFilePathGenerated) else {
print("[\(Self.toolName)] Strings are already up to date :) ") print("[\(Self.toolName)] Strings are already up to date :) ")
return false return false
} }

View File

@ -28,6 +28,8 @@ struct TwineOptions: ParsableArguments {
var extensionOutputPath: String var extensionOutputPath: String
} }
// MARK: - Private var getter
extension TwineOptions { extension TwineOptions {
var langs: [String] { var langs: [String] {
langsRaw langsRaw
@ -35,3 +37,22 @@ extension TwineOptions {
.map { String($0) } .map { String($0) }
} }
} }
// MARK: - Computed var
extension TwineOptions {
var inputFilenameWithoutExt: String {
URL(fileURLWithPath: inputFile)
.deletingPathExtension()
.lastPathComponent
}
var extensionFilePath: String {
"\(extensionOutputPath)/\(inputFilenameWithoutExt).swift"
}
// "R2String+" is hardcoded in Twine formatter
var extensionFilePathGenerated: String {
"\(extensionOutputPath)/R2String+\(inputFilenameWithoutExt).swift"
}
}