From c11112118b15ea1e1b0eb199958a22c46b82c5fc Mon Sep 17 00:00:00 2001 From: Andreas Neusuess Date: Thu, 8 Jan 2026 16:15:25 -0800 Subject: [PATCH 1/2] Provide actool with known localizations from project --- .../AssetCatalogCompiler.swift | 11 +++ .../Specs/AssetCatalogCompiler.xcspec | 7 ++ Sources/SWBCore/Settings/BuiltinMacros.swift | 2 + .../AssetCatalogTaskConstructionTests.swift | 90 +++++++++++++++++++ 4 files changed, 110 insertions(+) diff --git a/Sources/SWBApplePlatform/AssetCatalogCompiler.swift b/Sources/SWBApplePlatform/AssetCatalogCompiler.swift index a0e1117c7..84a2ae85a 100644 --- a/Sources/SWBApplePlatform/AssetCatalogCompiler.swift +++ b/Sources/SWBApplePlatform/AssetCatalogCompiler.swift @@ -177,6 +177,17 @@ public final class ActoolCompilerSpec : GenericCompilerSpec, SpecIdentifierType, return [base, region, path].joined(separator: ":") })) + case BuiltinMacros.ASSETCATALOG_COMPILER_INCLUDED_LANGUAGES: + if cbc.scope.evaluate(BuiltinMacros.BUILD_ONLY_KNOWN_LOCALIZATIONS), var knownLocalizations = cbc.producer.project?.knownLocalizations { + + knownLocalizations.removeAll(where: { $0 == "Base" }) + if !knownLocalizations.isEmpty { + delegate.note("Asset Catalog will compile languages for known regions: \(knownLocalizations.joined(separator: ", "))", location: .path(cbc.input.absolutePath)) + } + return cbc.scope.namespace.parseLiteralStringList(knownLocalizations) + } + return nil + default: return nil } diff --git a/Sources/SWBApplePlatform/Specs/AssetCatalogCompiler.xcspec b/Sources/SWBApplePlatform/Specs/AssetCatalogCompiler.xcspec index a09bab73e..8dd4ed6e6 100644 --- a/Sources/SWBApplePlatform/Specs/AssetCatalogCompiler.xcspec +++ b/Sources/SWBApplePlatform/Specs/AssetCatalogCompiler.xcspec @@ -206,6 +206,13 @@ DefaultValue = "$(TARGET_TEMP_DIR)/assetcatalog_generated_info.plist"; CommandLineArgs = ( "--output-partial-info-plist", "$(value)" ); }, + + { + Name = ASSETCATALOG_COMPILER_INCLUDED_LANGUAGES; + Type = StringList; + DefaultValue = ""; + CommandLineFlag = "--include-languages"; + }, { Name = "ASSETCATALOG_COMPILER_STICKER_PACK_STRINGS"; diff --git a/Sources/SWBCore/Settings/BuiltinMacros.swift b/Sources/SWBCore/Settings/BuiltinMacros.swift index 7bc0c8c32..f04b62ad4 100644 --- a/Sources/SWBCore/Settings/BuiltinMacros.swift +++ b/Sources/SWBCore/Settings/BuiltinMacros.swift @@ -463,6 +463,7 @@ public final class BuiltinMacros { public static let ARCHS_STANDARD_64_BIT = BuiltinMacros.declareStringListMacro("ARCHS_STANDARD_64_BIT") public static let ARCHS_STANDARD_INCLUDING_64_BIT = BuiltinMacros.declareStringListMacro("ARCHS_STANDARD_INCLUDING_64_BIT") public static let ASSETCATALOG_COMPILER_DEPENDENCY_INFO_FILE = BuiltinMacros.declarePathMacro("ASSETCATALOG_COMPILER_DEPENDENCY_INFO_FILE") + public static let ASSETCATALOG_COMPILER_INCLUDED_LANGUAGES = BuiltinMacros.declareStringListMacro("ASSETCATALOG_COMPILER_INCLUDED_LANGUAGES") public static let ASSETCATALOG_COMPILER_INCLUDE_STICKER_CONTENT = BuiltinMacros.declareBooleanMacro("ASSETCATALOG_COMPILER_INCLUDE_STICKER_CONTENT") public static let ASSETCATALOG_COMPILER_INFOPLIST_CONTENT_FILE = BuiltinMacros.declarePathMacro("ASSETCATALOG_COMPILER_INFOPLIST_CONTENT_FILE") public static let ASSETCATALOG_COMPILER_INPUTS = BuiltinMacros.declarePathListMacro("ASSETCATALOG_COMPILER_INPUTS") @@ -1462,6 +1463,7 @@ public final class BuiltinMacros { ARCHS_STANDARD_64_BIT, ARCHS_STANDARD_INCLUDING_64_BIT, ASSETCATALOG_COMPILER_DEPENDENCY_INFO_FILE, + ASSETCATALOG_COMPILER_INCLUDED_LANGUAGES, ASSETCATALOG_COMPILER_INCLUDE_STICKER_CONTENT, ASSETCATALOG_COMPILER_INFOPLIST_CONTENT_FILE, ASSETCATALOG_COMPILER_INPUTS, diff --git a/Tests/SWBTaskConstructionTests/AssetCatalogTaskConstructionTests.swift b/Tests/SWBTaskConstructionTests/AssetCatalogTaskConstructionTests.swift index fa12c93f9..ccdf694ee 100644 --- a/Tests/SWBTaskConstructionTests/AssetCatalogTaskConstructionTests.swift +++ b/Tests/SWBTaskConstructionTests/AssetCatalogTaskConstructionTests.swift @@ -438,4 +438,94 @@ fileprivate struct AssetCatalogTaskConstructionTests: CoreBasedTests { } } } + + @Test(.requireSDKs(.macOS)) + func assetCatalogKnownLocalizationsFiltering() async throws { + let actoolPath = try await self.actoolPath + try await withTemporaryDirectory { tmpDir in + let testProject = TestProject( + "AssetCatalogKnownRegionsTest", + sourceRoot: tmpDir, + groupTree: TestGroup("Root", children: [ + TestFile("Assets.xcassets"), + ]), + buildConfigurations: [ + TestBuildConfiguration("Debug", buildSettings: [ + "ASSETCATALOG_EXEC": actoolPath.str, + "BUILD_ONLY_KNOWN_LOCALIZATIONS": "YES", + "PRODUCT_NAME": "$(TARGET_NAME)", + "GENERATE_INFOPLIST_FILE": "YES", + ]) + ], + targets: [ + TestStandardTarget("App", type: .application, + buildPhases: [ + TestResourcesBuildPhase([ + "Assets.xcassets", + ]) + ]) + ], + knownLocalizations: ["en", "de", "Base"] // Only en and de should be compiled + ) + + let tester = try await TaskConstructionTester(getCore(), testProject) + + await tester.checkBuild(runDestination: .macOS) { results in + + results.checkTask( + .matchRuleType("CompileAssetCatalogVariant"), + .matchRuleItem("thinned") + ) { task in + task.checkCommandLineContains(["--include-languages", "en"]) + task.checkCommandLineContains(["--include-languages", "de"]) + task.checkCommandLineDoesNotContain("Base") + } + results.checkNoDiagnostics() + } + } + } + + @Test(.requireSDKs(.macOS)) + func assetCatalogEmptyKnownLocalizations() async throws { + let actoolPath = try await self.actoolPath + try await withTemporaryDirectory { tmpDir in + let testProject = TestProject( + "AssetCatalogEmptyKnownLocalizationsTest", + sourceRoot: tmpDir, + groupTree: TestGroup("Root", children: [ + TestFile("Assets.xcassets"), + ]), + buildConfigurations: [ + TestBuildConfiguration("Debug", buildSettings: [ + "ASSETCATALOG_EXEC": actoolPath.str, + "BUILD_ONLY_KNOWN_LOCALIZATIONS": "YES", + "PRODUCT_NAME": "$(TARGET_NAME)", + "GENERATE_INFOPLIST_FILE": "YES", + ]) + ], + targets: [ + TestStandardTarget("App", type: .application, + buildPhases: [ + TestResourcesBuildPhase([ + "Assets.xcassets", + ]) + ]) + ], + knownLocalizations: [] // Empty array, all localizations should build + ) + + let tester = try await TaskConstructionTester(getCore(), testProject) + + await tester.checkBuild(runDestination: .macOS) { results in + results.checkTask( + .matchRuleType("CompileAssetCatalogVariant"), + .matchRuleItem("thinned") + ) { task in + // When knownLocalizations is empty, no --include-languages should appear + task.checkCommandLineDoesNotContain("--include-languages") + } + results.checkNoDiagnostics() + } + } + } } From 282951fbbc2a9b5ed5d8178a96137a548b591973 Mon Sep 17 00:00:00 2001 From: Andreas Neusuess Date: Thu, 8 Jan 2026 16:25:47 -0800 Subject: [PATCH 2/2] Remove Space --- Sources/SWBApplePlatform/AssetCatalogCompiler.swift | 2 +- Sources/SWBApplePlatform/Specs/AssetCatalogCompiler.xcspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/SWBApplePlatform/AssetCatalogCompiler.swift b/Sources/SWBApplePlatform/AssetCatalogCompiler.swift index 84a2ae85a..34fbc5823 100644 --- a/Sources/SWBApplePlatform/AssetCatalogCompiler.swift +++ b/Sources/SWBApplePlatform/AssetCatalogCompiler.swift @@ -187,7 +187,7 @@ public final class ActoolCompilerSpec : GenericCompilerSpec, SpecIdentifierType, return cbc.scope.namespace.parseLiteralStringList(knownLocalizations) } return nil - + default: return nil } diff --git a/Sources/SWBApplePlatform/Specs/AssetCatalogCompiler.xcspec b/Sources/SWBApplePlatform/Specs/AssetCatalogCompiler.xcspec index 8dd4ed6e6..36f3e05d6 100644 --- a/Sources/SWBApplePlatform/Specs/AssetCatalogCompiler.xcspec +++ b/Sources/SWBApplePlatform/Specs/AssetCatalogCompiler.xcspec @@ -206,7 +206,7 @@ DefaultValue = "$(TARGET_TEMP_DIR)/assetcatalog_generated_info.plist"; CommandLineArgs = ( "--output-partial-info-plist", "$(value)" ); }, - + { Name = ASSETCATALOG_COMPILER_INCLUDED_LANGUAGES; Type = StringList;