From 3510b60e973297a30c38114d173d3633d0090f2c Mon Sep 17 00:00:00 2001 From: Thibaut Schmitt Date: Tue, 22 Jul 2025 09:10:45 +0200 Subject: [PATCH 1/5] Handle bundle for Stringium --- .../Generator/StringsFileGenerator.swift | 44 ++- .../Strings/Generator/TagsGenerator.swift | 27 +- .../Strings/Model/Definition.swift | 79 ++---- .../Strings/Stringium/Stringium.swift | 5 +- .../Strings/Stringium/StringiumOptions.swift | 5 + Sources/ResgenSwift/Strings/Tag/Tags.swift | 2 +- Sources/ToolCore/AssetBundle.swift | 26 ++ .../Strings/DefinitionTests.swift | 264 +++++++++++++++--- ...ileGenerator+R2ExtensionsExpectation.swift | 11 +- .../StringsFileGeneratorTests.swift | 26 +- .../Strings/TagsGeneratorTests.swift | 2 +- 11 files changed, 335 insertions(+), 156 deletions(-) create mode 100644 Sources/ToolCore/AssetBundle.swift diff --git a/Sources/ResgenSwift/Strings/Generator/StringsFileGenerator.swift b/Sources/ResgenSwift/Strings/Generator/StringsFileGenerator.swift index ed03263..73b420d 100644 --- a/Sources/ResgenSwift/Strings/Generator/StringsFileGenerator.swift +++ b/Sources/ResgenSwift/Strings/Generator/StringsFileGenerator.swift @@ -247,23 +247,25 @@ enum StringsFileGenerator { sections: [Section], defaultLang lang: String, tags: [String], - staticVar: Bool, + isStatic: Bool, inputFilename: String, extensionName: String, extensionFilePath: String, extensionSuffix: String, - visibility: ExtensionVisibility + visibility: ExtensionVisibility, + assetBundle: AssetBundle ) { // Get extension content let extensionFileContent = Self.getExtensionContent( sections: sections, defaultLang: lang, tags: tags, - staticVar: staticVar, + isStatic: isStatic, inputFilename: inputFilename, extensionName: extensionName, extensionSuffix: extensionSuffix, - visibility: visibility + visibility: visibility, + assetBundle: assetBundle ) // Write content @@ -283,11 +285,12 @@ enum StringsFileGenerator { sections: [Section], defaultLang lang: String, tags: [String], - staticVar: Bool, + isStatic: Bool, inputFilename: String, extensionName: String, extensionSuffix: String, - visibility: ExtensionVisibility + visibility: ExtensionVisibility, + assetBundle: AssetBundle ) -> String { [ Self.getHeader( @@ -305,8 +308,9 @@ enum StringsFileGenerator { sections: sections, defaultLang: lang, tags: tags, - staticVar: staticVar, - visibility: visibility + isStatic: isStatic, + visibility: visibility, + assetBundle: assetBundle ), Self.getFooter() ] @@ -379,8 +383,9 @@ enum StringsFileGenerator { sections: [Section], defaultLang lang: String, tags: [String], - staticVar: Bool, - visibility: ExtensionVisibility + isStatic: Bool, + visibility: ExtensionVisibility, + assetBundle: AssetBundle ) -> String { sections.compactMap { section in // Check that at least one string will be generated @@ -394,19 +399,12 @@ enum StringsFileGenerator { return nil // Go to next definition } - let property: String = { - if staticVar { - definition.getNSLocalizedStringStaticProperty( - forLang: lang, - visibility: visibility - ) - } else { - definition.getNSLocalizedStringProperty( - forLang: lang, - visibility: visibility - ) - } - }() + let property = definition.getNSLocalizedStringProperty( + forLang: lang, + isStatic: isStatic, + visibility: visibility, + assetBundle: assetBundle + ) return "\n\(property)" } diff --git a/Sources/ResgenSwift/Strings/Generator/TagsGenerator.swift b/Sources/ResgenSwift/Strings/Generator/TagsGenerator.swift index 31b9b52..d0aed7c 100644 --- a/Sources/ResgenSwift/Strings/Generator/TagsGenerator.swift +++ b/Sources/ResgenSwift/Strings/Generator/TagsGenerator.swift @@ -15,7 +15,7 @@ enum TagsGenerator { sections: [Section], lang: String, tags: [String], - staticVar: Bool, + isStatic: Bool, extensionName: String, extensionFilePath: String, visibility: ExtensionVisibility @@ -25,7 +25,7 @@ enum TagsGenerator { sections: sections, lang: lang, tags: tags, - staticVar: staticVar, + isStatic: isStatic, extensionName: extensionName, visibility: visibility ) @@ -47,20 +47,20 @@ enum TagsGenerator { sections: [Section], lang: String, tags: [String], - staticVar: Bool, + isStatic: Bool, extensionName: String, visibility: ExtensionVisibility ) -> String { [ Self.getHeader( extensionClassname: extensionName, - staticVar: staticVar + isStatic: isStatic ), Self.getProperties( sections: sections, lang: lang, tags: tags, - staticVar: staticVar, + isStatic: isStatic, visibility: visibility ), Self.getFooter() @@ -70,11 +70,11 @@ enum TagsGenerator { // MARK: - Extension part - private static func getHeader(extensionClassname: String, staticVar: Bool) -> String { + private static func getHeader(extensionClassname: String, isStatic: Bool) -> String { """ // Generated by ResgenSwift.Strings.\(Tags.toolName) \(ResgenSwiftVersion) - \(staticVar ? "typelias Tags = String\n\n" : "")import UIKit + \(isStatic ? "typelias Tags = String\n\n" : "")import UIKit extension \(extensionClassname) { """ @@ -84,7 +84,7 @@ enum TagsGenerator { sections: [Section], lang: String, tags: [String], - staticVar: Bool, + isStatic: Bool, visibility: ExtensionVisibility ) -> String { sections @@ -100,11 +100,12 @@ enum TagsGenerator { return // Go to next definition } - if staticVar { - res += "\n\n\(definition.getStaticProperty(forLang: lang, visibility: visibility))" - } else { - res += "\n\n\(definition.getProperty(forLang: lang, visibility: visibility))" - } + let property = definition.getProperty( + forLang: lang, + visibility: visibility, + isStatic: isStatic + ) + res += "\n\n\(property)" } return res } diff --git a/Sources/ResgenSwift/Strings/Model/Definition.swift b/Sources/ResgenSwift/Strings/Model/Definition.swift index 9e6f156..02f2759 100644 --- a/Sources/ResgenSwift/Strings/Model/Definition.swift +++ b/Sources/ResgenSwift/Strings/Model/Definition.swift @@ -105,7 +105,8 @@ class Definition { translation: String, isStatic: Bool, comment: String?, - visibility: ExtensionVisibility + visibility: ExtensionVisibility, + assetBundle: AssetBundle ) -> String { """ /// Translation in \(lang) : @@ -114,7 +115,7 @@ class Definition { /// Comment : /// \(comment?.isEmpty == false ? comment! : "No comment") \(visibility) \(isStatic ? "static " : "")var \(name): String { - NSLocalizedString("\(name)", tableName: kStringsFileName, bundle: Bundle.main, value: "\(translation)", comment: "\(comment ?? "")") + NSLocalizedString("\(name)", tableName: kStringsFileName, bundle: Bundle.\(assetBundle), value: "\(translation)", comment: "\(comment ?? "")") } """ } @@ -141,7 +142,12 @@ class Definition { """ } - func getNSLocalizedStringProperty(forLang lang: String, visibility: ExtensionVisibility) -> String { + func getNSLocalizedStringProperty( + forLang lang: String, + isStatic: Bool, + visibility: ExtensionVisibility, + assetBundle: AssetBundle + ) -> String { guard let translation = translations[lang] else { let error = StringiumError.langNotDefined(lang, name, reference != nil) print(error.description) @@ -152,9 +158,10 @@ class Definition { let property = getBaseProperty( lang: lang, translation: translation, - isStatic: false, + isStatic: isStatic, comment: self.comment, - visibility: visibility + visibility: visibility, + assetBundle: assetBundle ) // Generate method @@ -163,40 +170,7 @@ class Definition { method = getBaseMethod( lang: lang, translation: translation, - isStatic: false, - inputParameters: parameters.inputParameters, - translationArguments: parameters.translationArguments, - comment: self.comment, - visibility: visibility - ) - } - - return property + method - } - - func getNSLocalizedStringStaticProperty(forLang lang: String, visibility: ExtensionVisibility) -> String { - guard let translation = translations[lang] else { - let error = StringiumError.langNotDefined(lang, name, reference != nil) - print(error.description) - Stringium.exit(withError: error) - } - - // Generate property - let property = getBaseProperty( - lang: lang, - translation: translation, - isStatic: true, - comment: self.comment, - visibility: visibility - ) - - // Generate method - var method = "" - if let parameters = self.getStringParameters(input: translation) { - method = getBaseMethod( - lang: lang, - translation: translation, - isStatic: true, + isStatic: isStatic, inputParameters: parameters.inputParameters, translationArguments: parameters.translationArguments, comment: self.comment, @@ -209,7 +183,11 @@ class Definition { // MARK: - Raw strings - func getProperty(forLang lang: String, visibility: ExtensionVisibility) -> String { + func getProperty( + forLang lang: String, + visibility: ExtensionVisibility, + isStatic: Bool + ) -> String { guard let translation = translations[lang] else { let error = StringiumError.langNotDefined(lang, name, reference != nil) print(error.description) @@ -222,26 +200,7 @@ class Definition { /// /// Comment : /// \(comment?.isEmpty == false ? comment! : "No comment") - \(visibility) var \(name): String { - "\(translation)" - } - """ - } - - func getStaticProperty(forLang lang: String, visibility: ExtensionVisibility) -> String { - guard let translation = translations[lang] else { - let error = StringiumError.langNotDefined(lang, name, reference != nil) - print(error.description) - Stringium.exit(withError: error) - } - - return """ - /// Translation in \(lang) : - /// \(translation) - /// - /// Comment : - /// \(comment?.isEmpty == false ? comment! : "No comment") - \(visibility) static var \(name): String { + \(visibility) \(isStatic ? "static " : "")var \(name): String { "\(translation)" } """ diff --git a/Sources/ResgenSwift/Strings/Stringium/Stringium.swift b/Sources/ResgenSwift/Strings/Stringium/Stringium.swift index 73cbbc4..b70ec40 100644 --- a/Sources/ResgenSwift/Strings/Stringium/Stringium.swift +++ b/Sources/ResgenSwift/Strings/Stringium/Stringium.swift @@ -68,12 +68,13 @@ struct Stringium: ParsableCommand { sections: sections, defaultLang: options.defaultLang, tags: options.tags, - staticVar: options.staticMembers, + isStatic: options.staticMembers, inputFilename: options.inputFilenameWithoutExt, extensionName: extensionName, extensionFilePath: extensionFilePath, extensionSuffix: options.extensionSuffix ?? "", - visibility: options.extensionVisibility + visibility: options.extensionVisibility, + assetBundle: options.assetBundle ) } diff --git a/Sources/ResgenSwift/Strings/Stringium/StringiumOptions.swift b/Sources/ResgenSwift/Strings/Stringium/StringiumOptions.swift index 1f9ae1a..e73fcc6 100644 --- a/Sources/ResgenSwift/Strings/Stringium/StringiumOptions.swift +++ b/Sources/ResgenSwift/Strings/Stringium/StringiumOptions.swift @@ -57,6 +57,11 @@ struct StringiumOptions: ParsableArguments { ) var extensionVisibility: ExtensionVisibility = .internal + @Option( + help: "Bundle where the asset are generated" + ) + var assetBundle: AssetBundle = .main + @Option( help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() } diff --git a/Sources/ResgenSwift/Strings/Tag/Tags.swift b/Sources/ResgenSwift/Strings/Tag/Tags.swift index 16cbcbc..f359207 100644 --- a/Sources/ResgenSwift/Strings/Tag/Tags.swift +++ b/Sources/ResgenSwift/Strings/Tag/Tags.swift @@ -47,7 +47,7 @@ struct Tags: ParsableCommand { sections: sections, lang: options.lang, tags: ["ios", "iosonly", Self.noTranslationTag], - staticVar: options.staticMembers, + isStatic: options.staticMembers, extensionName: options.extensionName, extensionFilePath: options.extensionFilePath, visibility: options.extensionVisibility diff --git a/Sources/ToolCore/AssetBundle.swift b/Sources/ToolCore/AssetBundle.swift new file mode 100644 index 0000000..fe7cd46 --- /dev/null +++ b/Sources/ToolCore/AssetBundle.swift @@ -0,0 +1,26 @@ +// +// AssetBundle.swift +// ResgenSwift +// +// Created by Thibaut Schmitt on 21/07/2025. +// + +import ArgumentParser + +package enum AssetBundle: String, CustomStringConvertible, ExpressibleByArgument { + + case main + case module + + // MARK: - CustomStringConvertible + + package var description: String { + switch self { + case .main: + "main" + + case .module: + "module" + } + } +} diff --git a/Tests/ResgenSwiftTests/Strings/DefinitionTests.swift b/Tests/ResgenSwiftTests/Strings/DefinitionTests.swift index e940245..4edd3ac 100644 --- a/Tests/ResgenSwiftTests/Strings/DefinitionTests.swift +++ b/Tests/ResgenSwiftTests/Strings/DefinitionTests.swift @@ -94,9 +94,24 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getNSLocalizedStringProperty(forLang: "fr", visibility: .public) - let propertyEn = definition.getNSLocalizedStringProperty(forLang: "en", visibility: .public) - let propertyEnUs = definition.getNSLocalizedStringProperty(forLang: "en-us", visibility: .public) + let propertyFr = definition.getNSLocalizedStringProperty( + forLang: "fr", + isStatic: false, + visibility: .public, + assetBundle: .main + ) + let propertyEn = definition.getNSLocalizedStringProperty( + forLang: "en", + isStatic: false, + visibility: .public, + assetBundle: .main + ) + let propertyEnUs = definition.getNSLocalizedStringProperty( + forLang: "en-us", + isStatic: false, + visibility: .public, + assetBundle: .main + ) // Expect let expectFr = """ @@ -149,9 +164,24 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getNSLocalizedStringProperty(forLang: "fr", visibility: .private) - let propertyEn = definition.getNSLocalizedStringProperty(forLang: "en", visibility: .private) - let propertyEnUs = definition.getNSLocalizedStringProperty(forLang: "en-us", visibility: .private) + let propertyFr = definition.getNSLocalizedStringProperty( + forLang: "fr", + isStatic: false, + visibility: .private, + assetBundle: .main + ) + let propertyEn = definition.getNSLocalizedStringProperty( + forLang: "en", + isStatic: false, + visibility: .private, + assetBundle: .main + ) + let propertyEnUs = definition.getNSLocalizedStringProperty( + forLang: "en-us", + isStatic: false, + visibility: .private, + assetBundle: .main + ) // Expect let expectFr = """ @@ -203,9 +233,24 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getNSLocalizedStringProperty(forLang: "fr", visibility: .public) - let propertyEn = definition.getNSLocalizedStringProperty(forLang: "en", visibility: .public) - let propertyEnUs = definition.getNSLocalizedStringProperty(forLang: "en-us", visibility: .public) + let propertyFr = definition.getNSLocalizedStringProperty( + forLang: "fr", + isStatic: false, + visibility: .public, + assetBundle: .main + ) + let propertyEn = definition.getNSLocalizedStringProperty( + forLang: "en", + isStatic: false, + visibility: .public, + assetBundle: .main + ) + let propertyEnUs = definition.getNSLocalizedStringProperty( + forLang: "en-us", + isStatic: false, + visibility: .public, + assetBundle: .main + ) // Expect let expectFr = """ @@ -246,7 +291,7 @@ final class DefinitionTests: XCTestCase { XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest()) } - // MARK: - getNSLocalizedStringStaticProperty + // MARK: - getNSLocalizedStringProperty - static func testGeneratedNSLocalizedStringStaticProperty() { // Given @@ -260,9 +305,24 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getNSLocalizedStringStaticProperty(forLang: "fr", visibility: .public) - let propertyEn = definition.getNSLocalizedStringStaticProperty(forLang: "en", visibility: .public) - let propertyEnUs = definition.getNSLocalizedStringStaticProperty(forLang: "en-us", visibility: .public) + let propertyFr = definition.getNSLocalizedStringProperty( + forLang: "fr", + isStatic: true, + visibility: .public, + assetBundle: .main + ) + let propertyEn = definition.getNSLocalizedStringProperty( + forLang: "en", + isStatic: true, + visibility: .public, + assetBundle: .main + ) + let propertyEnUs = definition.getNSLocalizedStringProperty( + forLang: "en-us", + isStatic: true, + visibility: .public, + assetBundle: .main + ) // Expect let expectFr = """ @@ -315,9 +375,24 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getNSLocalizedStringStaticProperty(forLang: "fr", visibility: .internal) - let propertyEn = definition.getNSLocalizedStringStaticProperty(forLang: "en", visibility: .internal) - let propertyEnUs = definition.getNSLocalizedStringStaticProperty(forLang: "en-us", visibility: .internal) + let propertyFr = definition.getNSLocalizedStringProperty( + forLang: "fr", + isStatic: true, + visibility: .internal, + assetBundle: .main + ) + let propertyEn = definition.getNSLocalizedStringProperty( + forLang: "en", + isStatic: true, + visibility: .internal, + assetBundle: .main + ) + let propertyEnUs = definition.getNSLocalizedStringProperty( + forLang: "en-us", + isStatic: true, + visibility: .internal, + assetBundle: .main + ) // Expect let expectFr = """ @@ -369,9 +444,24 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getNSLocalizedStringStaticProperty(forLang: "fr", visibility: .internal) - let propertyEn = definition.getNSLocalizedStringStaticProperty(forLang: "en", visibility: .internal) - let propertyEnUs = definition.getNSLocalizedStringStaticProperty(forLang: "en-us", visibility: .internal) + let propertyFr = definition.getNSLocalizedStringProperty( + forLang: "fr", + isStatic: true, + visibility: .internal, + assetBundle: .main + ) + let propertyEn = definition.getNSLocalizedStringProperty( + forLang: "en", + isStatic: true, + visibility: .internal, + assetBundle: .main + ) + let propertyEnUs = definition.getNSLocalizedStringProperty( + forLang: "en-us", + isStatic: true, + visibility: .internal, + assetBundle: .main + ) // Expect let expectFr = """ @@ -422,7 +512,12 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getNSLocalizedStringProperty(forLang: "fr", visibility: .internal) + let propertyFr = definition.getNSLocalizedStringProperty( + forLang: "fr", + isStatic: false, + visibility: .internal, + assetBundle: .main + ) // Expect let expectFr = """ @@ -458,7 +553,12 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getNSLocalizedStringProperty(forLang: "fr", visibility: .private) + let propertyFr = definition.getNSLocalizedStringProperty( + forLang: "fr", + isStatic: false, + visibility: .private, + assetBundle: .main + ) // Expect let expectFr = """ @@ -495,8 +595,18 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getNSLocalizedStringProperty(forLang: "fr", visibility: .public) - let propertyEn = definition.getNSLocalizedStringProperty(forLang: "en", visibility: .public) + let propertyFr = definition.getNSLocalizedStringProperty( + forLang: "fr", + isStatic: false, + visibility: .public, + assetBundle: .main + ) + let propertyEn = definition.getNSLocalizedStringProperty( + forLang: "en", + isStatic: false, + visibility: .public, + assetBundle: .main + ) let expectFr = """ /// Translation in fr : @@ -556,9 +666,21 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getProperty(forLang: "fr", visibility: .public) - let propertyEn = definition.getProperty(forLang: "en", visibility: .public) - let propertyEnUs = definition.getProperty(forLang: "en-us", visibility: .public) + let propertyFr = definition.getProperty( + forLang: "fr", + visibility: .public, + isStatic: false + ) + let propertyEn = definition.getProperty( + forLang: "en", + visibility: .public, + isStatic: false + ) + let propertyEnUs = definition.getProperty( + forLang: "en-us", + visibility: .public, + isStatic: false + ) // Expect let expectFr = """ @@ -611,9 +733,21 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getProperty(forLang: "fr", visibility: .package) - let propertyEn = definition.getProperty(forLang: "en", visibility: .package) - let propertyEnUs = definition.getProperty(forLang: "en-us", visibility: .package) + let propertyFr = definition.getProperty( + forLang: "fr", + visibility: .package, + isStatic: false + ) + let propertyEn = definition.getProperty( + forLang: "en", + visibility: .package, + isStatic: false + ) + let propertyEnUs = definition.getProperty( + forLang: "en-us", + visibility: .package, + isStatic: false + ) // Expect let expectFr = """ @@ -665,9 +799,21 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getProperty(forLang: "fr", visibility: .private) - let propertyEn = definition.getProperty(forLang: "en", visibility: .private) - let propertyEnUs = definition.getProperty(forLang: "en-us", visibility: .private) + let propertyFr = definition.getProperty( + forLang: "fr", + visibility: .private, + isStatic: false + ) + let propertyEn = definition.getProperty( + forLang: "en", + visibility: .private, + isStatic: false + ) + let propertyEnUs = definition.getProperty( + forLang: "en-us", + visibility: .private, + isStatic: false + ) // Expect let expectFr = """ @@ -722,9 +868,21 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getStaticProperty(forLang: "fr", visibility: .internal) - let propertyEn = definition.getStaticProperty(forLang: "en", visibility: .internal) - let propertyEnUs = definition.getStaticProperty(forLang: "en-us", visibility: .internal) + let propertyFr = definition.getProperty( + forLang: "fr", + visibility: .internal, + isStatic: true + ) + let propertyEn = definition.getProperty( + forLang: "en", + visibility: .internal, + isStatic: true + ) + let propertyEnUs = definition.getProperty( + forLang: "en-us", + visibility: .internal, + isStatic: true + ) // Expect let expectFr = """ @@ -777,9 +935,21 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getStaticProperty(forLang: "fr", visibility: .internal) - let propertyEn = definition.getStaticProperty(forLang: "en", visibility: .internal) - let propertyEnUs = definition.getStaticProperty(forLang: "en-us", visibility: .internal) + let propertyFr = definition.getProperty( + forLang: "fr", + visibility: .internal, + isStatic: true + ) + let propertyEn = definition.getProperty( + forLang: "en", + visibility: .internal, + isStatic: true + ) + let propertyEnUs = definition.getProperty( + forLang: "en-us", + visibility: .internal, + isStatic: true + ) // Expect let expectFr = """ @@ -831,9 +1001,21 @@ final class DefinitionTests: XCTestCase { ] // When - let propertyFr = definition.getStaticProperty(forLang: "fr", visibility: .internal) - let propertyEn = definition.getStaticProperty(forLang: "en", visibility: .internal) - let propertyEnUs = definition.getStaticProperty(forLang: "en-us", visibility: .internal) + let propertyFr = definition.getProperty( + forLang: "fr", + visibility: .internal, + isStatic: true + ) + let propertyEn = definition.getProperty( + forLang: "en", + visibility: .internal, + isStatic: true + ) + let propertyEnUs = definition.getProperty( + forLang: "en-us", + visibility: .internal, + isStatic: true + ) // Expect let expectFr = """ diff --git a/Tests/ResgenSwiftTests/Strings/StringFileGeneratorTests/Expectation/StringsFileGenerator+R2ExtensionsExpectation.swift b/Tests/ResgenSwiftTests/Strings/StringFileGeneratorTests/Expectation/StringsFileGenerator+R2ExtensionsExpectation.swift index 4632cba..d57ab95 100644 --- a/Tests/ResgenSwiftTests/Strings/StringFileGeneratorTests/Expectation/StringsFileGenerator+R2ExtensionsExpectation.swift +++ b/Tests/ResgenSwiftTests/Strings/StringFileGeneratorTests/Expectation/StringsFileGenerator+R2ExtensionsExpectation.swift @@ -20,7 +20,8 @@ extension StringsFileGeneratorTests { s2DefOneComment: String = "", s2DefTwoFr: String = "Section Deux - Definition Deux", s2DefTwoComment: String = "", - visibility: ExtensionVisibility = .internal + visibility: ExtensionVisibility = .internal, + assetBundle: AssetBundle = .main ) -> String { """ // Generated by ResgenSwift.Strings.Stringium \(ResgenSwiftVersion) @@ -55,7 +56,7 @@ extension StringsFileGeneratorTests { /// Comment : /// \(s1DefOneComment.isEmpty ? "No comment" : s1DefOneComment) \(visibility) \(staticVar ? "static " : "")var s1_def_one: String { - NSLocalizedString("s1_def_one", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Un - Definition Un", comment: "\(s1DefOneComment)") + NSLocalizedString("s1_def_one", tableName: kStringsFileName, bundle: Bundle.\(assetBundle), value: "Section Un - Definition Un", comment: "\(s1DefOneComment)") } /// Translation in fr : @@ -64,7 +65,7 @@ extension StringsFileGeneratorTests { /// Comment : /// \(s1DefTwoComment.isEmpty ? "No comment" : s1DefTwoComment) \(visibility) \(staticVar ? "static " : "")var s1_def_two: String { - NSLocalizedString("s1_def_two", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Un - Definition Deux", comment: "\(s1DefTwoComment)") + NSLocalizedString("s1_def_two", tableName: kStringsFileName, bundle: Bundle.\(assetBundle), value: "Section Un - Definition Deux", comment: "\(s1DefTwoComment)") } // MARK: - section_two @@ -75,7 +76,7 @@ extension StringsFileGeneratorTests { /// Comment : /// \(s2DefOneComment.isEmpty ? "No comment" : s2DefOneComment) \(visibility) \(staticVar ? "static " : "")var s2_def_one: String { - NSLocalizedString("s2_def_one", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Deux - Definition Un", comment: "\(s2DefOneComment)") + NSLocalizedString("s2_def_one", tableName: kStringsFileName, bundle: Bundle.\(assetBundle), value: "Section Deux - Definition Un", comment: "\(s2DefOneComment)") } /// Translation in fr : @@ -84,7 +85,7 @@ extension StringsFileGeneratorTests { /// Comment : /// \(s2DefTwoComment.isEmpty ? "No comment" : s2DefTwoComment) \(visibility) \(staticVar ? "static " : "")var s2_def_two: String { - NSLocalizedString("s2_def_two", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Deux - Definition Deux", comment: "\(s2DefTwoComment)") + NSLocalizedString("s2_def_two", tableName: kStringsFileName, bundle: Bundle.\(assetBundle), value: "Section Deux - Definition Deux", comment: "\(s2DefTwoComment)") } } """ diff --git a/Tests/ResgenSwiftTests/Strings/StringFileGeneratorTests/StringsFileGeneratorTests.swift b/Tests/ResgenSwiftTests/Strings/StringFileGeneratorTests/StringsFileGeneratorTests.swift index b32ffe4..257bc66 100644 --- a/Tests/ResgenSwiftTests/Strings/StringFileGeneratorTests/StringsFileGeneratorTests.swift +++ b/Tests/ResgenSwiftTests/Strings/StringFileGeneratorTests/StringsFileGeneratorTests.swift @@ -377,11 +377,12 @@ final class StringsFileGeneratorTests: XCTestCase { sections: [sectionOne, sectionTwo], defaultLang: "fr", tags: ["ios", "iosonly", "notranslation"], - staticVar: false, + isStatic: false, inputFilename: "myInputFilename", extensionName: "GenStrings", extensionSuffix: "strings", - visibility: .internal + visibility: .internal, + assetBundle: .main ) // Expect @@ -411,11 +412,12 @@ final class StringsFileGeneratorTests: XCTestCase { sections: [sectionOne, sectionTwo], defaultLang: "fr", tags: ["ios", "iosonly", "notranslation"], - staticVar: false, + isStatic: false, inputFilename: "myInputFilename", extensionName: "GenStrings", extensionSuffix: "strings", - visibility: .public + visibility: .public, + assetBundle: .main ) // Expect @@ -445,17 +447,19 @@ final class StringsFileGeneratorTests: XCTestCase { sections: [sectionOne, sectionTwo], defaultLang: "fr", tags: ["ios", "iosonly", "notranslation"], - staticVar: true, + isStatic: true, inputFilename: "myInputFilename", extensionName: "GenStrings", extensionSuffix: "strings", - visibility: .package + visibility: .package, + assetBundle: .module ) // Expect let expect = Self.getExtensionContentExpectation( staticVar: true, - visibility: .package + visibility: .package, + assetBundle: .module ) if extensionContent != expect { @@ -480,11 +484,12 @@ final class StringsFileGeneratorTests: XCTestCase { sections: [sectionOne, sectionTwo], defaultLang: "fr", tags: ["ios", "iosonly", "notranslation"], - staticVar: true, + isStatic: true, inputFilename: "myInputFilename", extensionName: "GenStrings", extensionSuffix: "strings", - visibility: .internal + visibility: .internal, + assetBundle: .module ) // Expect @@ -494,7 +499,8 @@ final class StringsFileGeneratorTests: XCTestCase { s1DefTwoComment: "This is a comment", s2DefOneComment: "This is a comment", s2DefTwoComment: "This is a comment", - visibility: .internal + visibility: .internal, + assetBundle: .module ) if extensionContent != expect { diff --git a/Tests/ResgenSwiftTests/Strings/TagsGeneratorTests.swift b/Tests/ResgenSwiftTests/Strings/TagsGeneratorTests.swift index aa7e42d..35f5ec2 100644 --- a/Tests/ResgenSwiftTests/Strings/TagsGeneratorTests.swift +++ b/Tests/ResgenSwiftTests/Strings/TagsGeneratorTests.swift @@ -49,7 +49,7 @@ final class TagsGeneratorTests: XCTestCase { sections: [sectionOne, sectionTwo, sectionThree], lang: "ium", tags: ["ios", "iosonly"], - staticVar: false, + isStatic: false, extensionName: "GenTags", visibility: .public ) -- 2.39.5 From d7dd37c32dfa960f07e4c47ce294f9ba8441fbf5 Mon Sep 17 00:00:00 2001 From: Thibaut Schmitt Date: Fri, 25 Jul 2025 10:03:14 +0200 Subject: [PATCH 2/5] Handle bundle for Image and Color --- Sources/ResgenSwift/Colors/Colors.swift | 6 ++-- .../Colors/ColorsToolOptions.swift | 5 ++++ .../Generator/ColorExtensionGenerator.swift | 18 ++++++++---- .../Colors/Model/ParsedColor.swift | 7 +++-- .../Generator/ImageExtensionGenerator.swift | 25 ++++++++++++----- Sources/ResgenSwift/Images/Images.swift | 6 ++-- .../ResgenSwift/Images/ImagesOptions.swift | 5 ++++ .../Images/Model/ParsedImage.swift | 11 ++++++-- .../Colors/ColorExtensionGeneratorTests.swift | 28 +++++++++++-------- .../Colors/ParsedColorTests.swift | 20 +++++++------ .../Images/ImageExtensionGeneratorTests.swift | 28 +++++++++++-------- .../Images/ParsedImageTests.swift | 20 +++++++------ 12 files changed, 116 insertions(+), 63 deletions(-) diff --git a/Sources/ResgenSwift/Colors/Colors.swift b/Sources/ResgenSwift/Colors/Colors.swift index 0b8843c..75a67d8 100644 --- a/Sources/ResgenSwift/Colors/Colors.swift +++ b/Sources/ResgenSwift/Colors/Colors.swift @@ -63,7 +63,8 @@ struct Colors: ParsableCommand { extensionName: extensionName, extensionFilePath: extensionFilePath, isSwiftUI: true, - visibility: options.extensionVisibility + visibility: options.extensionVisibility, + assetBundle: options.assetBundle ) } @@ -76,7 +77,8 @@ struct Colors: ParsableCommand { extensionName: extensionNameUIKit, extensionFilePath: extensionFilePathUIKit, isSwiftUI: false, - visibility: options.extensionVisibility + visibility: options.extensionVisibility, + assetBundle: options.assetBundle ) } diff --git a/Sources/ResgenSwift/Colors/ColorsToolOptions.swift b/Sources/ResgenSwift/Colors/ColorsToolOptions.swift index 0427c7e..d06cc1d 100644 --- a/Sources/ResgenSwift/Colors/ColorsToolOptions.swift +++ b/Sources/ResgenSwift/Colors/ColorsToolOptions.swift @@ -44,6 +44,11 @@ struct ColorsToolOptions: ParsableArguments { ) var extensionVisibility: ExtensionVisibility = .internal + @Option( + help: "Bundle where the asset are generated" + ) + var assetBundle: AssetBundle = .main + @Option( help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() } diff --git a/Sources/ResgenSwift/Colors/Generator/ColorExtensionGenerator.swift b/Sources/ResgenSwift/Colors/Generator/ColorExtensionGenerator.swift index dc4ef2b..3701c72 100644 --- a/Sources/ResgenSwift/Colors/Generator/ColorExtensionGenerator.swift +++ b/Sources/ResgenSwift/Colors/Generator/ColorExtensionGenerator.swift @@ -21,7 +21,8 @@ struct ColorExtensionGenerator { extensionName: String, extensionFilePath: String, isSwiftUI: Bool, - visibility: ExtensionVisibility + visibility: ExtensionVisibility, + assetBundle: AssetBundle ) { // Create extension content let extensionContent = Self.getExtensionContent( @@ -29,7 +30,8 @@ struct ColorExtensionGenerator { staticVar: staticVar, extensionName: extensionName, isSwiftUI: isSwiftUI, - visibility: visibility + visibility: visibility, + assetBundle: assetBundle ) // Write content @@ -48,7 +50,8 @@ struct ColorExtensionGenerator { staticVar: Bool, extensionName: String, isSwiftUI: Bool, - visibility: ExtensionVisibility + visibility: ExtensionVisibility, + assetBundle: AssetBundle ) -> String { [ Self.getHeader( @@ -59,7 +62,8 @@ struct ColorExtensionGenerator { for: colors, withStaticVar: staticVar, isSwiftUI: isSwiftUI, - visibility: visibility + visibility: visibility, + assetBundle: assetBundle ), Self.getFooter() ] @@ -87,13 +91,15 @@ struct ColorExtensionGenerator { for colors: [ParsedColor], withStaticVar staticVar: Bool, isSwiftUI: Bool, - visibility: ExtensionVisibility + visibility: ExtensionVisibility, + assetBundle: AssetBundle ) -> String { colors.map { $0.getColorProperty( isStatic: staticVar, isSwiftUI: isSwiftUI, - visibility: visibility + visibility: visibility, + assetBundle: assetBundle ) } .joined(separator: "\n\n") diff --git a/Sources/ResgenSwift/Colors/Model/ParsedColor.swift b/Sources/ResgenSwift/Colors/Model/ParsedColor.swift index e4fe09c..7c2e240 100644 --- a/Sources/ResgenSwift/Colors/Model/ParsedColor.swift +++ b/Sources/ResgenSwift/Colors/Model/ParsedColor.swift @@ -83,20 +83,21 @@ struct ParsedColor { func getColorProperty( isStatic: Bool, isSwiftUI: Bool, - visibility: ExtensionVisibility + visibility: ExtensionVisibility, + assetBundle: AssetBundle ) -> String { if isSwiftUI { return """ /// Color \(name) is \(light) (light) or \(dark) (dark)" \(visibility) \(isStatic ? "static " : "")var \(name): Color { - Color("\(name)") + Color("\(name)", bundle: Bundle.\(assetBundle)) } """ } return """ /// Color \(name) is \(light) (light) or \(dark) (dark)" \(isStatic ? "" : "@objc ")\(visibility) \(isStatic ? "static " : "")var \(name): UIColor { - UIColor(named: "\(name)")! + UIColor(named: "\(name)", in: Bundle.\(assetBundle), compatibleWith: nil)! } """ } diff --git a/Sources/ResgenSwift/Images/Generator/ImageExtensionGenerator.swift b/Sources/ResgenSwift/Images/Generator/ImageExtensionGenerator.swift index 291abbd..3346bf0 100644 --- a/Sources/ResgenSwift/Images/Generator/ImageExtensionGenerator.swift +++ b/Sources/ResgenSwift/Images/Generator/ImageExtensionGenerator.swift @@ -19,7 +19,8 @@ enum ImageExtensionGenerator { extensionName: String, extensionFilePath: String, isSwiftUI: Bool, - visibility: ExtensionVisibility + visibility: ExtensionVisibility, + assetBundle: AssetBundle ) { // Create extension conten1t let extensionContent = Self.getExtensionContent( @@ -28,7 +29,8 @@ enum ImageExtensionGenerator { extensionName: extensionName, inputFilename: inputFilename, isSwiftUI: isSwiftUI, - visibility: visibility + visibility: visibility, + assetBundle: assetBundle ) // Write content @@ -48,7 +50,8 @@ enum ImageExtensionGenerator { extensionName: String, inputFilename: String, isSwiftUI: Bool, - visibility: ExtensionVisibility + visibility: ExtensionVisibility, + assetBundle: AssetBundle ) -> String { [ Self.getHeader( @@ -60,7 +63,8 @@ enum ImageExtensionGenerator { images: images, staticVar: staticVar, isSwiftUI: isSwiftUI, - visibility: visibility + visibility: visibility, + assetBundle: assetBundle ), Self.getFooter() ] @@ -86,11 +90,18 @@ enum ImageExtensionGenerator { images: [ParsedImage], staticVar: Bool, isSwiftUI: Bool, - visibility: ExtensionVisibility + visibility: ExtensionVisibility, + assetBundle: AssetBundle ) -> String { images - .map { - "\n\($0.getImageProperty(isStatic: staticVar, isSwiftUI: isSwiftUI, visibility: visibility))" + .map { parsedImage in + let property = parsedImage.getImageProperty( + isStatic: staticVar, + isSwiftUI: isSwiftUI, + visibility: visibility, + assetBundle: assetBundle + ) + return "\n\(property)" } .joined(separator: "\n") } diff --git a/Sources/ResgenSwift/Images/Images.swift b/Sources/ResgenSwift/Images/Images.swift index be34353..3e7c1e1 100644 --- a/Sources/ResgenSwift/Images/Images.swift +++ b/Sources/ResgenSwift/Images/Images.swift @@ -62,7 +62,8 @@ struct Images: ParsableCommand { extensionName: extensionName, extensionFilePath: extensionFilePath, isSwiftUI: true, - visibility: options.extensionVisibility + visibility: options.extensionVisibility, + assetBundle: options.assetBundle ) } @@ -75,7 +76,8 @@ struct Images: ParsableCommand { extensionName: extensionNameUIKit, extensionFilePath: extensionFilePathUIKit, isSwiftUI: false, - visibility: options.extensionVisibility + visibility: options.extensionVisibility, + assetBundle: options.assetBundle ) } diff --git a/Sources/ResgenSwift/Images/ImagesOptions.swift b/Sources/ResgenSwift/Images/ImagesOptions.swift index 5f4e6b4..c0d20e2 100644 --- a/Sources/ResgenSwift/Images/ImagesOptions.swift +++ b/Sources/ResgenSwift/Images/ImagesOptions.swift @@ -51,6 +51,11 @@ struct ImagesOptions: ParsableArguments { ) var extensionVisibility: ExtensionVisibility = .internal + @Option( + help: "Bundle where the asset are generated" + ) + var assetBundle: AssetBundle = .main + @Option( help: "Path where to generate the extension.", transform: { $0.replaceTiltWithHomeDirectoryPath() } diff --git a/Sources/ResgenSwift/Images/Model/ParsedImage.swift b/Sources/ResgenSwift/Images/Model/ParsedImage.swift index 50381f1..2404d4f 100644 --- a/Sources/ResgenSwift/Images/Model/ParsedImage.swift +++ b/Sources/ResgenSwift/Images/Model/ParsedImage.swift @@ -130,17 +130,22 @@ struct ParsedImage { // MARK: - Extension property - func getImageProperty(isStatic: Bool, isSwiftUI: Bool, visibility: ExtensionVisibility) -> String { + func getImageProperty( + isStatic: Bool, + isSwiftUI: Bool, + visibility: ExtensionVisibility, + assetBundle: AssetBundle + ) -> String { if isSwiftUI { return """ \(visibility) \(isStatic ? "static " : "")var \(name): Image { - Image("\(name)") + Image("\(name)", bundle: Bundle.\(assetBundle)) } """ } return """ \(visibility) \(isStatic ? "static " : "")var \(name): UIImage { - UIImage(named: "\(name)")! + UIImage(named: "\(name)", in: Bundle.\(assetBundle), with: nil)! } """ } diff --git a/Tests/ResgenSwiftTests/Colors/ColorExtensionGeneratorTests.swift b/Tests/ResgenSwiftTests/Colors/ColorExtensionGeneratorTests.swift index a914425..4ed0811 100644 --- a/Tests/ResgenSwiftTests/Colors/ColorExtensionGeneratorTests.swift +++ b/Tests/ResgenSwiftTests/Colors/ColorExtensionGeneratorTests.swift @@ -26,7 +26,8 @@ final class ColorExtensionGeneratorTests: XCTestCase { staticVar: false, extensionName: "GenColors", isSwiftUI: false, - visibility: .public + visibility: .public, + assetBundle: .main ) // Expect @@ -39,12 +40,12 @@ final class ColorExtensionGeneratorTests: XCTestCase { /// Color colorOne is #FF00FF (light) or #00FF00 (dark)" @objc public var colorOne: UIColor { - UIColor(named: "colorOne")! + UIColor(named: "colorOne", in: Bundle.main, compatibleWith: nil)! } /// Color colorTwo is #F0F0F0 (light) or #0F0F0F (dark)" @objc public var colorTwo: UIColor { - UIColor(named: "colorTwo")! + UIColor(named: "colorTwo", in: Bundle.main, compatibleWith: nil)! } } """ @@ -65,7 +66,8 @@ final class ColorExtensionGeneratorTests: XCTestCase { staticVar: true, extensionName: "GenColor", isSwiftUI: false, - visibility: .public + visibility: .public, + assetBundle: .module ) // Expect @@ -78,12 +80,12 @@ final class ColorExtensionGeneratorTests: XCTestCase { /// Color colorOne is #FF00FF (light) or #00FF00 (dark)" public static var colorOne: UIColor { - UIColor(named: "colorOne")! + UIColor(named: "colorOne", in: Bundle.module, compatibleWith: nil)! } /// Color colorTwo is #F0F0F0 (light) or #0F0F0F (dark)" public static var colorTwo: UIColor { - UIColor(named: "colorTwo")! + UIColor(named: "colorTwo", in: Bundle.module, compatibleWith: nil)! } } """ @@ -104,7 +106,8 @@ final class ColorExtensionGeneratorTests: XCTestCase { staticVar: false, extensionName: "GenColors", isSwiftUI: true, - visibility: .package + visibility: .package, + assetBundle: .main ) // Expect @@ -117,12 +120,12 @@ final class ColorExtensionGeneratorTests: XCTestCase { /// Color colorOne is #FF00FF (light) or #00FF00 (dark)" package var colorOne: Color { - Color("colorOne") + Color("colorOne", bundle: Bundle.main) } /// Color colorTwo is #F0F0F0 (light) or #0F0F0F (dark)" package var colorTwo: Color { - Color("colorTwo") + Color("colorTwo", bundle: Bundle.main) } } """ @@ -143,7 +146,8 @@ final class ColorExtensionGeneratorTests: XCTestCase { staticVar: true, extensionName: "GenColor", isSwiftUI: true, - visibility: .internal + visibility: .internal, + assetBundle: .module ) // Expect @@ -156,12 +160,12 @@ final class ColorExtensionGeneratorTests: XCTestCase { /// Color colorOne is #FF00FF (light) or #00FF00 (dark)" internal static var colorOne: Color { - Color("colorOne") + Color("colorOne", bundle: Bundle.module) } /// Color colorTwo is #F0F0F0 (light) or #0F0F0F (dark)" internal static var colorTwo: Color { - Color("colorTwo") + Color("colorTwo", bundle: Bundle.module) } } """ diff --git a/Tests/ResgenSwiftTests/Colors/ParsedColorTests.swift b/Tests/ResgenSwiftTests/Colors/ParsedColorTests.swift index 1c03720..cadcc3d 100644 --- a/Tests/ResgenSwiftTests/Colors/ParsedColorTests.swift +++ b/Tests/ResgenSwiftTests/Colors/ParsedColorTests.swift @@ -20,14 +20,15 @@ final class ParsedColorTests: XCTestCase { let property = color.getColorProperty( isStatic: false, isSwiftUI: false, - visibility: .public + visibility: .public, + assetBundle: .main ) // Expect let expect = """ /// Color red is #FF0000 (light) or #0000FF (dark)" @objc public var red: UIColor { - UIColor(named: "red")! + UIColor(named: "red", in: Bundle.main, compatibleWith: nil)! } """ @@ -42,14 +43,15 @@ final class ParsedColorTests: XCTestCase { let property = color.getColorProperty( isStatic: true, isSwiftUI: false, - visibility: .private + visibility: .private, + assetBundle: .module ) // Expect let expect = """ /// Color red is #FF0000 (light) or #0000FF (dark)" private static var red: UIColor { - UIColor(named: "red")! + UIColor(named: "red", in: Bundle.module, compatibleWith: nil)! } """ @@ -64,14 +66,15 @@ final class ParsedColorTests: XCTestCase { let property = color.getColorProperty( isStatic: false, isSwiftUI: true, - visibility: .package + visibility: .package, + assetBundle: .main ) // Expect let expect = """ /// Color red is #FF0000 (light) or #0000FF (dark)" package var red: Color { - Color("red") + Color("red", bundle: Bundle.main) } """ @@ -86,14 +89,15 @@ final class ParsedColorTests: XCTestCase { let property = color.getColorProperty( isStatic: true, isSwiftUI: true, - visibility: .internal + visibility: .internal, + assetBundle: .module ) // Expect let expect = """ /// Color red is #FF0000 (light) or #0000FF (dark)" internal static var red: Color { - Color("red") + Color("red", bundle: Bundle.module) } """ diff --git a/Tests/ResgenSwiftTests/Images/ImageExtensionGeneratorTests.swift b/Tests/ResgenSwiftTests/Images/ImageExtensionGeneratorTests.swift index 995b5d9..d0db112 100644 --- a/Tests/ResgenSwiftTests/Images/ImageExtensionGeneratorTests.swift +++ b/Tests/ResgenSwiftTests/Images/ImageExtensionGeneratorTests.swift @@ -27,7 +27,8 @@ final class ImageExtensionGeneratorTests: XCTestCase { extensionName: "GenImages", inputFilename: "myInputFilename", isSwiftUI: false, - visibility: .public + visibility: .public, + assetBundle: .main ) // Expect @@ -40,11 +41,11 @@ final class ImageExtensionGeneratorTests: XCTestCase { extension GenImages { public var image_one: UIImage { - UIImage(named: "image_one")! + UIImage(named: "image_one", in: Bundle.main, with: nil)! } public var image_two: UIImage { - UIImage(named: "image_two")! + UIImage(named: "image_two", in: Bundle.main, with: nil)! } } """ @@ -66,7 +67,8 @@ final class ImageExtensionGeneratorTests: XCTestCase { extensionName: "GenImages", inputFilename: "myInputFilename", isSwiftUI: false, - visibility: .internal + visibility: .internal, + assetBundle: .module ) // Expect @@ -79,11 +81,11 @@ final class ImageExtensionGeneratorTests: XCTestCase { extension GenImages { internal static var image_one: UIImage { - UIImage(named: "image_one")! + UIImage(named: "image_one", in: Bundle.module, with: nil)! } internal static var image_two: UIImage { - UIImage(named: "image_two")! + UIImage(named: "image_two", in: Bundle.module, with: nil)! } } """ @@ -105,7 +107,8 @@ final class ImageExtensionGeneratorTests: XCTestCase { extensionName: "GenImages", inputFilename: "myInputFilename", isSwiftUI: true, - visibility: .public + visibility: .public, + assetBundle: .main ) // Expect @@ -118,11 +121,11 @@ final class ImageExtensionGeneratorTests: XCTestCase { extension GenImages { public var image_one: Image { - Image("image_one") + Image("image_one", bundle: Bundle.main) } public var image_two: Image { - Image("image_two") + Image("image_two", bundle: Bundle.main) } } """ @@ -144,7 +147,8 @@ final class ImageExtensionGeneratorTests: XCTestCase { extensionName: "GenImages", inputFilename: "myInputFilename", isSwiftUI: true, - visibility: .package + visibility: .package, + assetBundle: .module ) // Expect @@ -157,11 +161,11 @@ final class ImageExtensionGeneratorTests: XCTestCase { extension GenImages { package static var image_one: Image { - Image("image_one") + Image("image_one", bundle: Bundle.module) } package static var image_two: Image { - Image("image_two") + Image("image_two", bundle: Bundle.module) } } """ diff --git a/Tests/ResgenSwiftTests/Images/ParsedImageTests.swift b/Tests/ResgenSwiftTests/Images/ParsedImageTests.swift index 4d332e1..ea11035 100644 --- a/Tests/ResgenSwiftTests/Images/ParsedImageTests.swift +++ b/Tests/ResgenSwiftTests/Images/ParsedImageTests.swift @@ -48,13 +48,14 @@ final class ParsedImageTests: XCTestCase { let property = parsedImage.getImageProperty( isStatic: false, isSwiftUI: false, - visibility: .public + visibility: .public, + assetBundle: .main ) // Expect let expect = """ public var \(imageName): UIImage { - UIImage(named: "\(imageName)")! + UIImage(named: "\(imageName)", in: Bundle.main, with: nil)! } """ @@ -75,13 +76,14 @@ final class ParsedImageTests: XCTestCase { let property = parsedImage.getImageProperty( isStatic: true, isSwiftUI: false, - visibility: .internal + visibility: .internal, + assetBundle: .module ) // Expect let expect = """ internal static var \(imageName): UIImage { - UIImage(named: "\(imageName)")! + UIImage(named: "\(imageName)", in: Bundle.module, with: nil)! } """ @@ -102,13 +104,14 @@ final class ParsedImageTests: XCTestCase { let property = parsedImage.getImageProperty( isStatic: false, isSwiftUI: true, - visibility: .private + visibility: .private, + assetBundle: .main ) // Expect let expect = """ private var \(imageName): Image { - Image("\(imageName)") + Image("\(imageName)", bundle: Bundle.main) } """ @@ -129,13 +132,14 @@ final class ParsedImageTests: XCTestCase { let property = parsedImage.getImageProperty( isStatic: true, isSwiftUI: true, - visibility: .package + visibility: .package, + assetBundle: .module ) // Expect let expect = """ package static var \(imageName): Image { - Image("\(imageName)") + Image("\(imageName)", bundle: Bundle.module) } """ -- 2.39.5 From 058624fa6ac20bc9bb112817f3ac20320702df50 Mon Sep 17 00:00:00 2001 From: Thibaut Schmitt Date: Fri, 25 Jul 2025 11:19:54 +0200 Subject: [PATCH 3/5] Update Generate command and Readme --- README.md | 444 +++++++++++++----- .../Generate/Model/ConfigurationFile.swift | 12 + .../ColorsConfiguration+Runnable.swift | 1 + .../ImagesConfiguration+Runnable.swift | 1 + .../StringsConfiguration+Runnable.swift | 1 + .../Generate/ColorsConfigurationTests.swift | 4 + .../Generate/ImagesConfigurationTests.swift | 4 + .../Generate/StringsConfigurationTests.swift | 4 + 8 files changed, 348 insertions(+), 123 deletions(-) diff --git a/README.md b/README.md index 8beb9de..f37d7fd 100644 --- a/README.md +++ b/README.md @@ -10,57 +10,114 @@ Font generator generates an extension of `UIFont` and `Font` (or custom classes) 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`. So, be sure that your `$PATH` variable contains path of `fc-scan`. + +```sh +USAGE: +swift run -c release ResgenSwift fonts [-f] --extension-output-path \ + [--static-members ] \ + [--visibility ] \ + [--extension-name ] \ + [--extension-name-ui-kit ] \ + [--extension-suffix ] \ + [--info-plist-paths ] + +ARGUMENTS: + Input files where fonts ared defined. + +OPTIONS: + -f, -F Should force generation + --static-members + Tell if it will generate static properties or methods (default: false) + --visibility + Visibility of extension and properties. Possibles values: public, private, package, internal. Default is internal (default: internal) + --extension-output-path + Path where to generate the extension. + --extension-name + Extension name. If not specified, it will generate an Font extension. (default: Font) + --extension-name-ui-kit + Extension name. If not specified, no extension will be generated. + --extension-suffix + Extension suffix. Ex: MyApp, it will generate {extensionName}+FontsMyApp.swift + --info-plist-paths + Info.plist paths (array). Will be used to update UIAppFonts content + --version Show the version. + -h, --help Show help information. +``` + **Example** ```sh -swift run -c release ResgenSwift fonts $FORCE_FLAG "./Fonts/fonts.txt" \ +swift run -c release ResgenSwift fonts -f "./Fonts/fonts.txt" \ --extension-output-path "./Fonts/Generated" \ + --static-members true \ + --visibility "public" \ --extension-name "AppFont" \ --extension-name-ui-kit "UIAppFont" \ --extension-suffix "GreatApp" \ - --static-members true \ - --info-plist-paths "./path/one/to/Info.plist ./path/two/to/Info.plist" + --info-plist-paths "./path/one/to/Info.plist ./path/two/to/Info.plist" ``` -**Parameters** - -1. `-f`: force generation -2. Font input folder, it will search for every `.ttf` and `.otf` files specified in `fonts.txt` -3. `--extension-output-path`: path where to generate generated extension -4. `--extension-name` *(optional)* : name of the class to add SwiftUI getters -5. `--extension-name-ui-kit` *(optional)* : name of the class to add UIKit getters -6. `--extension-suffix` *(optional)* : additional text which is added to the filename (ex: `AppFont+GreatApp.swift`) -7. `--static-members` *(optional)*: generate static properties or not -8. `--info-plist-paths` *(optional)*: array of `.plist`, you can specify multiple `Info.plist` for multiple targets - - ## Colors Colors generator generates colorsets in specified xcassets and an extension of `Color` (or a custom class) associated to those colorsets. If the extension name is not specified, no extension will be generated. + ```sh -swift run -c release ResgenSwift colors $FORCE_FLAG "./Colors/colors.txt" \ - --style all \ - --xcassets-path "./Colors/colors.xcassets" \ - --extension-output-path "./Colors/Generated/" \ - --extension-name "AppColor" \ - --extension-name-ui-kit "UIAppColor" \ - --extension-suffix "GreatApp" \ - --static-members true +USAGE: +swift run -c release ResgenSwift colors [-f] \ + --style