diff --git a/.bazelrc b/.bazelrc index 9cd9ca991..b69fea0f6 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,7 +1,7 @@ # To update these lines, execute # `bazel run @rules_bazel_integration_test//tools:update_deleted_packages` -build --deleted_packages=bzlmod/workspace,bzlmod/workspace/Sources/MyExecutable,bzlmod/workspace/Sources/MyLibrary,bzlmod/workspace/Sources/System,bzlmod/workspace/Tests/MyLibraryTests,examples/firebase_example,examples/firebase_example/abtesting,examples/firebase_example/abtesting/SharedApp,examples/firebase_example/analytics/AnalyticsExample,examples/firebase_example/appdistribution,examples/firebase_example/appdistribution/AppDistributionExample,examples/firebase_example/appdistribution/AppDistributionTests,examples/firebase_example/crashlytics,examples/google_maps_example,examples/google_maps_example/GoogleMapsExample,examples/google_maps_example/third-party/google-maps-ios-sdk,examples/grpc_example,examples/grpc_example/aaa_test,examples/grpc_example/protos,examples/grpc_example/protos/echo_service,examples/grpc_example/protos/echo_service/requests,examples/grpc_example/protos/echo_service/responses,examples/grpc_example/sources,examples/grpc_example/sources/client,examples/grpc_example/sources/server,examples/grpc_example/sources/test,examples/grpc_package_example,examples/grpc_package_example/aaa_test,examples/grpc_package_example/protos,examples/grpc_package_example/protos/echo_service,examples/grpc_package_example/sources,examples/grpc_package_example/sources/client,examples/grpc_package_example/sources/server,examples/grpc_package_example/sources/test,examples/interesting_deps,examples/ios_sim,examples/ios_sim/Sources/Foo,examples/ios_sim/Tests/FooTests,examples/ios_sim/third-party/swift-cmark,examples/lottie_ios_example,examples/lottie_ios_example/LottieExample,examples/lottie_ios_example/LottieExampleUITest,examples/messagekit_example,examples/messagekit_example/Sources,examples/messagekit_example/UITests,examples/nimble_example,examples/nimble_example/Sources/NimbleExample,examples/objc_code,examples/phone_number_kit,examples/phone_number_kit/Tests/PhoneNumberKitTests,examples/pkg_manifest_minimal,examples/pkg_manifest_minimal/Sources/MyExecutable,examples/pkg_manifest_minimal/Sources/MyLibrary,examples/pkg_manifest_minimal/Tests/MyLibraryTests,examples/pkg_manifest_minimal/third_party,examples/resources_example,examples/resources_example/Sources/MyApp,examples/resources_example/Tests/MyAppTests,examples/resources_example/Tests/MyAppUITests,examples/resources_example/third_party,examples/shake_ios_example,examples/shake_ios_example/ShakeIOSExample,examples/shake_ios_example/ShakeIOSExampleUITests,examples/snapkit_example,examples/soto_example,examples/soto_example/Tests/SotoTests,examples/stripe_example,examples/stripe_example/PaymentSheet/PaymentSheetExample,examples/stripe_example/PaymentSheet/PaymentSheetUITest,examples/symlink_example,examples/symlink_example/Sources/ImportFramework,examples/symlink_example/Tests/ImportFrameworkTests,examples/tca_example,examples/tca_example/Sources,examples/tca_example/Tests,examples/vapor_example,examples/vapor_example/Sources/App,examples/vapor_example/Sources/Run,examples/vapor_example/Tests/AppTests,examples/vapor_example/swift,examples/xcmetrics_example -query --deleted_packages=bzlmod/workspace,bzlmod/workspace/Sources/MyExecutable,bzlmod/workspace/Sources/MyLibrary,bzlmod/workspace/Sources/System,bzlmod/workspace/Tests/MyLibraryTests,examples/firebase_example,examples/firebase_example/abtesting,examples/firebase_example/abtesting/SharedApp,examples/firebase_example/analytics/AnalyticsExample,examples/firebase_example/appdistribution,examples/firebase_example/appdistribution/AppDistributionExample,examples/firebase_example/appdistribution/AppDistributionTests,examples/firebase_example/crashlytics,examples/google_maps_example,examples/google_maps_example/GoogleMapsExample,examples/google_maps_example/third-party/google-maps-ios-sdk,examples/grpc_example,examples/grpc_example/aaa_test,examples/grpc_example/protos,examples/grpc_example/protos/echo_service,examples/grpc_example/protos/echo_service/requests,examples/grpc_example/protos/echo_service/responses,examples/grpc_example/sources,examples/grpc_example/sources/client,examples/grpc_example/sources/server,examples/grpc_example/sources/test,examples/grpc_package_example,examples/grpc_package_example/aaa_test,examples/grpc_package_example/protos,examples/grpc_package_example/protos/echo_service,examples/grpc_package_example/sources,examples/grpc_package_example/sources/client,examples/grpc_package_example/sources/server,examples/grpc_package_example/sources/test,examples/interesting_deps,examples/ios_sim,examples/ios_sim/Sources/Foo,examples/ios_sim/Tests/FooTests,examples/ios_sim/third-party/swift-cmark,examples/lottie_ios_example,examples/lottie_ios_example/LottieExample,examples/lottie_ios_example/LottieExampleUITest,examples/messagekit_example,examples/messagekit_example/Sources,examples/messagekit_example/UITests,examples/nimble_example,examples/nimble_example/Sources/NimbleExample,examples/objc_code,examples/phone_number_kit,examples/phone_number_kit/Tests/PhoneNumberKitTests,examples/pkg_manifest_minimal,examples/pkg_manifest_minimal/Sources/MyExecutable,examples/pkg_manifest_minimal/Sources/MyLibrary,examples/pkg_manifest_minimal/Tests/MyLibraryTests,examples/pkg_manifest_minimal/third_party,examples/resources_example,examples/resources_example/Sources/MyApp,examples/resources_example/Tests/MyAppTests,examples/resources_example/Tests/MyAppUITests,examples/resources_example/third_party,examples/shake_ios_example,examples/shake_ios_example/ShakeIOSExample,examples/shake_ios_example/ShakeIOSExampleUITests,examples/snapkit_example,examples/soto_example,examples/soto_example/Tests/SotoTests,examples/stripe_example,examples/stripe_example/PaymentSheet/PaymentSheetExample,examples/stripe_example/PaymentSheet/PaymentSheetUITest,examples/symlink_example,examples/symlink_example/Sources/ImportFramework,examples/symlink_example/Tests/ImportFrameworkTests,examples/tca_example,examples/tca_example/Sources,examples/tca_example/Tests,examples/vapor_example,examples/vapor_example/Sources/App,examples/vapor_example/Sources/Run,examples/vapor_example/Tests/AppTests,examples/vapor_example/swift,examples/xcmetrics_example +build --deleted_packages=bzlmod/workspace,bzlmod/workspace/Sources/MyExecutable,bzlmod/workspace/Sources/MyLibrary,bzlmod/workspace/Sources/System,bzlmod/workspace/Tests/MyLibraryTests,examples/firebase_example,examples/firebase_example/abtesting,examples/firebase_example/abtesting/SharedApp,examples/firebase_example/analytics/AnalyticsExample,examples/firebase_example/appdistribution,examples/firebase_example/appdistribution/AppDistributionExample,examples/firebase_example/appdistribution/AppDistributionTests,examples/firebase_example/crashlytics,examples/google_maps_example,examples/google_maps_example/GoogleMapsExample,examples/google_maps_example/third-party/google-maps-ios-sdk,examples/grpc_example,examples/grpc_example/aaa_test,examples/grpc_example/protos,examples/grpc_example/protos/echo_service,examples/grpc_example/protos/echo_service/requests,examples/grpc_example/protos/echo_service/responses,examples/grpc_example/sources,examples/grpc_example/sources/client,examples/grpc_example/sources/server,examples/grpc_example/sources/test,examples/grpc_package_example,examples/grpc_package_example/aaa_test,examples/grpc_package_example/protos,examples/grpc_package_example/protos/echo_service,examples/grpc_package_example/sources,examples/grpc_package_example/sources/client,examples/grpc_package_example/sources/server,examples/grpc_package_example/sources/test,examples/interesting_deps,examples/ios_sim,examples/ios_sim/Sources/Foo,examples/ios_sim/Tests/FooTests,examples/ios_sim/third-party/swift-cmark,examples/lottie_ios_example,examples/lottie_ios_example/LottieExample,examples/lottie_ios_example/LottieExampleUITest,examples/messagekit_example,examples/messagekit_example/Sources,examples/messagekit_example/UITests,examples/nimble_example,examples/nimble_example/Sources/NimbleExample,examples/objc_code,examples/phone_number_kit,examples/phone_number_kit/Tests/PhoneNumberKitTests,examples/pkg_manifest_minimal,examples/pkg_manifest_minimal/Sources/MyExecutable,examples/pkg_manifest_minimal/Sources/MyLibrary,examples/pkg_manifest_minimal/Tests/MyLibraryTests,examples/pkg_manifest_minimal/third_party,examples/resources_example,examples/resources_example/Sources/MyApp,examples/resources_example/Tests/MyAppTests,examples/resources_example/Tests/MyAppUITests,examples/resources_example/third_party,examples/shake_ios_example,examples/shake_ios_example/ShakeIOSExample,examples/shake_ios_example/ShakeIOSExampleUITests,examples/snapkit_example,examples/soto_example,examples/soto_example/Tests/SotoTests,examples/stripe_example,examples/stripe_example/PaymentSheet/PaymentSheetExample,examples/stripe_example/PaymentSheet/PaymentSheetUITest,examples/swift_package_registry_example,examples/symlink_example,examples/symlink_example/Sources/ImportFramework,examples/symlink_example/Tests/ImportFrameworkTests,examples/tca_example,examples/tca_example/Sources,examples/tca_example/Tests,examples/vapor_example,examples/vapor_example/Sources/App,examples/vapor_example/Sources/Run,examples/vapor_example/Tests/AppTests,examples/vapor_example/swift,examples/xcmetrics_example +query --deleted_packages=bzlmod/workspace,bzlmod/workspace/Sources/MyExecutable,bzlmod/workspace/Sources/MyLibrary,bzlmod/workspace/Sources/System,bzlmod/workspace/Tests/MyLibraryTests,examples/firebase_example,examples/firebase_example/abtesting,examples/firebase_example/abtesting/SharedApp,examples/firebase_example/analytics/AnalyticsExample,examples/firebase_example/appdistribution,examples/firebase_example/appdistribution/AppDistributionExample,examples/firebase_example/appdistribution/AppDistributionTests,examples/firebase_example/crashlytics,examples/google_maps_example,examples/google_maps_example/GoogleMapsExample,examples/google_maps_example/third-party/google-maps-ios-sdk,examples/grpc_example,examples/grpc_example/aaa_test,examples/grpc_example/protos,examples/grpc_example/protos/echo_service,examples/grpc_example/protos/echo_service/requests,examples/grpc_example/protos/echo_service/responses,examples/grpc_example/sources,examples/grpc_example/sources/client,examples/grpc_example/sources/server,examples/grpc_example/sources/test,examples/grpc_package_example,examples/grpc_package_example/aaa_test,examples/grpc_package_example/protos,examples/grpc_package_example/protos/echo_service,examples/grpc_package_example/sources,examples/grpc_package_example/sources/client,examples/grpc_package_example/sources/server,examples/grpc_package_example/sources/test,examples/interesting_deps,examples/ios_sim,examples/ios_sim/Sources/Foo,examples/ios_sim/Tests/FooTests,examples/ios_sim/third-party/swift-cmark,examples/lottie_ios_example,examples/lottie_ios_example/LottieExample,examples/lottie_ios_example/LottieExampleUITest,examples/messagekit_example,examples/messagekit_example/Sources,examples/messagekit_example/UITests,examples/nimble_example,examples/nimble_example/Sources/NimbleExample,examples/objc_code,examples/phone_number_kit,examples/phone_number_kit/Tests/PhoneNumberKitTests,examples/pkg_manifest_minimal,examples/pkg_manifest_minimal/Sources/MyExecutable,examples/pkg_manifest_minimal/Sources/MyLibrary,examples/pkg_manifest_minimal/Tests/MyLibraryTests,examples/pkg_manifest_minimal/third_party,examples/resources_example,examples/resources_example/Sources/MyApp,examples/resources_example/Tests/MyAppTests,examples/resources_example/Tests/MyAppUITests,examples/resources_example/third_party,examples/shake_ios_example,examples/shake_ios_example/ShakeIOSExample,examples/shake_ios_example/ShakeIOSExampleUITests,examples/snapkit_example,examples/soto_example,examples/soto_example/Tests/SotoTests,examples/stripe_example,examples/stripe_example/PaymentSheet/PaymentSheetExample,examples/stripe_example/PaymentSheet/PaymentSheetUITest,examples/swift_package_registry_example,examples/symlink_example,examples/symlink_example/Sources/ImportFramework,examples/symlink_example/Tests/ImportFrameworkTests,examples/tca_example,examples/tca_example/Sources,examples/tca_example/Tests,examples/vapor_example,examples/vapor_example/Sources/App,examples/vapor_example/Sources/Run,examples/vapor_example/Tests/AppTests,examples/vapor_example/swift,examples/xcmetrics_example # Import Shared settings import %workspace%/shared.bazelrc diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a3c0958d8..f12d7e91e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,6 +71,8 @@ jobs: runner: macos-13 - test: '@@//examples:stripe_example_test_bazel_.bazelversion' runner: macos-13 + - test: '@@//examples:swift_package_registry_example_test_bazel_.bazelversion' + runner: macos-13 - test: '@@//examples:symlink_example_test_bazel_.bazelversion' runner: macos-13 - test: '@@//examples:tca_example_test_bazel_.bazelversion' diff --git a/docs/BUILD.bazel b/docs/BUILD.bazel index d5e48bd24..67865f275 100644 --- a/docs/BUILD.bazel +++ b/docs/BUILD.bazel @@ -31,6 +31,7 @@ _DOC_INFOS = [ symbols = [ "local_swift_package", "swift_package", + "registry_swift_package", ], ), doc_infos.new( diff --git a/docs/bzlmod_extensions_overview.md b/docs/bzlmod_extensions_overview.md index ae15d0303..df240993c 100755 --- a/docs/bzlmod_extensions_overview.md +++ b/docs/bzlmod_extensions_overview.md @@ -17,9 +17,9 @@ On this page: swift_deps = use_extension("@rules_swift_package_manager//:extensions.bzl", "swift_deps") swift_deps.configure_package(name, init_submodules, patch_args, patch_cmds, patch_cmds_win, patch_tool, patches, recursive_init_submodules) -swift_deps.configure_swift_package(build_path, cache_path, dependency_caching, manifest_cache, - manifest_caching, security_path) -swift_deps.from_package(declare_swift_deps_info, declare_swift_package, resolved, swift) +swift_deps.configure_swift_package(build_path, cache_path, config_path, dependency_caching, + manifest_cache, manifest_caching, security_path) +swift_deps.from_package(declare_swift_deps_info, declare_swift_package, registries, resolved, swift) @@ -56,6 +56,7 @@ Used to configure the flags used when running the `swift package` binary. | :------------- | :------------- | :------------- | :------------- | :------------- | | build_path | The relative path within the runfiles tree for the Swift Package Manager build directory. | String | optional | `".build"` | | cache_path | The relative path within the runfiles tree for the shared Swift Package Manager cache directory. | String | optional | `".cache"` | +| config_path | The relative path within the runfiles tree for the Swift Package Manager configuration directory. | String | optional | `".swiftpm"` | | dependency_caching | Whether to enable the dependency cache. | Boolean | optional | `True` | | manifest_cache | Caching mode of Package.swift manifests (shared: shared cache, local: package's build directory, none: disabled) | String | optional | `"shared"` | | manifest_caching | Whether to enable build manifest caching. | Boolean | optional | `True` | @@ -73,6 +74,7 @@ Load Swift packages from `Package.swift` and `Package.resolved` files. | :------------- | :------------- | :------------- | :------------- | :------------- | | declare_swift_deps_info | Declare a `swift_deps_info` repository that is used by external tooling (e.g. Swift Gazelle plugin). | Boolean | optional | `False` | | declare_swift_package | Declare a `swift_package_tool` repository named `swift_package` which defines two targets: `update` and `resolve`. These targets run can be used to run the `swift package` binary in a Bazel context. The flags used when running the underlying `swift package` can be configured using the `configure_swift_package` tag.

They can be `bazel run` to update/resolve the `resolved` file:

bazel run @swift_package//:update
bazel run @swift_package//:resolve
| Boolean | optional | `True` | +| registries | A `registries.json` file that defines the configured Swift package registries.

The `registries.json` file is used when resolving Swift packages from a Swift package registry. It is created by Swift Package Manager when using the `swift package-registry` commands.

When using the `swift_package_tool` rules, this file is symlinked to the `config_path` directory defined in the `configure_swift_package` tag. If not using the `swift_package_tool` rules, the file must be in one of Swift Package Manager's search paths or in the manually specified `--config-path` directory. | Label | optional | `None` | | resolved | A `Package.resolved`. | Label | optional | `None` | | swift | A `Package.swift`. | Label | required | | diff --git a/docs/repository_rules_overview.md b/docs/repository_rules_overview.md index a69fb31c0..6781039f6 100755 --- a/docs/repository_rules_overview.md +++ b/docs/repository_rules_overview.md @@ -10,6 +10,7 @@ On this page: * [local_swift_package](#local_swift_package) * [swift_package](#swift_package) + * [registry_swift_package](#registry_swift_package) diff --git a/examples/example_infos.bzl b/examples/example_infos.bzl index 9931517d6..4cea448b2 100644 --- a/examples/example_infos.bzl +++ b/examples/example_infos.bzl @@ -149,6 +149,7 @@ _macos_single_bazel_version_test_examples = [ "xcmetrics_example", "tca_example", "symlink_example", + "swift_package_registry_example", ] _linux_single_bazel_version_test_examples = [] diff --git a/examples/interesting_deps/MODULE.bazel b/examples/interesting_deps/MODULE.bazel index e3125f2ba..215812199 100644 --- a/examples/interesting_deps/MODULE.bazel +++ b/examples/interesting_deps/MODULE.bazel @@ -58,6 +58,7 @@ swift_deps.from_package( swift_deps.configure_swift_package( build_path = "spm-build", cache_path = "spm-cache", + config_path = "spm-config", dependency_caching = False, manifest_cache = "none", manifest_caching = False, diff --git a/examples/swift_package_registry_example/.bazelrc b/examples/swift_package_registry_example/.bazelrc new file mode 100644 index 000000000..e9769fc7b --- /dev/null +++ b/examples/swift_package_registry_example/.bazelrc @@ -0,0 +1,8 @@ +# Import Shared settings +import %workspace%/../../shared.bazelrc + +# Import CI settings. +import %workspace%/../../ci.bazelrc + +# Try to import a local.rc file; typically, written by CI +try-import %workspace%/../../local.bazelrc diff --git a/examples/swift_package_registry_example/.swiftpm/configuration/registries.json b/examples/swift_package_registry_example/.swiftpm/configuration/registries.json new file mode 100644 index 000000000..70f094861 --- /dev/null +++ b/examples/swift_package_registry_example/.swiftpm/configuration/registries.json @@ -0,0 +1,12 @@ +{ + "authentication" : { + + }, + "registries" : { + "[default]" : { + "supportsAvailability" : false, + "url" : "https://fake-spm-registry.deno.dev" + } + }, + "version" : 1 +} diff --git a/examples/swift_package_registry_example/BUILD.bazel b/examples/swift_package_registry_example/BUILD.bazel new file mode 100644 index 000000000..a26935f8c --- /dev/null +++ b/examples/swift_package_registry_example/BUILD.bazel @@ -0,0 +1,13 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_binary") + +exports_files([ + ".swiftpm/configuration/registries.json", +]) + +swift_binary( + name = "swift_package_registry_example", + srcs = ["main.swift"], + module_name = "swift_package_registry_example", + visibility = ["//visibility:public"], + deps = ["@swiftpkg_swift_collections//:Collections"], +) diff --git a/examples/swift_package_registry_example/MODULE.bazel b/examples/swift_package_registry_example/MODULE.bazel new file mode 100644 index 000000000..adc6136ed --- /dev/null +++ b/examples/swift_package_registry_example/MODULE.bazel @@ -0,0 +1,49 @@ +bazel_dep( + name = "rules_swift_package_manager", + version = "0.0.0", +) +local_path_override( + module_name = "rules_swift_package_manager", + path = "../..", +) + +bazel_dep(name = "cgrindel_bazel_starlib", version = "0.21.0") +bazel_dep(name = "bazel_skylib", version = "1.7.1") +bazel_dep(name = "apple_support", version = "1.17.1") +bazel_dep( + name = "rules_swift", + version = "2.2.2", + repo_name = "build_bazel_rules_swift", +) +bazel_dep( + name = "rules_apple", + version = "3.10.0", + repo_name = "build_bazel_rules_apple", +) + +bazel_dep( + name = "bazel_skylib_gazelle_plugin", + version = "1.7.1", + dev_dependency = True, +) +bazel_dep( + name = "gazelle", + version = "0.39.1", + dev_dependency = True, + repo_name = "bazel_gazelle", +) + +swift_deps = use_extension( + "@rules_swift_package_manager//:extensions.bzl", + "swift_deps", +) +swift_deps.from_package( + registries = "//:.swiftpm/configuration/registries.json", + resolved = "//:Package.resolved", + swift = "//:Package.swift", +) +use_repo( + swift_deps, + "swift_package", + "swiftpkg_swift_collections", +) diff --git a/examples/swift_package_registry_example/Package.resolved b/examples/swift_package_registry_example/Package.resolved new file mode 100644 index 000000000..6faefa013 --- /dev/null +++ b/examples/swift_package_registry_example/Package.resolved @@ -0,0 +1,13 @@ +{ + "pins" : [ + { + "identity" : "apple.swift-collections", + "kind" : "registry", + "location" : "", + "state" : { + "version" : "1.1.3" + } + } + ], + "version" : 2 +} diff --git a/examples/swift_package_registry_example/Package.swift b/examples/swift_package_registry_example/Package.swift new file mode 100644 index 000000000..151cec066 --- /dev/null +++ b/examples/swift_package_registry_example/Package.swift @@ -0,0 +1,10 @@ +// swift-tools-version: 5.7 + +import PackageDescription + +let package = Package( + name: "swift_package_registry_example", + dependencies: [ + .package(id: "apple.swift-collections", exact: "1.1.3"), + ] +) diff --git a/examples/swift_package_registry_example/README.md b/examples/swift_package_registry_example/README.md new file mode 100644 index 000000000..bea2ec476 --- /dev/null +++ b/examples/swift_package_registry_example/README.md @@ -0,0 +1 @@ +# swift_package_registry Example diff --git a/examples/swift_package_registry_example/WORKSPACE b/examples/swift_package_registry_example/WORKSPACE new file mode 100644 index 000000000..d251ab7ba --- /dev/null +++ b/examples/swift_package_registry_example/WORKSPACE @@ -0,0 +1 @@ +# Intentionally blank: Using bzlmod diff --git a/examples/swift_package_registry_example/WORKSPACE.bzlmod b/examples/swift_package_registry_example/WORKSPACE.bzlmod new file mode 100644 index 000000000..af8a0e896 --- /dev/null +++ b/examples/swift_package_registry_example/WORKSPACE.bzlmod @@ -0,0 +1 @@ +# Intentionally blank: Force bzlmod to strict mode diff --git a/examples/swift_package_registry_example/do_test b/examples/swift_package_registry_example/do_test new file mode 100755 index 000000000..28cc472fb --- /dev/null +++ b/examples/swift_package_registry_example/do_test @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -eou pipefail + +# Use the Bazel binary specified by the integration test. Otherise, fall back +# to bazel. +bazel="${BIT_BAZEL_BINARY:-bazel}" + +# Test resolving the package via the `swift_package` repo. +"${bazel}" run @swift_package//:resolve + +# Ensure that it builds. +"${bazel}" build //... diff --git a/examples/swift_package_registry_example/main.swift b/examples/swift_package_registry_example/main.swift new file mode 100644 index 000000000..07f27050a --- /dev/null +++ b/examples/swift_package_registry_example/main.swift @@ -0,0 +1,6 @@ +import Collections + +let orderedSet = OrderedSet([1, 2, 3, 4, 5]) + +print("Hello, world!") +print(orderedSet) diff --git a/swiftpkg/bzlmod/BUILD.bazel b/swiftpkg/bzlmod/BUILD.bazel index 2aa85d703..6eed2560b 100644 --- a/swiftpkg/bzlmod/BUILD.bazel +++ b/swiftpkg/bzlmod/BUILD.bazel @@ -17,6 +17,7 @@ bzl_library( "//swiftpkg/internal:bazel_repo_names", "//swiftpkg/internal:local_swift_package", "//swiftpkg/internal:pkginfos", + "//swiftpkg/internal:registry_swift_package", "//swiftpkg/internal:repository_utils", "//swiftpkg/internal:swift_deps_info", "//swiftpkg/internal:swift_package", diff --git a/swiftpkg/bzlmod/swift_deps.bzl b/swiftpkg/bzlmod/swift_deps.bzl index c5c83465b..058b80cfb 100644 --- a/swiftpkg/bzlmod/swift_deps.bzl +++ b/swiftpkg/bzlmod/swift_deps.bzl @@ -1,12 +1,14 @@ """Implementation for `swift_deps` bzlmod extension.""" +load("@bazel_skylib//lib:dicts.bzl", "dicts") load("//swiftpkg/internal:bazel_repo_names.bzl", "bazel_repo_names") load("//swiftpkg/internal:local_swift_package.bzl", "local_swift_package") load("//swiftpkg/internal:pkginfos.bzl", "pkginfos") +load("//swiftpkg/internal:registry_swift_package.bzl", "registry_swift_package") load("//swiftpkg/internal:repository_utils.bzl", "repository_utils") load("//swiftpkg/internal:swift_deps_info.bzl", "swift_deps_info") load("//swiftpkg/internal:swift_package.bzl", "PATCH_ATTRS", "swift_package") -load("//swiftpkg/internal:swift_package_tool.bzl", "SWIFT_PACKAGE_CONFIG_ATTRS") +load("//swiftpkg/internal:swift_package_tool_attrs.bzl", "swift_package_tool_attrs") load("//swiftpkg/internal:swift_package_tool_repo.bzl", "swift_package_tool_repo") # MARK: - swift_deps bzlmod Extension @@ -57,7 +59,8 @@ def _declare_pkgs_from_package(module_ctx, from_package, config_pkgs, config_swi # By ignoring these for now we can allow the build to progress while # expecting a resolution in the future. if not dep.file_system and \ - not dep.source_control: + not dep.source_control and \ + not dep.registry: # buildifier: disable=print print(""" WARNING: {name} is unresolved and won't be available duing the build, resolve \ @@ -148,11 +151,11 @@ the Swift package to make it available.\ config_pkg = config_pkgs.get( bazel_repo_names.from_identity(dep.identity), ) - _declare_pkg_from_dependency(dep, config_pkg) + _declare_pkg_from_dependency(dep, config_pkg, from_package) return direct_dep_repo_names -def _declare_pkg_from_dependency(dep, config_pkg): +def _declare_pkg_from_dependency(dep, config_pkg, from_package): name = bazel_repo_names.from_identity(dep.identity) if dep.source_control: init_submodules = None @@ -196,10 +199,18 @@ def _declare_pkg_from_dependency(dep, config_pkg): dependencies_index = None, ) + elif dep.registry: + registry_swift_package( + name = name, + id = dep.registry.pin.identity, + version = dep.registry.pin.state.version, + registries = from_package.registries, + ) + def _declare_swift_package_repo(name, from_package, config_swift_package): config_swift_package_kwargs = repository_utils.struct_to_kwargs( struct = config_swift_package, - keys = SWIFT_PACKAGE_CONFIG_ATTRS, + keys = swift_package_tool_attrs.swift_package_tool_config, ) swift_package_tool_repo( @@ -208,6 +219,7 @@ def _declare_swift_package_repo(name, from_package, config_swift_package): package = from_package.swift.package, name = from_package.swift.name, ), + registries = from_package.registries, **config_swift_package_kwargs ) @@ -237,16 +249,18 @@ def _swift_deps_impl(module_ctx): ) _from_package_tag = tag_class( - attrs = { - "declare_swift_deps_info": attr.bool( - doc = """\ + attrs = dicts.add( + swift_package_tool_attrs.swift_package_registry, + { + "declare_swift_deps_info": attr.bool( + doc = """\ Declare a `swift_deps_info` repository that is used by external tooling (e.g. \ Swift Gazelle plugin).\ """, - ), - "declare_swift_package": attr.bool( - default = True, - doc = """\ + ), + "declare_swift_package": attr.bool( + default = True, + doc = """\ Declare a `swift_package_tool` repository named `swift_package` which defines two targets: `update` and `resolve`.\ @@ -261,17 +275,18 @@ bazel run @swift_package//:update bazel run @swift_package//:resolve ``` """, - ), - "resolved": attr.label( - allow_files = [".resolved"], - doc = "A `Package.resolved`.", - ), - "swift": attr.label( - mandatory = True, - allow_files = [".swift"], - doc = "A `Package.swift`.", - ), - }, + ), + "resolved": attr.label( + allow_files = [".resolved"], + doc = "A `Package.resolved`.", + ), + "swift": attr.label( + mandatory = True, + allow_files = [".swift"], + doc = "A `Package.swift`.", + ), + }, + ), doc = "Load Swift packages from `Package.swift` and `Package.resolved` files.", ) @@ -296,7 +311,7 @@ The identity (i.e., name in the package's manifest) for the Swift package.\ ) _configure_swift_package_tag = tag_class( - attrs = SWIFT_PACKAGE_CONFIG_ATTRS, + attrs = swift_package_tool_attrs.swift_package_tool_config, doc = "Used to configure the flags used when running the `swift package` binary.", ) diff --git a/swiftpkg/internal/BUILD.bazel b/swiftpkg/internal/BUILD.bazel index b21d05f06..252ec32ee 100644 --- a/swiftpkg/internal/BUILD.bazel +++ b/swiftpkg/internal/BUILD.bazel @@ -318,6 +318,16 @@ bzl_library( ], ) +bzl_library( + name = "registry_swift_package", + srcs = ["registry_swift_package.bzl"], + visibility = ["//swiftpkg:__subpackages__"], + deps = [ + ":repo_rules", + "@bazel_skylib//lib:dicts", + ], +) + bzl_library( name = "bazel_repo_names", srcs = ["bazel_repo_names.bzl"], @@ -366,6 +376,12 @@ bzl_library( visibility = ["//swiftpkg:__subpackages__"], ) +bzl_library( + name = "swift_package_tool_attrs", + srcs = ["swift_package_tool_attrs.bzl"], + visibility = ["//swiftpkg:__subpackages__"], +) + bzl_library( name = "validations", srcs = ["validations.bzl"], diff --git a/swiftpkg/internal/bazel_repo_names.bzl b/swiftpkg/internal/bazel_repo_names.bzl index 108eba263..1a3745d9a 100644 --- a/swiftpkg/internal/bazel_repo_names.bzl +++ b/swiftpkg/internal/bazel_repo_names.bzl @@ -17,6 +17,16 @@ def _from_identity(identity): Returns: A Bazel repository name as a `string`. """ + + # TODO: Should we do this replacement for registry packages? + # This potentially conflicts with Swift Package Manager's `--use-registry-identity-for-scm` flag. + # Without this though, what would have been generated as `swiftpkg_swift_collections` is instead + # `swiftpkg_apple.swift_collections` which seems more confusing and build breaking if going from registry + # to non-registry. + registry_org_identity_split = identity.split(".") + if len(registry_org_identity_split) > 1: + identity = registry_org_identity_split[1] + return "swiftpkg_" + identity.replace("-", "_") def _normalize(repo_name): diff --git a/swiftpkg/internal/pkginfos.bzl b/swiftpkg/internal/pkginfos.bzl index 08aa9a413..78a0da30a 100644 --- a/swiftpkg/internal/pkginfos.bzl +++ b/swiftpkg/internal/pkginfos.bzl @@ -151,6 +151,8 @@ def _new_dependency_from_desc_json_map(dep_names_by_id, dep_map, resolved_dep_ma source_control = None file_system = None + registry = None + if type == "sourceControl": pin = None if resolved_dep_map: @@ -160,6 +162,13 @@ def _new_dependency_from_desc_json_map(dep_names_by_id, dep_map, resolved_dep_ma ) elif type == "fileSystem": file_system = _new_file_system(path = dep_map["path"]) + elif type == "registry": + pin = None + if resolved_dep_map: + pin = _new_pin_from_resolved_dep_map(resolved_dep_map) + registry = _new_registry( + pin = pin, + ) else: fail("Unrecognized dependency type {type} for {identity}.".format( type = type, @@ -171,6 +180,7 @@ def _new_dependency_from_desc_json_map(dep_names_by_id, dep_map, resolved_dep_ma name = name, source_control = source_control, file_system = file_system, + registry = registry, ) def _new_pin_from_resolved_dep_map(resolved_dep_map): @@ -180,7 +190,7 @@ def _new_pin_from_resolved_dep_map(resolved_dep_map): kind = resolved_dep_map["kind"], location = resolved_dep_map["location"], state = _new_pin_state( - revision = state_map["revision"], + revision = state_map.get("revision"), version = state_map.get("version"), ), ) @@ -499,7 +509,7 @@ def _new_dependency_identity_to_name_map(dump_deps): result = {} for dep in dump_deps: identity_provider_list = ( - dep.get("sourceControl") or dep.get("fileSystem") + dep.get("sourceControl") or dep.get("fileSystem") or dep.get("registry") ) if not identity_provider_list: continue @@ -703,7 +713,7 @@ def _new_platform(name, version): # MARK: - External Dependency -def _new_dependency(identity, name, source_control = None, file_system = None): +def _new_dependency(identity, name, source_control = None, file_system = None, registry = None): """Creates a `struct` representing an external dependency for a Swift \ package. @@ -716,6 +726,9 @@ def _new_dependency(identity, name, source_control = None, file_system = None): file_system: Optional. A `struct` as returned by `pkginfos.new_file_system()`. If present, it identifies the dependency as being loaded from a local file system. + registry: Optional. A `struct` as returned by + `pkginfos.new_registry()`. If present, it identifies the + dependency as being loaded from a Swift package registry. Returns: A `struct` representing an external dependency. @@ -726,6 +739,7 @@ def _new_dependency(identity, name, source_control = None, file_system = None): name = pkginfo_dependencies.normalize_name(name), source_control = source_control, file_system = file_system, + registry = registry, ) def _new_source_control(pin): @@ -767,8 +781,11 @@ def _new_pin(identity, kind, location, state): def _new_pin_state(revision, version = None): """Create a `struct` representing the state for a pin. + `revision` is not provided for Swift package registry pins. + `version` is not provided for git ref pins. + Args: - revision: The commit hash as a `string`. + revision: Optional. The commit hash as a `string`. version: Optional. The version string for the commit as a `string`. Returns: @@ -792,6 +809,19 @@ def _new_file_system(path): path = path, ) +def _new_registry(pin): + """Create a `struct` representing a registry dependency. + + Args: + pin: A `struct` as returned by `pkginfos.new_pin()`. + + Returns: + A `struct` representing a registry dependency. + """ + return struct( + pin = pin, + ) + def _new_dependency_requirement(ranges = None): """Creates a `struct` representing the requirements for an external \ dependency. @@ -1667,6 +1697,7 @@ pkginfos = struct( new_product = _new_product, new_product_reference = _new_product_reference, new_product_type = _new_product_type, + new_registry = _new_registry, new_resource = _new_resource, new_resource_rule = _new_resource_rule, new_resource_rule_process = _new_resource_rule_process, diff --git a/swiftpkg/internal/registry_swift_package.bzl b/swiftpkg/internal/registry_swift_package.bzl new file mode 100644 index 000000000..eba2e951e --- /dev/null +++ b/swiftpkg/internal/registry_swift_package.bzl @@ -0,0 +1,176 @@ +"""Implementation for `registry_swift_package`.""" + +load("@bazel_skylib//lib:dicts.bzl", "dicts") +load("//swiftpkg/internal:swift_package_tool_attrs.bzl", "swift_package_tool_attrs") +load("//swiftpkg/internal:pkg_ctxs.bzl", "pkg_ctxs") +load("//swiftpkg/internal:repo_rules.bzl", "repo_rules") + +_DEFAULT_REGISTRY_KEY = "[default]" +_SOURCE_ARCHIVE_NAME = "source-archive" + +def _get_id(id): + """Returns the scope and name from the package identifier. + + https://github.com/swiftlang/swift-evolution/blob/main/proposals/0292-package-registry-service.md#package-identity + """ + scope, name = id.split(".") + return struct( + scope = scope, + name = name, + ) + +def _get_registries(registries_json): + """Returns the registry structs from the registries JSON.""" + default_registry = None + scoped_registries = {} + + for registry_key, registry in registries_json.items(): + if registry_key == _DEFAULT_REGISTRY_KEY: + default_registry = registry + else: + scoped_registries[registry_key] = registry.get("url") + + if not default_registry and not scoped_registries: + fail("No registries were parsed from the `registries` field: {registries}".format(registries = registries_json)) + + return struct( + default = default_registry.get("url"), + scoped = scoped_registries, + ) + +def _get_registry_url(*, id, registries): + """Returns the registry URL for the given package identifier, preferring a scoped registry if it is defined.""" + return registries.scoped.get(id.scope, registries.default) + +def _download_and_parse_package_json(*, id, output, repository_ctx, registry_url, version): + """Downloads and parses the package JSON metadata from the registry. + + https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#42-fetch-information-about-a-package-release + """ + package_json_url = "{registry_url}/{scope}/{name}/{version}".format( + registry_url = registry_url, + scope = id.scope, + name = id.name, + version = version, + ) + + repository_ctx.download( + url = package_json_url, + output = output, + ) + + return json.decode(repository_ctx.read(output)) + + +def _download_archive(*, checksum, id, output, repository_ctx, registry_url, version): + """Downloads the specific version of the archive from the registry. + + https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#44-download-source-archive + """ + archive_url = "{registry_url}/{scope}/{name}/{version}.zip".format( + registry_url = registry_url, + scope = id.scope, + name = id.name, + version = version, + ) + repository_ctx.download_and_extract( + url = archive_url, + output = output, + sha256 = checksum, + stripPrefix = "{name}-{version}".format(name = id.name, version = version), + ) + +def _get_source_archive_checksum(*, package_json): + """Returns the checksum for the source archive from the package JSON.""" + source_archive = None + for resource in package_json.get("resources", []): + if resource.get("name") == _SOURCE_ARCHIVE_NAME: + source_archive = resource + break + + if not source_archive: + fail("No source archive was found in the package JSON: {package_json}".format(package_json = package_json)) + + return source_archive.get("checksum") + +def _registry_swift_package_impl(repository_ctx): + """Implementation for the `registry_swift_package` repository rule.""" + directory = str(repository_ctx.path(".")) + env = repo_rules.get_exec_env(repository_ctx) + id = _get_id(repository_ctx.attr.id) + version = repository_ctx.attr.version + + # TODO: potentially use the other fields here like `authentication`, for now just use the `registries` field. + registries_json = json.decode(repository_ctx.read(repository_ctx.attr.registries)).get("registries") + registries = _get_registries(registries_json) + + registry_url = _get_registry_url( + id = id, + registries = registries, + ) + + # Get the checksum for the source archive. + package_json_output = "{scope}_{name}_{version}.json".format( + scope = id.scope, + name = id.name, + version = version, + ) + package_json = _download_and_parse_package_json( + id = id, + output = package_json_output, + repository_ctx = repository_ctx, + registry_url = registry_url, + version = version, + ) + + # Download the source archive. + archive_output = "{scope}_{name}_{version}".format( + scope = id.scope, + name = id.name, + version = version, + ) + archive_checksum = _get_source_archive_checksum(package_json = package_json) + _download_archive( + checksum = archive_checksum, + id = id, + output = archive_output, + repository_ctx = repository_ctx, + registry_url = registry_url, + version = version, + ) + + # Generate the WORKSPACE file + repo_rules.write_workspace_file(repository_ctx, directory) + + # Generate the build file + pkg_ctx = pkg_ctxs.read(repository_ctx, directory, env) + repo_rules.gen_build_files(repository_ctx, pkg_ctx) + + # Remove unused modulemaps to prevent module redefinition errors + repo_rules.remove_modulemaps(repository_ctx, directory, pkg_ctx.pkg_info.targets) + +_REGISTRY_ATTRS = { + "id": attr.string( + mandatory = True, + doc = "The package identifier.", + ), + "version": attr.string( + mandatory = True, + doc = "The package version.", + ), +} + +_ALL_ATTRS = dicts.add( + _REGISTRY_ATTRS, + repo_rules.env_attrs, + repo_rules.swift_attrs, + swift_package_tool_attrs.swift_package_registry, +) + +registry_swift_package = repository_rule( + implementation = _registry_swift_package_impl, + attrs = _ALL_ATTRS, + doc = """\ +Used to download and build an external Swift package from a registry. +""", +) diff --git a/swiftpkg/internal/repo_rules.bzl b/swiftpkg/internal/repo_rules.bzl index 3565e9e80..3385bf6bf 100644 --- a/swiftpkg/internal/repo_rules.bzl +++ b/swiftpkg/internal/repo_rules.bzl @@ -186,11 +186,29 @@ def _get_auth(ctx, urls): auth_patterns = ctx.attr.auth_patterns return use_netrc(netrc, urls, auth_patterns) +def _remove_modulemaps(repository_ctx, directory, targets): + repository_files.find_and_delete_files( + repository_ctx, + directory, + "module.modulemap", + exclude_paths = [ + # Framework modulemaps don't cause issues, and are needed + "**/*.framework/*", + ] + [ + # We need to leave any modulemaps that we are passing into + # `objc_library` + target.clang_src_info.modulemap_path + for target in targets + if target.clang_src_info and target.clang_src_info.modulemap_path + ], + ) + repo_rules = struct( check_spm_version = _check_spm_version, env_attrs = _env_attrs, gen_build_files = _gen_build_files, get_exec_env = _get_exec_env, + remove_modulemaps = _remove_modulemaps, swift_attrs = _swift_attrs, write_workspace_file = _write_workspace_file, ) diff --git a/swiftpkg/internal/swift_package.bzl b/swiftpkg/internal/swift_package.bzl index fb21b87af..e320399e2 100644 --- a/swiftpkg/internal/swift_package.bzl +++ b/swiftpkg/internal/swift_package.bzl @@ -44,23 +44,6 @@ def _remove_bazel_files(repository_ctx, directory): for file in files: repository_files.find_and_delete_files(repository_ctx, directory, file) -def _remove_modulemaps(repository_ctx, directory, targets): - repository_files.find_and_delete_files( - repository_ctx, - directory, - "module.modulemap", - exclude_paths = [ - # Framework modulemaps don't cause issues, and are needed - "**/*.framework/*", - ] + [ - # We need to leave any modulemaps that we are passing into - # `objc_library` - target.clang_src_info.modulemap_path - for target in targets - if target.clang_src_info and target.clang_src_info.modulemap_path - ], - ) - def _swift_package_impl(repository_ctx): directory = str(repository_ctx.path(".")) env = repo_rules.get_exec_env(repository_ctx) @@ -86,7 +69,7 @@ def _swift_package_impl(repository_ctx): repository_ctx.delete(repository_ctx.path(".git")) # Remove unused modulemaps to prevent module redefinition errors - _remove_modulemaps(repository_ctx, directory, pkg_ctx.pkg_info.targets) + repo_rules.remove_modulemaps(repository_ctx, directory, pkg_ctx.pkg_info.targets) # Return attributes that make this reproducible return _update_git_attrs(repository_ctx.attr, _ALL_ATTRS.keys(), update) diff --git a/swiftpkg/internal/swift_package_tool.bzl b/swiftpkg/internal/swift_package_tool.bzl index aaab9c878..0e2cb3262 100644 --- a/swiftpkg/internal/swift_package_tool.bzl +++ b/swiftpkg/internal/swift_package_tool.bzl @@ -3,6 +3,7 @@ load("@bazel_skylib//lib:dicts.bzl", "dicts") load("@bazel_skylib//lib:paths.bzl", "paths") load("@build_bazel_rules_swift//swift:swift.bzl", "swift_common") +load("//swiftpkg/internal:swift_package_tool_attrs.bzl", "swift_package_tool_attrs") # The name of the runner script. _RUNNER_SCRIPT_NAME = "swift_package.sh" @@ -10,10 +11,11 @@ _RUNNER_SCRIPT_NAME = "swift_package.sh" def _swift_package_tool_impl(ctx): build_path = ctx.attr.build_path cache_path = ctx.attr.cache_path + config_path = ctx.attr.config_path cmd = ctx.attr.cmd package = ctx.attr.package package_path = paths.dirname(package) - + registries = ctx.file.registries toolchain = swift_common.get_toolchain(ctx) swift = toolchain.swift_worker @@ -24,10 +26,12 @@ def _swift_package_tool_impl(ctx): template_dict.add("%(package_path)s", package_path) template_dict.add("%(build_path)s", build_path) template_dict.add("%(cache_path)s", cache_path) + template_dict.add("%(config_path)s", config_path) template_dict.add("%(enable_build_manifest_caching)s", "true" if ctx.attr.manifest_caching else "false") template_dict.add("%(enable_dependency_cache)s", "true" if ctx.attr.dependency_caching else "false") template_dict.add("%(manifest_cache)s", ctx.attr.manifest_cache) template_dict.add("%(security_path)s", ctx.attr.security_path) + template_dict.add("%(registries_json)s", registries.short_path) ctx.actions.expand_template( template = ctx.file._runner_template, @@ -40,40 +44,12 @@ def _swift_package_tool_impl(ctx): DefaultInfo( executable = runner_script, files = depset([runner_script]), - runfiles = ctx.runfiles(files = [swift.executable]), + runfiles = ctx.runfiles( + files = [swift.executable] + ctx.files.registries, + ), ), ] -SWIFT_PACKAGE_CONFIG_ATTRS = { - "build_path": attr.string( - doc = "The relative path within the runfiles tree for the Swift Package Manager build directory.", - default = ".build", - ), - "cache_path": attr.string( - doc = "The relative path within the runfiles tree for the shared Swift Package Manager cache directory.", - default = ".cache", - ), - "dependency_caching": attr.bool( - doc = "Whether to enable the dependency cache.", - default = True, - ), - "manifest_cache": attr.string( - doc = """Caching mode of Package.swift manifests \ -(shared: shared cache, local: package's build directory, none: disabled) -""", - default = "shared", - values = ["shared", "local", "none"], - ), - "manifest_caching": attr.bool( - doc = "Whether to enable build manifest caching.", - default = True, - ), - "security_path": attr.string( - doc = "The relative path within the runfiles tree for the security directory.", - default = ".security", - ), -} - swift_package_tool = rule( implementation = _swift_package_tool_impl, doc = "Defines a rule that can be used to execute the `swift package` tool.", @@ -95,7 +71,8 @@ swift_package_tool = rule( default = Label("//swiftpkg/internal:swift_package_tool_runner_template.sh"), ), }, - SWIFT_PACKAGE_CONFIG_ATTRS, + swift_package_tool_attrs.swift_package_tool_config, + swift_package_tool_attrs.swift_package_registry, ), executable = True, ) diff --git a/swiftpkg/internal/swift_package_tool_attrs.bzl b/swiftpkg/internal/swift_package_tool_attrs.bzl new file mode 100644 index 000000000..9e230161e --- /dev/null +++ b/swiftpkg/internal/swift_package_tool_attrs.bzl @@ -0,0 +1,59 @@ +"""Attributes shared between rules that interact with the Swift package tool.""" + +_swift_package_registry_attrs = { + "registries": attr.label( + allow_single_file = True, + doc = """ +A `registries.json` file that defines the configured Swift package registries. + +The `registries.json` file is used when resolving Swift packages from a \ +Swift package registry. It is created by Swift Package Manager when using \ +the `swift package-registry` commands. + +When using the `swift_package_tool` rules, this file is symlinked to the \ +`config_path` directory defined in the `configure_swift_package` tag. \ +If not using the `swift_package_tool` rules, the file must be in one of \ +Swift Package Manager's search paths or in the manually specified \ +`--config-path` directory. +""", + ), +} + +_swift_package_tool_config_attrs = { + "build_path": attr.string( + doc = "The relative path within the runfiles tree for the Swift Package Manager build directory.", + default = ".build", + ), + "cache_path": attr.string( + doc = "The relative path within the runfiles tree for the shared Swift Package Manager cache directory.", + default = ".cache", + ), + "config_path": attr.string( + doc = "The relative path within the runfiles tree for the Swift Package Manager configuration directory.", + default = ".swiftpm", + ), + "dependency_caching": attr.bool( + doc = "Whether to enable the dependency cache.", + default = True, + ), + "manifest_cache": attr.string( + doc = """Caching mode of Package.swift manifests \ +(shared: shared cache, local: package's build directory, none: disabled) +""", + default = "shared", + values = ["shared", "local", "none"], + ), + "manifest_caching": attr.bool( + doc = "Whether to enable build manifest caching.", + default = True, + ), + "security_path": attr.string( + doc = "The relative path within the runfiles tree for the security directory.", + default = ".security", + ), +} + +swift_package_tool_attrs = struct( + swift_package_registry = _swift_package_registry_attrs, + swift_package_tool_config = _swift_package_tool_config_attrs, +) diff --git a/swiftpkg/internal/swift_package_tool_repo.bzl b/swiftpkg/internal/swift_package_tool_repo.bzl index 037fe7bd1..4543b3f23 100644 --- a/swiftpkg/internal/swift_package_tool_repo.bzl +++ b/swiftpkg/internal/swift_package_tool_repo.bzl @@ -3,18 +3,21 @@ load("@bazel_skylib//lib:dicts.bzl", "dicts") load("@bazel_skylib//lib:types.bzl", "types") load("//swiftpkg/internal:repository_utils.bzl", "repository_utils") -load("//swiftpkg/internal:swift_package_tool.bzl", "SWIFT_PACKAGE_CONFIG_ATTRS") +load("//swiftpkg/internal:swift_package_tool_attrs.bzl", "swift_package_tool_attrs") def _package_config_attrs_to_content(attrs): """Returns a BUILD file compatible string representation of the keyword arguments""" kwargs = repository_utils.struct_to_kwargs( struct = attrs, - keys = SWIFT_PACKAGE_CONFIG_ATTRS, + keys = dicts.add( + swift_package_tool_attrs.swift_package_tool_config, + swift_package_tool_attrs.swift_package_registry, + ), ) kwarg_lines = [] for k, v in kwargs.items(): - if types.is_string(v): + if types.is_string(v) or type(v) == "Label": kwarg_lines.append(" {key} = \"{value}\"".format(key = k, value = v)) elif types.is_bool(v): kwarg_lines.append(" {key} = {value}".format(key = k, value = "True" if v else "False")) @@ -63,7 +66,8 @@ swift_package_tool_repo = repository_rule( mandatory = True, ), }, - SWIFT_PACKAGE_CONFIG_ATTRS, + swift_package_tool_attrs.swift_package_tool_config, + swift_package_tool_attrs.swift_package_registry, ), doc = "Declares a `@swift_package` repository for using the `swift_package_tool` targets.", ) diff --git a/swiftpkg/internal/swift_package_tool_runner_template.sh b/swiftpkg/internal/swift_package_tool_runner_template.sh index f2e810920..638c0d0b3 100644 --- a/swiftpkg/internal/swift_package_tool_runner_template.sh +++ b/swiftpkg/internal/swift_package_tool_runner_template.sh @@ -23,10 +23,12 @@ cmd="%(cmd)s" package_path="$BUILD_WORKSPACE_DIRECTORY/%(package_path)s" build_path="%(build_path)s" cache_path="%(cache_path)s" +config_path="%(config_path)s" enable_build_manifest_caching="%(enable_build_manifest_caching)s" enable_dependency_cache="%(enable_dependency_cache)s" manifest_cache="%(manifest_cache)s" security_path="%(security_path)s" +registries_json="%(registries_json)s" # Construct dynamic arguments. args=() @@ -45,10 +47,16 @@ fi args+=("--manifest-cache=$manifest_cache") +# If registries_json is set, symlink the `.json` file to the `config_path/configuration` directory. +if [ -n "$registries_json" ]; then + mkdir -p "$config_path" && ln -sf "$(readlink -f "$registries_json")" "$config_path/registries.json" +fi + # Run the command. "$swift_worker" swift package \ --build-path "$build_path" \ --cache-path "$cache_path" \ + --config-path "$config_path" \ --package-path "$package_path" \ --security-path "$security_path" \ "$cmd" \