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" \