From ea4b8999513ff4c50c6e6b250b07f544a34252a5 Mon Sep 17 00:00:00 2001 From: freddi Date: Thu, 15 Feb 2024 17:05:18 +0900 Subject: [PATCH 1/2] create availableModule to avoid crash on Bundle loading --- Sources/XcodeGenKit/SettingsBuilder.swift | 48 ++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/Sources/XcodeGenKit/SettingsBuilder.swift b/Sources/XcodeGenKit/SettingsBuilder.swift index 81047de7a..0a173355a 100644 --- a/Sources/XcodeGenKit/SettingsBuilder.swift +++ b/Sources/XcodeGenKit/SettingsBuilder.swift @@ -249,7 +249,7 @@ extension SettingsPresetFile { symlink.parent() + relativePath, ] + possibleSettingsPaths } - if let moduleResourcePath = Bundle.module.path(forResource: "SettingPresets", ofType: nil) { + if let moduleResourcePath = Bundle.availableModule?.path(forResource: "SettingPresets", ofType: nil) { possibleSettingsPaths.append(Path(moduleResourcePath) + "\(path).yml") } @@ -272,3 +272,49 @@ extension SettingsPresetFile { return buildSettings } } + +private class BundleFinder {} + +/// The default SPM generated `Bundle.module` crashes on runtime if there is no .bundle file. +/// Below implementation modified from generated `Bundle.module` code which call `fatalError` if .bundle file not found. +private extension Bundle { + /// Returns the resource bundle associated with the current Swift module. + static let availableModule: Bundle? = { + let bundleName = "XcodeGen_XcodeGenKit" + + let overrides: [URL] + #if DEBUG + // The 'PACKAGE_RESOURCE_BUNDLE_PATH' name is preferred since the expected value is a path. The + // check for 'PACKAGE_RESOURCE_BUNDLE_URL' will be removed when all clients have switched over. + // This removal is tracked by rdar://107766372. + if let override = ProcessInfo.processInfo.environment["PACKAGE_RESOURCE_BUNDLE_PATH"] + ?? ProcessInfo.processInfo.environment["PACKAGE_RESOURCE_BUNDLE_URL"] { + overrides = [URL(fileURLWithPath: override)] + } else { + overrides = [] + } + #else + overrides = [] + #endif + + let candidates = overrides + [ + // Bundle should be present here when the package is linked into an App. + Bundle.main.resourceURL, + + // Bundle should be present here when the package is linked into a framework. + Bundle(for: BundleFinder.self).resourceURL, + + // For command-line tools. + Bundle.main.bundleURL, + ] + + for candidate in candidates { + let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle") + if let bundle = bundlePath.flatMap(Bundle.init(url:)) { + return bundle + } + } + return nil + }() +} + From 5cf4cd0d938e87b83c6f7a36880ed8046a8b77bf Mon Sep 17 00:00:00 2001 From: freddi Date: Thu, 15 Feb 2024 17:05:41 +0900 Subject: [PATCH 2/2] remove unnecessary line --- Sources/XcodeGenKit/SettingsBuilder.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/XcodeGenKit/SettingsBuilder.swift b/Sources/XcodeGenKit/SettingsBuilder.swift index 0a173355a..b65079b9d 100644 --- a/Sources/XcodeGenKit/SettingsBuilder.swift +++ b/Sources/XcodeGenKit/SettingsBuilder.swift @@ -317,4 +317,3 @@ private extension Bundle { return nil }() } -