From 3d60513c08b6ba634012910ac3ddd8549e289dca Mon Sep 17 00:00:00 2001 From: Thibaut Schmitt Date: Wed, 31 Aug 2022 15:18:44 +0200 Subject: [PATCH] Add new Flag to every command to choose if we want to generate static members or not --- README.md | 140 +++++++++++++++--- Sources/ResgenSwift/Colors/Colors.swift | 21 +-- .../Colors/ColorsToolOptions.swift | 18 ++- .../Colors/Parser/ColorFileParser.swift | 1 + Sources/ResgenSwift/Fonts/FontOptions.swift | 9 +- Sources/ResgenSwift/Fonts/Fonts.swift | 21 +-- Sources/ResgenSwift/Generate/Generate.swift | 1 + .../Generate/Model/ConfigurationFile.swift | 40 +++++ ...ColorsConfiguration+ShellCommandable.swift | 4 +- .../FontsConfiguration+ShellCommandable.swift | 4 +- ...ImagesConfiguration+ShellCommandable.swift | 6 +- .../Runnable.swift | 0 ...tringsConfiguration+ShellCommandable.swift | 4 +- .../TagsConfiguration+ShellCommandable.swift | 4 +- .../Images/Generator/XcassetsGenerator.swift | 2 +- Sources/ResgenSwift/Images/Images.swift | 21 +-- .../ResgenSwift/Images/ImagesOptions.swift | 31 +++- .../Generator/StringsFileGenerator.swift | 2 +- .../Strings/Stringium/Stringium.swift | 33 +---- .../Strings/Stringium/StringiumOptions.swift | 26 ++++ Sources/ResgenSwift/Strings/Tag/Tags.swift | 21 +-- .../ResgenSwift/Strings/Tag/TagsOptions.swift | 18 +++ Sources/ResgenSwift/Strings/Twine/Twine.swift | 19 +-- .../Strings/Twine/TwineOptions.swift | 21 +++ 24 files changed, 323 insertions(+), 144 deletions(-) rename Sources/ResgenSwift/Generate/{ShellCommandable => Runnable}/ColorsConfiguration+ShellCommandable.swift (89%) rename Sources/ResgenSwift/Generate/{ShellCommandable => Runnable}/FontsConfiguration+ShellCommandable.swift (88%) rename Sources/ResgenSwift/Generate/{ShellCommandable => Runnable}/ImagesConfiguration+ShellCommandable.swift (82%) rename Sources/ResgenSwift/Generate/{ShellCommandable => Runnable}/Runnable.swift (100%) rename Sources/ResgenSwift/Generate/{ShellCommandable => Runnable}/StringsConfiguration+ShellCommandable.swift (90%) rename Sources/ResgenSwift/Generate/{ShellCommandable => Runnable}/TagsConfiguration+ShellCommandable.swift (88%) diff --git a/README.md b/README.md index 78384b2..81fb67f 100644 --- a/README.md +++ b/README.md @@ -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` -# Fonts +## Fonts 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`. @@ -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" \ --extension-output-path "./Fonts/Generated" \ --extension-name "AppFont" \ - --extension-suffix "GreatApp" + --extension-suffix "GreatApp" \ + --static-members true ``` **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 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`) - -> ⚠️ If extension name is not set or is `UIFont`, it will generate static property on `UIFont` instead of method in your custom class. +6. `--static-members` *(optional)*: generate static properties or not -# Colors +## Colors 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" \ --extension-output-path "./Colors/Generated/" \ --extension-name "AppColor" \ - --extension-suffix "GreatApp" + --extension-suffix "GreatApp" \ + --static-members true ``` **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 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`) +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. -## Twine (not recommended) +### Twine (not recommended) ``` 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. `--extension-output-path`: path where to generate generated extension -## Stringium (recommended) +### Stringium (recommended) ``` 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" \ --extension-output-path "./Strings/Generated" \ --extension-name "AppString" \ - --extension-suffix "GreatApp" + --extension-suffix "GreatApp" \ + --static-members true ``` **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 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`) +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. @@ -109,7 +110,8 @@ swift run -c release Strings tags $FORCE_FLAG "./Tags/tags.txt" \ --lang "ium" \ --extension-output-path "./Tags/Generated" \ --extension-name "AppTags" \ - --extension-suffix "GreatApp" + --extension-suffix "GreatApp" \ + --static-members true ``` **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 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`) +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. @@ -132,7 +135,8 @@ swift run -c release Imagium $FORCE_FLAG "./Images/images.txt" \ --xcassets-path "./Images/app.xcassets" \ --extension-output-path "./Images/Generated" \ --extension-name "AppImage" \ - --extension-suffix "GreatApp" + --extension-suffix "GreatApp" \ + --static-members true ``` **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 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`) +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 diff --git a/Sources/ResgenSwift/Colors/Colors.swift b/Sources/ResgenSwift/Colors/Colors.swift index d905bad..9d0da92 100644 --- a/Sources/ResgenSwift/Colors/Colors.swift +++ b/Sources/ResgenSwift/Colors/Colors.swift @@ -24,19 +24,6 @@ struct Colors: ParsableCommand { static let defaultExtensionName = "UIColor" static let assetsColorsFolderName = "Colors" - // MARK: - Properties - - var extensionFileName: String { - if options.extensionSuffix.isEmpty == false { - return "\(options.extensionName)+\(options.extensionSuffix).swift" - } - return "\(options.extensionName).swift" - } - var extensionFilePath: String { "\(options.extensionOutputPath)/\(extensionFileName)" } - var generateStaticVariable: Bool { - options.extensionName == Self.defaultExtensionName - } - // MARK: - Command options @OptionGroup var options: ColorsToolOptions @@ -65,9 +52,9 @@ struct Colors: ParsableCommand { // Generate extension ColorExtensionGenerator.writeExtensionFile(colors: parsedColors, - staticVar: generateStaticVariable, + staticVar: options.staticMembers, extensionName: options.extensionName, - extensionFilePath: extensionFilePath) + extensionFilePath: options.extensionFilePath) print("[\(Self.toolName)] Colors generated") } @@ -92,7 +79,9 @@ struct Colors: ParsableCommand { } // 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 :) ") return false } diff --git a/Sources/ResgenSwift/Colors/ColorsToolOptions.swift b/Sources/ResgenSwift/Colors/ColorsToolOptions.swift index a9aea80..9f5ae80 100644 --- a/Sources/ResgenSwift/Colors/ColorsToolOptions.swift +++ b/Sources/ResgenSwift/Colors/ColorsToolOptions.swift @@ -24,15 +24,31 @@ struct ColorsToolOptions: ParsableArguments { @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) var extensionOutputPath: String + @Option(help: "Tell if it will generate static properties or not") + var staticMembers: Bool = false + @Option(help: "Extension name. If not specified, it will generate an UIColor extension. Using default extension name will generate static property.") var extensionName: String = Colors.defaultExtensionName @Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+ColorsMyApp.swift") - var extensionSuffix: String = "" + var extensionSuffix: String? } +// MARK: - Computed var + extension ColorsToolOptions { var colorStyle: ColorStyle { ColorStyle(rawValue: style) ?? .all } + + var extensionFileName: String { + if let extensionSuffix = extensionSuffix { + return "\(extensionName)+\(extensionSuffix).swift" + } + return "\(extensionName).swift" + } + + var extensionFilePath: String { + "\(extensionOutputPath)/\(extensionFileName)" + } } diff --git a/Sources/ResgenSwift/Colors/Parser/ColorFileParser.swift b/Sources/ResgenSwift/Colors/Parser/ColorFileParser.swift index a96b4e7..653006b 100644 --- a/Sources/ResgenSwift/Colors/Parser/ColorFileParser.swift +++ b/Sources/ResgenSwift/Colors/Parser/ColorFileParser.swift @@ -18,6 +18,7 @@ class ColorFileParser { // Required format: // colorName="#RGB/#ARGB", colorName "#RGB/#ARGB", colorName "#RGB/#ARGB" "#RGB/#ARGB" let colorLineCleanedUp = colorLine + .removeLeadingWhitespace() .removeTrailingWhitespace() .replacingOccurrences(of: "=", with: "") // Keep compat with current file format diff --git a/Sources/ResgenSwift/Fonts/FontOptions.swift b/Sources/ResgenSwift/Fonts/FontOptions.swift index cec71a4..983f00d 100644 --- a/Sources/ResgenSwift/Fonts/FontOptions.swift +++ b/Sources/ResgenSwift/Fonts/FontOptions.swift @@ -18,6 +18,9 @@ struct FontsOptions: ParsableArguments { @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) 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.") var extensionName: String = Fonts.defaultExtensionName @@ -25,6 +28,8 @@ struct FontsOptions: ParsableArguments { var extensionSuffix: String = "" } +// MARK: - Computed var + extension FontsOptions { var extensionFileName: String { if extensionSuffix.isEmpty == false { @@ -36,8 +41,4 @@ extension FontsOptions { var extensionFilePath: String { "\(extensionOutputPath)/\(extensionFileName)" } - - var generateStaticVariable: Bool { - extensionName == Fonts.defaultExtensionName - } } diff --git a/Sources/ResgenSwift/Fonts/Fonts.swift b/Sources/ResgenSwift/Fonts/Fonts.swift index a010cb3..671b477 100644 --- a/Sources/ResgenSwift/Fonts/Fonts.swift +++ b/Sources/ResgenSwift/Fonts/Fonts.swift @@ -23,19 +23,6 @@ struct Fonts: ParsableCommand { static let toolName = "Fonts" 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 @OptionGroup var options: FontsOptions @@ -60,9 +47,9 @@ struct Fonts: ParsableCommand { // Generate extension FontExtensionGenerator.writeExtensionFile(fontsNames: fontsNames, - staticVar: generateStaticVariable, + staticVar: options.staticMembers, extensionName: options.extensionName, - extensionFilePath: extensionFilePath) + extensionFilePath: options.extensionFilePath) print("Info.plist information:") print("\(FontPlistGenerator.generatePlistUIAppsFontContent(for: fontsNames))") @@ -83,7 +70,9 @@ struct Fonts: ParsableCommand { } // 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 :) ") return false } diff --git a/Sources/ResgenSwift/Generate/Generate.swift b/Sources/ResgenSwift/Generate/Generate.swift index eba7822..1d91f88 100644 --- a/Sources/ResgenSwift/Generate/Generate.swift +++ b/Sources/ResgenSwift/Generate/Generate.swift @@ -44,6 +44,7 @@ struct Generate: ParsableCommand { configuration.runnableConfigurations .forEach { $0.run(force: options.forceGeneration) + print("\n") } print("[\(Self.toolName)] Resgen ended") diff --git a/Sources/ResgenSwift/Generate/Model/ConfigurationFile.swift b/Sources/ResgenSwift/Generate/Model/ConfigurationFile.swift index bf4bd84..7ba457f 100644 --- a/Sources/ResgenSwift/Generate/Model/ConfigurationFile.swift +++ b/Sources/ResgenSwift/Generate/Model/ConfigurationFile.swift @@ -46,6 +46,14 @@ struct ColorsConfiguration: Codable, CustomDebugStringConvertible { let extensionOutputPath: String let extensionName: String? let extensionSuffix: String? + private let staticMembers: Bool? + + var staticMembersOptions: Bool { + if let staticMembers = staticMembers { + return staticMembers + } + return false + } var debugDescription: String { """ @@ -65,6 +73,14 @@ struct FontsConfiguration: Codable, CustomDebugStringConvertible { let extensionOutputPath: String let extensionName: String? let extensionSuffix: String? + private let staticMembers: Bool? + + var staticMembersOptions: Bool { + if let staticMembers = staticMembers { + return staticMembers + } + return false + } var debugDescription: String { """ @@ -83,6 +99,14 @@ struct ImagesConfiguration: Codable, CustomDebugStringConvertible { let extensionOutputPath: String let extensionName: String? let extensionSuffix: String? + private let staticMembers: Bool? + + var staticMembersOptions: Bool { + if let staticMembers = staticMembers { + return staticMembers + } + return false + } var debugDescription: String { """ @@ -104,6 +128,14 @@ struct StringsConfiguration: Codable, CustomDebugStringConvertible { let extensionOutputPath: String let extensionName: String? let extensionSuffix: String? + private let staticMembers: Bool? + + var staticMembersOptions: Bool { + if let staticMembers = staticMembers { + return staticMembers + } + return false + } var debugDescription: String { """ @@ -125,6 +157,14 @@ struct TagsConfiguration: Codable, CustomDebugStringConvertible { let extensionOutputPath: String let extensionName: String? let extensionSuffix: String? + private let staticMembers: Bool? + + var staticMembersOptions: Bool { + if let staticMembers = staticMembers { + return staticMembers + } + return false + } var debugDescription: String { """ diff --git a/Sources/ResgenSwift/Generate/ShellCommandable/ColorsConfiguration+ShellCommandable.swift b/Sources/ResgenSwift/Generate/Runnable/ColorsConfiguration+ShellCommandable.swift similarity index 89% rename from Sources/ResgenSwift/Generate/ShellCommandable/ColorsConfiguration+ShellCommandable.swift rename to Sources/ResgenSwift/Generate/Runnable/ColorsConfiguration+ShellCommandable.swift index ea62f0d..390e177 100644 --- a/Sources/ResgenSwift/Generate/ShellCommandable/ColorsConfiguration+ShellCommandable.swift +++ b/Sources/ResgenSwift/Generate/Runnable/ColorsConfiguration+ShellCommandable.swift @@ -22,7 +22,9 @@ extension ColorsConfiguration: Runnable { "--xcassets-path", xcassetsPath, "--extension-output-path", - extensionOutputPath + extensionOutputPath, + "--static-members", + "\(staticMembersOptions)" ] if let extensionName = extensionName { diff --git a/Sources/ResgenSwift/Generate/ShellCommandable/FontsConfiguration+ShellCommandable.swift b/Sources/ResgenSwift/Generate/Runnable/FontsConfiguration+ShellCommandable.swift similarity index 88% rename from Sources/ResgenSwift/Generate/ShellCommandable/FontsConfiguration+ShellCommandable.swift rename to Sources/ResgenSwift/Generate/Runnable/FontsConfiguration+ShellCommandable.swift index 0c9005f..ece931a 100644 --- a/Sources/ResgenSwift/Generate/ShellCommandable/FontsConfiguration+ShellCommandable.swift +++ b/Sources/ResgenSwift/Generate/Runnable/FontsConfiguration+ShellCommandable.swift @@ -18,7 +18,9 @@ extension FontsConfiguration: Runnable { args += [ inputFile, "--extension-output-path", - extensionOutputPath + extensionOutputPath, + "--static-members", + "\(staticMembersOptions)" ] if let extensionName = extensionName { diff --git a/Sources/ResgenSwift/Generate/ShellCommandable/ImagesConfiguration+ShellCommandable.swift b/Sources/ResgenSwift/Generate/Runnable/ImagesConfiguration+ShellCommandable.swift similarity index 82% rename from Sources/ResgenSwift/Generate/ShellCommandable/ImagesConfiguration+ShellCommandable.swift rename to Sources/ResgenSwift/Generate/Runnable/ImagesConfiguration+ShellCommandable.swift index 82e0fcb..837bbf7 100644 --- a/Sources/ResgenSwift/Generate/ShellCommandable/ImagesConfiguration+ShellCommandable.swift +++ b/Sources/ResgenSwift/Generate/Runnable/ImagesConfiguration+ShellCommandable.swift @@ -12,7 +12,7 @@ extension ImagesConfiguration: Runnable { var args = [String]() if force { - args += ["-f"] + args += ["-F"] // Images has a -f and -F options } args += [ @@ -20,7 +20,9 @@ extension ImagesConfiguration: Runnable { "--xcassets-path", xcassetsPath, "--extension-output-path", - extensionOutputPath + extensionOutputPath, + "--static-members", + "\(staticMembersOptions)" ] if let extensionName = extensionName { diff --git a/Sources/ResgenSwift/Generate/ShellCommandable/Runnable.swift b/Sources/ResgenSwift/Generate/Runnable/Runnable.swift similarity index 100% rename from Sources/ResgenSwift/Generate/ShellCommandable/Runnable.swift rename to Sources/ResgenSwift/Generate/Runnable/Runnable.swift diff --git a/Sources/ResgenSwift/Generate/ShellCommandable/StringsConfiguration+ShellCommandable.swift b/Sources/ResgenSwift/Generate/Runnable/StringsConfiguration+ShellCommandable.swift similarity index 90% rename from Sources/ResgenSwift/Generate/ShellCommandable/StringsConfiguration+ShellCommandable.swift rename to Sources/ResgenSwift/Generate/Runnable/StringsConfiguration+ShellCommandable.swift index 03726a7..ae60f95 100644 --- a/Sources/ResgenSwift/Generate/ShellCommandable/StringsConfiguration+ShellCommandable.swift +++ b/Sources/ResgenSwift/Generate/Runnable/StringsConfiguration+ShellCommandable.swift @@ -24,7 +24,9 @@ extension StringsConfiguration: Runnable { "--default-lang", defaultLang, "--extension-output-path", - extensionOutputPath + extensionOutputPath, + "--static-members", + "\(staticMembersOptions)" ] if let extensionName = extensionName { diff --git a/Sources/ResgenSwift/Generate/ShellCommandable/TagsConfiguration+ShellCommandable.swift b/Sources/ResgenSwift/Generate/Runnable/TagsConfiguration+ShellCommandable.swift similarity index 88% rename from Sources/ResgenSwift/Generate/ShellCommandable/TagsConfiguration+ShellCommandable.swift rename to Sources/ResgenSwift/Generate/Runnable/TagsConfiguration+ShellCommandable.swift index e89fff2..efab0d2 100644 --- a/Sources/ResgenSwift/Generate/ShellCommandable/TagsConfiguration+ShellCommandable.swift +++ b/Sources/ResgenSwift/Generate/Runnable/TagsConfiguration+ShellCommandable.swift @@ -20,7 +20,9 @@ extension TagsConfiguration: Runnable { "--lang", lang, "--extension-output-path", - extensionOutputPath + extensionOutputPath, + "--static-members", + "\(staticMembersOptions)" ] if let extensionName = extensionName { diff --git a/Sources/ResgenSwift/Images/Generator/XcassetsGenerator.swift b/Sources/ResgenSwift/Images/Generator/XcassetsGenerator.swift index 08ec6b7..8c5fe8f 100644 --- a/Sources/ResgenSwift/Images/Generator/XcassetsGenerator.swift +++ b/Sources/ResgenSwift/Images/Generator/XcassetsGenerator.swift @@ -148,7 +148,7 @@ class XcassetsGenerator { // MARK: - Helpers: bypass generation private func shouldBypassGeneration(for image: ParsedImage, xcassetImagePath: String) -> Bool { - guard forceGeneration == false else { + if forceGeneration { return false } diff --git a/Sources/ResgenSwift/Images/Images.swift b/Sources/ResgenSwift/Images/Images.swift index bfe3af8..d3ff386 100644 --- a/Sources/ResgenSwift/Images/Images.swift +++ b/Sources/ResgenSwift/Images/Images.swift @@ -23,16 +23,6 @@ struct Images: ParsableCommand { static let toolName = "Images" 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 @OptionGroup var options: ImagesOptions @@ -54,6 +44,7 @@ struct Images: ParsableCommand { let inputFolder = URL(fileURLWithPath: options.inputFile) .deletingLastPathComponent() .relativePath + let xcassetsGenerator = XcassetsGenerator(forceGeneration: options.forceExecutionAndGeneration) xcassetsGenerator.generateXcassets(inputPath: inputFolder, imagesToGenerate: imagesToGenerate, @@ -61,10 +52,10 @@ struct Images: ParsableCommand { // Generate extension ImageExtensionGenerator.writeStringsFiles(images: imagesToGenerate, - staticVar: options.extensionName == Self.defaultExtensionName, - inputFilename: inputFilenameWithoutExt, + staticVar: options.staticMembers, + inputFilename: options.inputFilenameWithoutExt, extensionName: options.extensionName, - extensionFilePath: extensionFilePath) + extensionFilePath: options.extensionFilePath) print("[\(Self.toolName)] Images generated") @@ -90,7 +81,9 @@ struct Images: ParsableCommand { _ = Images.getSvgConverterPath() // 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 :) ") return false } diff --git a/Sources/ResgenSwift/Images/ImagesOptions.swift b/Sources/ResgenSwift/Images/ImagesOptions.swift index 7eb5831..b36001d 100644 --- a/Sources/ResgenSwift/Images/ImagesOptions.swift +++ b/Sources/ResgenSwift/Images/ImagesOptions.swift @@ -24,18 +24,33 @@ struct ImagesOptions: ParsableArguments { @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) var extensionOutputPath: String + @Option(help: "Tell if it will generate static properties or not") + var staticMembers: Bool = false + @Option(help: "Extension name. If not specified, it will generate an UIImage extension. Using default extension name will generate static property.") var extensionName: String = Images.defaultExtensionName @Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+Image{extensionSuffix}.swift") - var extensionSuffix: String = "" + var extensionSuffix: String? } +// MARK: - Computed var -/* - swift run -c release Imagium $FORCE_FLAG "./Images/sampleImages.txt" \ - --xcassets-path "./Images/imagium.xcassets" \ - --extension-output-path "./Images/Generated" \ - --extension-name "UIImage" \ - --extension-suffix "GenAllScript" - */ +extension ImagesOptions { + 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 + } +} diff --git a/Sources/ResgenSwift/Strings/Generator/StringsFileGenerator.swift b/Sources/ResgenSwift/Strings/Generator/StringsFileGenerator.swift index 83971fc..0beb811 100644 --- a/Sources/ResgenSwift/Strings/Generator/StringsFileGenerator.swift +++ b/Sources/ResgenSwift/Strings/Generator/StringsFileGenerator.swift @@ -98,7 +98,7 @@ class StringsFileGenerator { return // Go to next section } - content += "\n\t// MARK: - \(section.name)" + content += "\n // MARK: - \(section.name)" section.definitions.forEach { definition in guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else { return // Go to next definition diff --git a/Sources/ResgenSwift/Strings/Stringium/Stringium.swift b/Sources/ResgenSwift/Strings/Stringium/Stringium.swift index 626d5e9..72d577e 100644 --- a/Sources/ResgenSwift/Strings/Stringium/Stringium.swift +++ b/Sources/ResgenSwift/Strings/Stringium/Stringium.swift @@ -24,27 +24,6 @@ struct Stringium: ParsableCommand { static let defaultExtensionName = "String" 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 @OptionGroup var options: StringiumOptions @@ -68,16 +47,16 @@ struct Stringium: ParsableCommand { defaultLang: options.defaultLang, tags: options.tags, outputPath: options.stringsFileOutputPath, - inputFilenameWithoutExt: inputFilenameWithoutExt) + inputFilenameWithoutExt: options.inputFilenameWithoutExt) // Generate extension StringsFileGenerator.writeExtensionFiles(sections: sections, defaultLang: options.defaultLang, tags: options.tags, - staticVar: generateStaticVariable, - inputFilename: inputFilenameWithoutExt, + staticVar: options.staticMembers, + inputFilename: options.inputFilenameWithoutExt, extensionName: options.extensionName, - extensionFilePath: extensionFilePath) + extensionFilePath: options.extensionFilePath) print("[\(Self.toolName)] Strings generated") } @@ -108,7 +87,9 @@ struct Stringium: ParsableCommand { } // 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 :) ") return false } diff --git a/Sources/ResgenSwift/Strings/Stringium/StringiumOptions.swift b/Sources/ResgenSwift/Strings/Stringium/StringiumOptions.swift index 0277aa5..ab9e0cd 100644 --- a/Sources/ResgenSwift/Strings/Stringium/StringiumOptions.swift +++ b/Sources/ResgenSwift/Strings/Stringium/StringiumOptions.swift @@ -30,6 +30,9 @@ struct StringiumOptions: ParsableArguments { @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) var extensionOutputPath: String + @Option(help: "Tell if it will generate static properties or not") + var staticMembers: Bool = false + @Option(help: "Extension name. If not specified, it will generate an String extension. Using default extension name will generate static property.") var extensionName: String = Stringium.defaultExtensionName @@ -37,6 +40,8 @@ struct StringiumOptions: ParsableArguments { var extensionSuffix: String? } +// MARK: - Private var getter + extension StringiumOptions { var stringsFileOutputPath: String { var outputPath = outputPathRaw @@ -58,3 +63,24 @@ extension StringiumOptions { .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 + } +} diff --git a/Sources/ResgenSwift/Strings/Tag/Tags.swift b/Sources/ResgenSwift/Strings/Tag/Tags.swift index 6c9455d..d5fdccd 100644 --- a/Sources/ResgenSwift/Strings/Tag/Tags.swift +++ b/Sources/ResgenSwift/Strings/Tag/Tags.swift @@ -25,19 +25,6 @@ struct Tags: ParsableCommand { static let defaultExtensionName = "Tags" 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 @OptionGroup var options: TagsOptions @@ -59,9 +46,9 @@ struct Tags: ParsableCommand { TagsGenerator.writeExtensionFiles(sections: sections, lang: options.lang, tags: ["ios", "iosonly", Self.noTranslationTag], - staticVar: generateStaticVariable, + staticVar: options.staticMembers, extensionName: options.extensionName, - extensionFilePath: extensionFilePath) + extensionFilePath: options.extensionFilePath) print("[\(Self.toolName)] Tags generated") } @@ -79,7 +66,9 @@ struct Tags: ParsableCommand { } // 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 :) ") return false } diff --git a/Sources/ResgenSwift/Strings/Tag/TagsOptions.swift b/Sources/ResgenSwift/Strings/Tag/TagsOptions.swift index 4dc643a..3618ce0 100644 --- a/Sources/ResgenSwift/Strings/Tag/TagsOptions.swift +++ b/Sources/ResgenSwift/Strings/Tag/TagsOptions.swift @@ -21,9 +21,27 @@ struct TagsOptions: ParsableArguments { @Option(help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) var extensionOutputPath: String + @Option(help: "Tell if it will generate static properties or not") + var staticMembers: Bool = false + @Option(help: "Extension name. If not specified, it will generate a Tag extension. Using default extension name will generate static property.") var extensionName: String = Tags.defaultExtensionName @Option(help: "Extension suffix. Ex: MyApp, it will generate {extensionName}+Tag{extensionSuffix}.swift") 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)" + } +} diff --git a/Sources/ResgenSwift/Strings/Twine/Twine.swift b/Sources/ResgenSwift/Strings/Twine/Twine.swift index 97ae46d..e495a03 100644 --- a/Sources/ResgenSwift/Strings/Twine/Twine.swift +++ b/Sources/ResgenSwift/Strings/Twine/Twine.swift @@ -24,13 +24,6 @@ struct Twine: ParsableCommand { static let defaultExtensionName = "String" static let twineExecutable = "\(FileManager.default.homeDirectoryForCurrentUser.relativePath)/scripts/twine/twine" - // MARK: - Properties - - var inputFilenameWithoutExt: String { URL(fileURLWithPath: options.inputFile) - .deletingPathExtension() - .lastPathComponent - } - // MARK: - Command Options @OptionGroup var options: TwineOptions @@ -50,17 +43,16 @@ struct Twine: ParsableCommand { Shell.shell(Self.twineExecutable, "generate-localization-file", options.inputFile, "--lang", "\(lang)", - "\(options.outputPath)/\(lang).lproj/\(inputFilenameWithoutExt).strings", + "\(options.outputPath)/\(lang).lproj/\(options.inputFilenameWithoutExt).strings", "--tags=ios,iosonly,iosOnly") } // Generate extension - var extensionFilePath: String { "\(options.extensionOutputPath)/\(inputFilenameWithoutExt).swift" } Shell.shell(Self.twineExecutable, "generate-localization-file", options.inputFile, "--format", "apple-swift", "--lang", "\(options.defaultLang)", - extensionFilePath, + options.extensionFilePath, "--tags=ios,iosonly,iosOnly") print("[\(Self.toolName)] Strings generated") @@ -91,11 +83,10 @@ struct Twine: ParsableCommand { Twine.exit(withError: error) } - // "R2String+" is hardcoded in Twine formatter - let extensionFilePathGenerated = "\(options.extensionOutputPath)/R2String+\(inputFilenameWithoutExt).swift" - // 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 :) ") return false } diff --git a/Sources/ResgenSwift/Strings/Twine/TwineOptions.swift b/Sources/ResgenSwift/Strings/Twine/TwineOptions.swift index 4a3752a..3d79aff 100644 --- a/Sources/ResgenSwift/Strings/Twine/TwineOptions.swift +++ b/Sources/ResgenSwift/Strings/Twine/TwineOptions.swift @@ -28,6 +28,8 @@ struct TwineOptions: ParsableArguments { var extensionOutputPath: String } +// MARK: - Private var getter + extension TwineOptions { var langs: [String] { langsRaw @@ -35,3 +37,22 @@ extension TwineOptions { .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" + } +}