Skip to content

Commit be95724

Browse files
committed
Parity: Bundle.allBundles
Implement this as a function of CFBundleGetAllBundles(). Add .allFrameworks, which is API that was missed.
1 parent 7337331 commit be95724

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ CF_EXPORT _Nullable CFErrorRef CFReadStreamCopyError(CFReadStreamRef _Null_unspe
391391

392392
CF_EXPORT _Nullable CFErrorRef CFWriteStreamCopyError(CFWriteStreamRef _Null_unspecified stream);
393393

394+
CF_CROSS_PLATFORM_EXPORT CFStringRef _Nullable _CFBundleCopyExecutablePath(CFBundleRef bundle);
394395
CF_CROSS_PLATFORM_EXPORT Boolean _CFBundleSupportsFHSBundles(void);
395396

396397
// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html

CoreFoundation/PlugIn.subproj/CFBundle.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,13 @@ CF_PRIVATE CFURLRef _CFBundleCopyAppStoreReceiptURLInDirectory(CFURLRef bundleUR
951951
CFURLRef _CFBundleCopyAppStoreReceiptURL(CFBundleRef bundle) {
952952
return _CFBundleCopyAppStoreReceiptURLInDirectory(bundle->_url, bundle->_version);
953953
}
954-
954+
955+
#ifdef CF_OPEN_SOURCE
956+
CF_CROSS_PLATFORM_EXPORT CFStringRef _CFBundleCopyExecutablePath(CFBundleRef bundle) {
957+
return _CFBundleCopyExecutableName(bundle, NULL, NULL);
958+
}
959+
#endif
960+
955961
CF_PRIVATE CFStringRef _CFBundleCopyExecutableName(CFBundleRef bundle, CFURLRef url, CFDictionaryRef infoDict) {
956962
CFStringRef executableName = NULL;
957963

Foundation/Bundle.swift

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,41 @@ open class Bundle: NSObject {
2222
}
2323
}
2424

25-
open class var allBundles: [Bundle] {
26-
NSUnimplemented()
25+
private class var allBundlesRegardlessOfType: [Bundle] {
26+
// FIXME: This doesn't return bundles that weren't loaded using CFBundle or class Bundle. SR-XXXX.
27+
guard let bundles = CFBundleGetAllBundles()?._swiftObject as? [CFBundle] else { return [] }
28+
return bundles.map(Bundle.init(cfBundle:))
2729
}
2830

31+
private var isFramework: Bool {
32+
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
33+
return bundleURL.pathExtension == "framework"
34+
#else
35+
36+
#if os(Windows)
37+
if let name = _CFBundleCopyExecutablePath(_bundle)?._nsObject {
38+
return name.pathExtension.lowercased == "dll"
39+
}
40+
#else
41+
42+
// We're assuming this is an OS like Linux or BSD that uses FHS-style library names (lib….so or lib….so.2.3.4)
43+
if let name = _CFBundleCopyExecutablePath(_bundle)?._nsObject {
44+
return name.hasPrefix("lib") && (name.pathExtension == "so" || name.range(of: ".so.").location != NSNotFound)
45+
}
46+
47+
#endif
48+
49+
return false
50+
#endif
51+
}
52+
53+
open class var allBundles: [Bundle] {
54+
return allBundlesRegardlessOfType.filter { !$0.isFramework }
55+
}
56+
57+
open class var allFrameworks: [Bundle] {
58+
return allBundlesRegardlessOfType.filter { $0.isFramework }
59+
}
2960

3061
internal init(cfBundle: CFBundle) {
3162
super.init()

0 commit comments

Comments
 (0)