From 9814455275bb9133dbb0f9d5281e8d8153513744 Mon Sep 17 00:00:00 2001 From: Chuck Grindel Date: Sat, 23 Mar 2024 15:01:28 -0600 Subject: [PATCH] fix: support xcframeworks that use archive files (XXX.a) (#975) - Check frameworks that are provided as archive files (XXX.a). - See [xcframwork doc](https://developer.apple.com/documentation/xcode/creating-a-multi-platform-binary-framework-bundle) for more information. - Add [GoogleCloudPlatform/recaptcha-enterprise-mobile-sdk](https://github.com/GoogleCloudPlatform/recaptcha-enterprise-mobile-sdk) to the `resources_example`. This package provides their frameworks as archive files. Closes #968. --- examples/resources_example/MODULE.bazel | 1 + .../Sources/MyApp/BUILD.bazel | 1 + .../Sources/MyApp/MyApp.swift | 1 + .../resources_example/swift/Package.resolved | 18 ++++++ .../resources_example/swift/Package.swift | 4 ++ .../resources_example/swift_deps_index.json | 61 +++++++++++++++++++ swiftpkg/internal/artifact_infos.bzl | 56 +++++++++++++++-- 7 files changed, 136 insertions(+), 6 deletions(-) diff --git a/examples/resources_example/MODULE.bazel b/examples/resources_example/MODULE.bazel index 3e1b37c5c..68ecd5e6d 100644 --- a/examples/resources_example/MODULE.bazel +++ b/examples/resources_example/MODULE.bazel @@ -53,6 +53,7 @@ use_repo( "swiftpkg_app_lovin_sdk", "swiftpkg_googlesignin_ios", "swiftpkg_package_with_resources", + "swiftpkg_recaptcha_enterprise_mobile_sdk", "swiftpkg_sdwebimageswiftui", ) # swift_deps END diff --git a/examples/resources_example/Sources/MyApp/BUILD.bazel b/examples/resources_example/Sources/MyApp/BUILD.bazel index e85725f8d..863ec6191 100644 --- a/examples/resources_example/Sources/MyApp/BUILD.bazel +++ b/examples/resources_example/Sources/MyApp/BUILD.bazel @@ -14,6 +14,7 @@ swift_library( "@swiftpkg_another_package_with_resources//:MoreCoolUI", "@swiftpkg_googlesignin_ios//:GoogleSignInSwift", "@swiftpkg_package_with_resources//:CoolUI", + "@swiftpkg_recaptcha_enterprise_mobile_sdk//:RecaptchaEnterprise", "@swiftpkg_sdwebimageswiftui//:SDWebImageSwiftUI", ], ) diff --git a/examples/resources_example/Sources/MyApp/MyApp.swift b/examples/resources_example/Sources/MyApp/MyApp.swift index 403c60937..60ab4f5ad 100644 --- a/examples/resources_example/Sources/MyApp/MyApp.swift +++ b/examples/resources_example/Sources/MyApp/MyApp.swift @@ -1,6 +1,7 @@ import CoolUI import GoogleSignInSwift import MoreCoolUI +import RecaptchaEnterprise import SDWebImageSwiftUI import SwiftUI diff --git a/examples/resources_example/swift/Package.resolved b/examples/resources_example/swift/Package.resolved index 5c181817b..3481cbbb3 100644 --- a/examples/resources_example/swift/Package.resolved +++ b/examples/resources_example/swift/Package.resolved @@ -36,6 +36,24 @@ "version" : "2.0.0" } }, + { + "identity" : "interop-ios-for-google-sdks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/interop-ios-for-google-sdks.git", + "state" : { + "revision" : "2d12673670417654f08f5f90fdd62926dc3a2648", + "version" : "100.0.0" + } + }, + { + "identity" : "recaptcha-enterprise-mobile-sdk", + "kind" : "remoteSourceControl", + "location" : "https://github.com/GoogleCloudPlatform/recaptcha-enterprise-mobile-sdk", + "state" : { + "revision" : "54f4584f85144cac8288210da556a10b32067081", + "version" : "18.4.2" + } + }, { "identity" : "sdwebimage", "kind" : "remoteSourceControl", diff --git a/examples/resources_example/swift/Package.swift b/examples/resources_example/swift/Package.swift index 11f3de6a8..0a9c88146 100644 --- a/examples/resources_example/swift/Package.swift +++ b/examples/resources_example/swift/Package.swift @@ -10,5 +10,9 @@ let package = Package( .package(path: "../third_party/package_with_resources"), .package(url: "https://github.com/SDWebImage/SDWebImageSwiftUI.git", from: "3.0.1"), .package(url: "https://github.com/google/GoogleSignIn-iOS", from: "7.0.0"), + .package( + url: "https://github.com/GoogleCloudPlatform/recaptcha-enterprise-mobile-sdk", + from: "18.4.2" + ), ] ) diff --git a/examples/resources_example/swift_deps_index.json b/examples/resources_example/swift_deps_index.json index 450fb71c8..1461f1e22 100644 --- a/examples/resources_example/swift_deps_index.json +++ b/examples/resources_example/swift_deps_index.json @@ -4,6 +4,7 @@ "app_lovin_sdk", "googlesignin-ios", "package_with_resources", + "recaptcha-enterprise-mobile-sdk", "sdwebimageswiftui" ], "modules": [ @@ -134,6 +135,16 @@ "GTMAppAuth" ] }, + { + "name": "RecaptchaInterop", + "c99name": "RecaptchaInterop", + "src_type": "objc", + "label": "@swiftpkg_interop_ios_for_google_sdks//:RecaptchaInterop.rspm", + "package_identity": "interop-ios-for-google-sdks", + "product_memberships": [ + "RecaptchaInterop" + ] + }, { "name": "CoolUI", "c99name": "CoolUI", @@ -144,6 +155,26 @@ "CoolUI" ] }, + { + "name": "RecaptchaEnterprise", + "c99name": "RecaptchaEnterprise", + "src_type": "binary", + "label": "@swiftpkg_recaptcha_enterprise_mobile_sdk//:RecaptchaEnterprise.rspm", + "package_identity": "recaptcha-enterprise-mobile-sdk", + "product_memberships": [ + "RecaptchaEnterprise" + ] + }, + { + "name": "recaptcha-enterprise", + "c99name": "recaptcha_enterprise", + "src_type": "clang", + "label": "@swiftpkg_recaptcha_enterprise_mobile_sdk//:recaptcha-enterprise.rspm", + "package_identity": "recaptcha-enterprise-mobile-sdk", + "product_memberships": [ + "RecaptchaEnterprise" + ] + }, { "name": "SDWebImage", "c99name": "SDWebImage", @@ -249,12 +280,24 @@ "type": "library", "label": "@swiftpkg_gtmappauth//:GTMAppAuth" }, + { + "identity": "interop-ios-for-google-sdks", + "name": "RecaptchaInterop", + "type": "library", + "label": "@swiftpkg_interop_ios_for_google_sdks//:RecaptchaInterop" + }, { "identity": "package_with_resources", "name": "CoolUI", "type": "library", "label": "@swiftpkg_package_with_resources//:CoolUI" }, + { + "identity": "recaptcha-enterprise-mobile-sdk", + "name": "RecaptchaEnterprise", + "type": "library", + "label": "@swiftpkg_recaptcha_enterprise_mobile_sdk//:RecaptchaEnterprise" + }, { "identity": "sdwebimageswiftui", "name": "SDWebImageSwiftUI", @@ -325,6 +368,15 @@ "version": "2.0.0" } }, + { + "name": "swiftpkg_interop_ios_for_google_sdks", + "identity": "interop-ios-for-google-sdks", + "remote": { + "commit": "2d12673670417654f08f5f90fdd62926dc3a2648", + "remote": "https://github.com/google/interop-ios-for-google-sdks.git", + "version": "100.0.0" + } + }, { "name": "swiftpkg_package_with_resources", "identity": "package_with_resources", @@ -332,6 +384,15 @@ "path": "third_party/package_with_resources" } }, + { + "name": "swiftpkg_recaptcha_enterprise_mobile_sdk", + "identity": "recaptcha-enterprise-mobile-sdk", + "remote": { + "commit": "54f4584f85144cac8288210da556a10b32067081", + "remote": "https://github.com/GoogleCloudPlatform/recaptcha-enterprise-mobile-sdk", + "version": "18.4.2" + } + }, { "name": "swiftpkg_sdwebimage", "identity": "sdwebimage", diff --git a/swiftpkg/internal/artifact_infos.bzl b/swiftpkg/internal/artifact_infos.bzl index c9822245c..4c51aacab 100644 --- a/swiftpkg/internal/artifact_infos.bzl +++ b/swiftpkg/internal/artifact_infos.bzl @@ -61,7 +61,7 @@ https://github.com/cgrindel/rules_swift_package_manager/issues/new/choose. path: """.format(path)) return name -def _new_framework_info_from_files(repository_ctx, path): +def _new_framework_info_from_framework_dir(repository_ctx, path): """Create a `struct` representing an Apple framework from the files at the \ specified path. @@ -96,6 +96,25 @@ def _new_framework_info_from_files(repository_ctx, path): link_type = link_type, ) +def _new_framework_info_from_framework_a_file(repository_ctx, framework_a_file): + """Create a `struct` representing an Apple framework from an archive file \ + (XXX.a). + + Args: + repository_ctx: A `repository_ctx` instance. + framework_a_file: The path to a `XXX.a` file as a `string`. + + Returns: + A `struct` representing an Apple framework as returned by + `artifact_infos.new_framework_info()`. + """ + path = paths.dirname(framework_a_file) + link_type = _link_type(repository_ctx, framework_a_file) + return _new_framework_info( + path = path, + link_type = link_type, + ) + def _link_type(repository_ctx, path): """Determine the link type for the framework binary file. @@ -134,21 +153,46 @@ def _new_xcframework_info_from_files(repository_ctx, path): `artifact_infos.new_xcframework_info()`. """ - # XC Frameworks have a structure like the following: + # XC Frameworks have one of two layouts: + # + # Layout: XXX.framework directory # XXX.xcframework # └─ ios-arm64/XXX.framework # └─ ios-arm64_x86_64-maccatalyst/XXX.framework # └─ macos-arm64_x86_64/XXX.framework + # + # Layout: XXX.a file + # XXX.xcframework + # └─ ios-arm64/XXX.a + # └─ ios-arm64_x86_64-maccatalyst/XXX.a + # └─ macos-arm64_x86_64/XXX.a + # + # We check for the XXX.framework layout first. If we do not find anything, + # we look for the XXX.a layout. framework_paths = repository_files.list_directories_under( repository_ctx, path, by_name = "*.framework", depth = 2, ) - framework_infos = [ - _new_framework_info_from_files(repository_ctx, fp) - for fp in framework_paths - ] + + if framework_paths: + framework_infos = [ + _new_framework_info_from_framework_dir(repository_ctx, fp) + for fp in framework_paths + ] + else: + framework_a_files = repository_files.list_files_under( + repository_ctx, + path, + by_name = "*.a", + depth = 2, + ) + framework_infos = [ + _new_framework_info_from_framework_a_file(repository_ctx, faf) + for faf in framework_a_files + ] + return _new_xcframework_info( path = path, framework_infos = framework_infos,