From c61efa37e5800c87a54d634ef439d8f230584af9 Mon Sep 17 00:00:00 2001
From: Tony Li <tony.li@automattic.com>
Date: Tue, 17 Dec 2024 21:41:07 +1300
Subject: [PATCH 1/3] Integrate uniffi-swift-helper

---
 .buildkite/pipeline.yml                       |   2 +-
 .buildkite/swift-test.sh                      |   3 +
 .buildkite/validate-cocoapods.sh              |   4 +-
 .gitignore                                    |   1 +
 Cargo.lock                                    | 172 ++++++--
 Cargo.toml                                    |   6 +-
 Makefile                                      |  54 +--
 Package.swift                                 | 132 ------
 .../Sources/wordpress-api-wrapper/README.md   |   3 -
 scripts/swift-bindings.sh                     |  47 ---
 swift_helper_cli/Cargo.toml                   |   8 +
 swift_helper_cli/src/main.rs                  |   3 +
 xcframework/Cargo.toml                        |   9 -
 xcframework/src/main.rs                       | 379 ------------------
 14 files changed, 178 insertions(+), 645 deletions(-)
 delete mode 100644 Package.swift
 delete mode 100644 native/swift/Sources/wordpress-api-wrapper/README.md
 delete mode 100755 scripts/swift-bindings.sh
 create mode 100644 swift_helper_cli/Cargo.toml
 create mode 100644 swift_helper_cli/src/main.rs
 delete mode 100644 xcframework/Cargo.toml
 delete mode 100644 xcframework/src/main.rs

diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml
index ce8dfbb4a..cb7e1c053 100644
--- a/.buildkite/pipeline.yml
+++ b/.buildkite/pipeline.yml
@@ -66,7 +66,7 @@ steps:
 
           echo "--- :swift: Building xcframework"
           make xcframework
-          zip -r target/libwordpressFFI.xcframework.zip target/libwordpressFFI.xcframework
+          zip -r target/libwordpressFFI.xcframework.zip target/libwordpressFFI/libwordpressFFI.xcframework
         artifact_paths:
           - target/libwordpressFFI.xcframework.zip
           - native/swift/Sources/wordpress-api-wrapper/wp_api.swift
diff --git a/.buildkite/swift-test.sh b/.buildkite/swift-test.sh
index 2155606e7..16ad6c84a 100755
--- a/.buildkite/swift-test.sh
+++ b/.buildkite/swift-test.sh
@@ -6,6 +6,9 @@ set -euo pipefail
 
 export SKIP_PACKAGE_WP_API=true
 
+echo "--- :swift: Generating Package.swift"
+make generate-swift-package-manifest
+
 function run_tests() {
     local platform; platform=$1
     echo "--- :swift: Testing on $platform simulator"
diff --git a/.buildkite/validate-cocoapods.sh b/.buildkite/validate-cocoapods.sh
index f9695797c..dd463707c 100755
--- a/.buildkite/validate-cocoapods.sh
+++ b/.buildkite/validate-cocoapods.sh
@@ -24,12 +24,12 @@ Pod::Spec.new do |spec|
   spec.ios.deployment_target = '13.0'
   spec.osx.deployment_target = '11.0'
 
-  # zip -r swift-source-archive.zip native/swift target/libwordpressFFI.xcframework
+  # zip -r swift-source-archive.zip native/swift target/libwordpressFFI/libwordpressFFI.xcframework
   spec.source       = { :http => "http://s3.com/WordPressAPI.zip" }
 
   spec.swift_version = '5.10'
   spec.source_files  = 'native/swift/Sources/**/*.{swift}'
-  spec.vendored_frameworks = 'target/libwordpressFFI.xcframework'
+  spec.vendored_frameworks = 'target/libwordpressFFI/libwordpressFFI.xcframework'
 
   spec.pod_target_xcconfig = {
     'SWIFT_PACKAGE_NAME' => 'WordPressAPI'
diff --git a/.gitignore b/.gitignore
index df83c0b9c..6d1c4e7c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,7 @@ xcuserdata
 DerivedData
 fastlane/report.xml
 libwordPressFFI.xcframework*
+/Package.swift
 
 # Auto-generated Swift Files
 native/swift/Sources/wordpress-api-wrapper/*.swift
diff --git a/Cargo.lock b/Cargo.lock
index cca586ca8..332ab8262 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -353,7 +353,21 @@ dependencies = [
  "semver",
  "serde",
  "serde_json",
- "thiserror",
+ "thiserror 1.0.69",
+]
+
+[[package]]
+name = "cargo_metadata"
+version = "0.19.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8769706aad5d996120af43197bf46ef6ad0fda35216b4505f926a365a232d924"
+dependencies = [
+ "camino",
+ "cargo-platform",
+ "semver",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.7",
 ]
 
 [[package]]
@@ -559,9 +573,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
 
 [[package]]
 name = "errno"
-version = "0.3.9"
+version = "0.3.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
 dependencies = [
  "libc",
  "windows-sys",
@@ -569,9 +583,9 @@ dependencies = [
 
 [[package]]
 name = "fastrand"
-version = "2.1.0"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
 
 [[package]]
 name = "figment"
@@ -902,6 +916,15 @@ version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
 
+[[package]]
+name = "humansize"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7"
+dependencies = [
+ "libm",
+]
+
 [[package]]
 name = "hyper"
 version = "0.14.30"
@@ -1239,9 +1262,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
 [[package]]
 name = "libc"
-version = "0.2.155"
+version = "0.2.168"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
+checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d"
+
+[[package]]
+name = "libm"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
 
 [[package]]
 name = "linux-raw-sys"
@@ -1539,6 +1568,12 @@ version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
 
+[[package]]
+name = "pathdiff"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
+
 [[package]]
 name = "pear"
 version = "0.2.9"
@@ -1835,6 +1870,47 @@ dependencies = [
  "windows-sys",
 ]
 
+[[package]]
+name = "rinja"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3dc4940d00595430b3d7d5a01f6222b5e5b51395d1120bdb28d854bb8abb17a5"
+dependencies = [
+ "humansize",
+ "itoa",
+ "percent-encoding",
+ "rinja_derive",
+]
+
+[[package]]
+name = "rinja_derive"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d9ed0146aef6e2825f1b1515f074510549efba38d71f4554eec32eb36ba18b"
+dependencies = [
+ "basic-toml",
+ "memchr",
+ "mime",
+ "mime_guess",
+ "proc-macro2",
+ "quote",
+ "rinja_parser",
+ "rustc-hash",
+ "serde",
+ "syn",
+]
+
+[[package]]
+name = "rinja_parser"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93f9a866e2e00a7a1fb27e46e9e324a6f7c0e7edc4543cae1d38f4e4a100c610"
+dependencies = [
+ "memchr",
+ "nom",
+ "serde",
+]
+
 [[package]]
 name = "rocket"
 version = "0.5.1"
@@ -1964,6 +2040,12 @@ version = "0.1.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
 
+[[package]]
+name = "rustc-hash"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497"
+
 [[package]]
 name = "rustc_version"
 version = "0.4.0"
@@ -1975,9 +2057,9 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.38.34"
+version = "0.38.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
+checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
 dependencies = [
  "bitflags",
  "errno",
@@ -2326,6 +2408,14 @@ version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
 
+[[package]]
+name = "swift_helper_cli"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "uniffi-swift-helper",
+]
+
 [[package]]
 name = "syn"
 version = "2.0.90"
@@ -2386,12 +2476,13 @@ checksum = "42a4d50cdb458045afc8131fd91b64904da29548bcb63c7236e0844936c13078"
 
 [[package]]
 name = "tempfile"
-version = "3.10.1"
+version = "3.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
+checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
 dependencies = [
  "cfg-if",
  "fastrand",
+ "once_cell",
  "rustix",
  "windows-sys",
 ]
@@ -2420,7 +2511,16 @@ version = "1.0.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
 dependencies = [
- "thiserror-impl",
+ "thiserror-impl 1.0.69",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93605438cbd668185516ab499d589afb7ee1859ea3d5fc8f6b0755e1c7443767"
+dependencies = [
+ "thiserror-impl 2.0.7",
 ]
 
 [[package]]
@@ -2434,6 +2534,17 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "thiserror-impl"
+version = "2.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1d8749b4531af2117677a5fcd12b1348a3fe2b81e36e61ffeac5c4aa3273e36"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "thread_local"
 version = "1.1.8"
@@ -2777,7 +2888,7 @@ checksum = "4cb08c58c7ed7033150132febe696bef553f891b1ede57424b40d87a89e3c170"
 dependencies = [
  "anyhow",
  "camino",
- "cargo_metadata",
+ "cargo_metadata 0.15.4",
  "clap",
  "uniffi_bindgen",
  "uniffi_build",
@@ -2785,6 +2896,22 @@ dependencies = [
  "uniffi_macros",
 ]
 
+[[package]]
+name = "uniffi-swift-helper"
+version = "0.1.0"
+source = "git+https://github.com/automattic/uniffi-swift-helper.git?branch=real-stuff#d48ae27a66727a8fcc526e3325c2a35a8ca9eeda"
+dependencies = [
+ "anyhow",
+ "cargo_metadata 0.19.1",
+ "clap",
+ "pathdiff",
+ "rinja",
+ "serde_json",
+ "tempfile",
+ "uniffi",
+ "uniffi_bindgen",
+]
+
 [[package]]
 name = "uniffi_bindgen"
 version = "0.28.3"
@@ -2794,7 +2921,7 @@ dependencies = [
  "anyhow",
  "askama",
  "camino",
- "cargo_metadata",
+ "cargo_metadata 0.15.4",
  "fs-err",
  "glob",
  "goblin",
@@ -2881,7 +3008,7 @@ checksum = "6a6f984f0781f892cc864a62c3a5c60361b1ccbd68e538e6c9fbced5d82268ac"
 dependencies = [
  "anyhow",
  "camino",
- "cargo_metadata",
+ "cargo_metadata 0.15.4",
  "fs-err",
  "once_cell",
 ]
@@ -3318,7 +3445,7 @@ dependencies = [
  "serde",
  "serde_json",
  "strum_macros",
- "thiserror",
+ "thiserror 1.0.69",
  "uniffi",
  "url",
  "uuid",
@@ -3379,7 +3506,7 @@ dependencies = [
  "quote",
  "serde",
  "syn",
- "thiserror",
+ "thiserror 1.0.69",
  "trybuild",
  "uniffi",
 ]
@@ -3397,7 +3524,7 @@ dependencies = [
  "strum",
  "strum_macros",
  "syn",
- "thiserror",
+ "thiserror 1.0.69",
  "toml 0.8.15",
  "trybuild",
  "uniffi",
@@ -3432,15 +3559,6 @@ version = "0.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
 
-[[package]]
-name = "xcframework"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "clap",
- "serde_json",
-]
-
 [[package]]
 name = "yansi"
 version = "1.0.1"
diff --git a/Cargo.toml b/Cargo.toml
index 77201bb97..65bb6f72b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,7 +8,7 @@ members = [
   "wp_derive_request_builder",
   "wp_serde_helper",
   "wp_uniffi_bindgen",
-  "xcframework",
+  "swift_helper_cli",
 ]
 resolver = "2"
 
@@ -43,5 +43,9 @@ tokio = "1.42"
 toml = "0.8"
 trybuild = "1.0"
 uniffi = "0.28"
+uniffi-swift-helper = "0.1.0"
 url = "2.5"
 uuid = "1.11"
+
+[patch.crates-io]
+uniffi-swift-helper = { git = "https://github.com/automattic/uniffi-swift-helper.git", branch = "real-stuff" }
diff --git a/Makefile b/Makefile
index 458e73272..03cb753b5 100644
--- a/Makefile
+++ b/Makefile
@@ -61,58 +61,22 @@ release-on-ci:
 	@echo "Swift package will be released by https://buildkite.com/automattic/wordpress-rs/builds/$$(jq -r '.number' .build/buildkite_release_job_response.json)"
 	@echo "Once that job finishes, Android libraries will be release by https://buildkite.com/automattic/wordpress-rs/builds?branch=$(WORDPRESS_RS_NEW_VERSION)"
 
-apple-platform-targets-macos := x86_64-apple-darwin aarch64-apple-darwin
-apple-platform-targets-ios := aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
-apple-platform-targets-tvos := aarch64-apple-tvos aarch64-apple-tvos-sim
-apple-platform-targets-watchos := arm64_32-apple-watchos x86_64-apple-watchos-sim aarch64-apple-watchos-sim
-apple-platform-targets := \
-	$(apple-platform-targets-macos) \
-	$(apple-platform-targets-ios) \
-	$(apple-platform-targets-tvos) \
-	$(apple-platform-targets-watchos)
-
 ifeq ($(BUILDKITE), true)
 CARGO_PROFILE ?= release
-CARGO_PROFILE_DIRNAME := release
 else
 CARGO_PROFILE ?= dev
-CARGO_PROFILE_DIRNAME := debug
 endif
 
-cargo_config_library = --config profile.$(CARGO_PROFILE).debug=true --config 'profile.$(CARGO_PROFILE).panic="abort"'
-
-# Set deployment targets for each platform
-_build-apple-%-darwin: export MACOSX_DEPLOYMENT_TARGET=$(swift_package_platform_macos)
-_build-apple-%-ios _build-apple-%-ios-sim: export IPHONEOS_DEPLOYMENT_TARGET=$(swift_package_platform_ios)
-_build-apple-%-tvos _build-apple-%-tvos-sim: export TVOS_DEPLOYMENT_TARGET=$(swift_package_platform_tvos)
-_build-apple-%-watchos _build-apple-%-watchos-sim: export WATCHOS_DEPLOYMENT_TARGET=$(swift_package_platform_watchos)
-
-# Use nightly toolchain for tvOS and watchOS
-_build-apple-%-tvos _build-apple-%-tvos-sim _build-apple-%-watchos _build-apple-%-watchos-sim: \
-	CARGO_OPTS = +$(rust_nightly_toolchain) -Z build-std=panic_abort,std
-
-# Build the library for a specific target
-_build-apple-%:
-	cargo $(CARGO_OPTS) $(cargo_config_library) build --target $* --package wp_api --profile $(CARGO_PROFILE)
-	./scripts/swift-bindings.sh target/$*/$(CARGO_PROFILE_DIRNAME)/libwp_api.a
-
-# Build the library for one single platform, including real device and simulator.
-build-apple-platform-macos := $(addprefix _build-apple-,$(apple-platform-targets-macos))
-build-apple-platform-ios := $(addprefix _build-apple-,$(apple-platform-targets-ios))
-build-apple-platform-tvos := $(addprefix _build-apple-,$(apple-platform-targets-tvos))
-build-apple-platform-watchos := $(addprefix _build-apple-,$(apple-platform-targets-watchos))
-
 # Creating xcframework for one single platform, including real device and simulator.
-xcframework-only-macos: $(build-apple-platform-macos)
-xcframework-only-ios: $(build-apple-platform-ios)
-xcframework-only-tvos: $(build-apple-platform-tvos)
-xcframework-only-watchos: $(build-apple-platform-watchos)
-xcframework-only-%:
-	cargo run --quiet --bin xcframework -- --profile $(CARGO_PROFILE) --targets $(apple-platform-targets-$*)
+xcframework-only-macos:
+	cargo run -q --bin swift_helper_cli build --package wp_api --profile $(CARGO_PROFILE) --ffi-module-name libwordpressFFI --only-macos
+
+xcframework-only-ios:
+	cargo run -q --bin swift_helper_cli build --package wp_api --profile $(CARGO_PROFILE) --ffi-module-name libwordpressFFI --only-ios
 
 # Creating xcframework for all platforms.
-xcframework-all: $(build-apple-platform-macos) $(build-apple-platform-ios) $(build-apple-platform-tvos) $(build-apple-platform-watchos)
-	cargo run --quiet --bin xcframework -- --profile $(CARGO_PROFILE) --targets $(apple-platform-targets)
+xcframework-all:
+	cargo run -q --bin swift_helper_cli build --package wp_api --profile $(CARGO_PROFILE) --ffi-module-name libwordpressFFI
 
 ifeq ($(SKIP_PACKAGE_WP_API),true)
 xcframework:
@@ -123,11 +87,13 @@ endif
 
 xcframework-package: xcframework-all
 	rm -rf libwordpressFFI.xcframework.zip
-	ditto -c -k --sequesterRsrc --keepParent target/libwordpressFFI.xcframework/ libwordpressFFI.xcframework.zip
+	ditto -c -k --sequesterRsrc --keepParent target/libwordpressFFI/libwordpressFFI.xcframework/ libwordpressFFI.xcframework.zip
 
 xcframework-package-checksum:
 	swift package compute-checksum libwordpressFFI.xcframework.zip | tee libwordpressFFI.xcframework.zip.checksum.txt
 
+generate-swift-package-manifest:
+	cargo run -q --bin swift_helper_cli generate-package --package wp_api --ffi-module-name libwordpressFFI --project-name wordpress-rs --package-name-map wp_api:WordpressAPI
 
 docker-image-swift:
 	docker build -t wordpress-rs-swift -f Dockerfile.swift .
diff --git a/Package.swift b/Package.swift
deleted file mode 100644
index cba698bc2..000000000
--- a/Package.swift
+++ /dev/null
@@ -1,132 +0,0 @@
-// swift-tools-version: 6.0
-
-import Foundation
-import PackageDescription
-
-let libwordpressFFIVersion: WordPressRSVersion = .local
-
-#if os(Linux)
-let libwordpressFFI: Target = .systemLibrary(
-        name: "libwordpressFFI",
-        path: "target/release/libwordpressFFI-linux/"
-    )
-#elseif os(macOS)
-let libwordpressFFI: Target = libwordpressFFIVersion.target
-#endif
-
-var package = Package(
-    name: "WordPressAPI",
-    platforms: [
-        .iOS(.v13),
-        .macOS(.v11),
-        .tvOS(.v13),
-        .watchOS(.v8)
-    ],
-    products: [
-        .library(
-            name: "WordPressAPI",
-            targets: ["WordPressAPI"]
-        )
-    ],
-    dependencies: [],
-    targets: [
-        .target(
-            name: "WordPressAPI",
-            dependencies: [
-                .target(name: "WordPressAPIInternal")
-            ],
-            path: "native/swift/Sources/wordpress-api",
-            swiftSettings: [
-                .enableExperimentalFeature("StrictConcurrency"),
-            ]
-        ),
-        .target(
-            name: "WordPressAPIInternal",
-            dependencies: [
-                .target(name: libwordpressFFI.name)
-            ],
-            path: "native/swift/Sources/wordpress-api-wrapper",
-            exclude: [
-                "README.md"
-            ],
-            swiftSettings: [
-                .swiftLanguageMode(.v5)
-            ]
-        ),
-        libwordpressFFI,
-        .testTarget(
-            name: "WordPressAPITests",
-            dependencies: [
-                .target(name: "WordPressAPI"),
-                .target(name: libwordpressFFI.name)
-            ],
-            path: "native/swift/Tests/wordpress-api",
-            resources: [.copy("Resources/Responses/")]
-        )
-    ]
-)
-
-// MARK: - Enable local development toolings
-
-let localDevelopment = libwordpressFFIVersion.isLocal
-
-if localDevelopment {
-    try enableSwiftLint()
-}
-
-// MARK: - Helpers
-
-enum WordPressRSVersion {
-    case local
-    case release(version: String, checksum: String)
-
-    var isLocal: Bool {
-        if case .local = self {
-            return true
-        }
-        return false
-    }
-
-    var target: Target {
-        switch libwordpressFFIVersion {
-        case .local:
-            return .binaryTarget(name: "libwordpressFFI", path: "target/libwordpressFFI.xcframework")
-        case let .release(version, checksum):
-            return .binaryTarget(
-                name: "libwordpressFFI",
-                url: "https://cdn.a8c-ci.services/wordpress-rs/\(version)/libwordpressFFI.xcframework.zip",
-                checksum: checksum
-            )
-        }
-    }
-}
-
-// Add SwiftLint to the package so that we can see linting issues directly from Xcode.
-@MainActor
-func enableSwiftLint() throws {
-#if os(macOS)
-    let filePath = URL(string:"./.swiftlint.yml", relativeTo: URL(filePath: #filePath))!
-    let version = try String(contentsOf: filePath, encoding: .utf8)
-        .split(separator: "\n")
-        .first(where: { $0.starts(with: "swiftlint_version") })?
-        .split(separator: ":")
-        .last?
-        .trimmingCharacters(in: .whitespaces)
-    guard let version else {
-        fatalError("Can't find swiftlint_version in .swiftlint.yml")
-    }
-
-    package.dependencies.append(.package(url: "https://github.com/realm/SwiftLint", exact: .init(version)!))
-
-    var platforms = package.platforms ?? []
-    if let mac = platforms.firstIndex(where: { $0 == .macOS(.v11) }) {
-        platforms.remove(at: mac)
-        platforms.append(.macOS(.v12))
-    }
-    package.platforms = platforms
-
-    if let target = package.targets.first(where: { $0.name == "WordPressAPI" }) {
-        target.plugins = (target.plugins ?? []) + [.plugin(name: "SwiftLintBuildToolPlugin", package: "SwiftLint")]
-    }
-#endif
-}
diff --git a/native/swift/Sources/wordpress-api-wrapper/README.md b/native/swift/Sources/wordpress-api-wrapper/README.md
deleted file mode 100644
index 38a7f7f2d..000000000
--- a/native/swift/Sources/wordpress-api-wrapper/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# wordpress-api-wrapper
-
-The contents of this directory are auto-generated by Rust and uniffi – you should not try to change them manually!
diff --git a/scripts/swift-bindings.sh b/scripts/swift-bindings.sh
deleted file mode 100755
index d55c7c826..000000000
--- a/scripts/swift-bindings.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-if [ $# -ne 1 ]; then
-    echo "Usage: $0 /path/to/library"
-  exit 1
-fi
-
-module_name="libwordpressFFI"
-library_path=$1
-output_dir="$(dirname "$library_path")/swift-bindings"
-rm -rf "$output_dir" && mkdir "$output_dir"
-
-cargo run --release --quiet --bin wp_uniffi_bindgen generate \
-    --library "$library_path" \
-    --out-dir "$output_dir" \
-    --language swift
-
-# The search-and-replace below can be removed after updating to a uniffi-rs
-# version that includes this PR https://github.com/mozilla/uniffi-rs/pull/2341
-for swift_binding in "$output_dir"/*.swift; do
-    options=("-i")
-    if [[ $(uname) == "Darwin" ]]; then
-        options+=("")
-    fi
-    sed "${options[@]}" 's/^protocol UniffiForeignFutureTask /fileprivate protocol UniffiForeignFutureTask /' "$swift_binding"
-done
-
-mv "$output_dir"/*.swift native/swift/Sources/wordpress-api-wrapper/
-
-header_dir="$output_dir/Headers"
-mkdir -p "$header_dir"
-
-{
-    for header_file in "$output_dir"/*.h; do
-        echo "#include \"$(basename "$header_file")\""
-    done
-} > "$header_dir/$module_name.h"
-mv "$output_dir"/*.h "$header_dir/"
-
-cat <<EOF > "$header_dir/module.modulemap"
-module $module_name {
-    header "$module_name.h"
-    export *
-}
-EOF
diff --git a/swift_helper_cli/Cargo.toml b/swift_helper_cli/Cargo.toml
new file mode 100644
index 000000000..fd22a517f
--- /dev/null
+++ b/swift_helper_cli/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "swift_helper_cli"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+uniffi-swift-helper = { workspace = true }
+anyhow = { version = "1.0" }
diff --git a/swift_helper_cli/src/main.rs b/swift_helper_cli/src/main.rs
new file mode 100644
index 000000000..2a23995f9
--- /dev/null
+++ b/swift_helper_cli/src/main.rs
@@ -0,0 +1,3 @@
+fn main() -> anyhow::Result<()> {
+    uniffi_swift_helper::cli_main()
+}
diff --git a/xcframework/Cargo.toml b/xcframework/Cargo.toml
deleted file mode 100644
index 5ec71cdfc..000000000
--- a/xcframework/Cargo.toml
+++ /dev/null
@@ -1,9 +0,0 @@
-[package]
-name = "xcframework"
-version = "0.1.0"
-edition = "2021"
-
-[dependencies]
-anyhow = { workspace = true }
-clap = { workspace = true, features = ["derive"] }
-serde_json = { workspace = true }
diff --git a/xcframework/src/main.rs b/xcframework/src/main.rs
deleted file mode 100644
index 50f8ad226..000000000
--- a/xcframework/src/main.rs
+++ /dev/null
@@ -1,379 +0,0 @@
-use anyhow::{Context, Result};
-use clap::*;
-use std::collections::HashMap;
-use std::fmt::Display;
-use std::path::{Path, PathBuf};
-use std::process::Command;
-
-const XCFRAMEWORK_OUTPUT_PATH: &str = "target/libwordpressFFI.xcframework";
-const LIBRARY_FILENAME: &str = "libwordpress.a";
-
-fn main() -> Result<()> {
-    CreateXCFramework::parse().run()
-}
-
-#[derive(Debug, Parser)]
-pub struct CreateXCFramework {
-    // Non-empty list of targets
-    #[clap(
-        long,
-        num_args = 1..,
-        required = true,
-        help = "List of targets whose static libraries should be included in the xcframework"
-    )]
-    targets: Vec<String>,
-
-    #[clap(
-        long,
-        default_value = "release",
-        help = "Cargo profile used to build the targets"
-    )]
-    profile: String,
-}
-
-impl CreateXCFramework {
-    fn run(&self) -> Result<()> {
-        let temp_dir = std::env::temp_dir().join("wp-rs-xcframework");
-        recreate_directory(&temp_dir)?;
-
-        XCFramework::new(&self.targets, &self.profile)?.create(&temp_dir)?;
-
-        Ok(())
-    }
-}
-
-// Represent a xcframework that contains static libraries for multiple platforms.
-//
-// Since `xcodebuild -create-xcframework` command requires its `-libraray` not
-// having duplicated platform. This type along with `LibraryGroup` and `Slice`
-// work together to make it easier to create a xcframework.
-struct XCFramework {
-    libraries: Vec<LibraryGroup>,
-}
-
-// Represent a group of static libraries that are built for the same platform.
-struct LibraryGroup {
-    id: LibraryGroupId,
-    slices: Vec<Slice>,
-}
-
-// Represent a thin static library which is built with `cargo build --target <target> --profile <profile>`
-struct Slice {
-    target: String,
-    profile: String,
-}
-
-impl XCFramework {
-    fn new(targets: &Vec<String>, profile: &str) -> Result<Self> {
-        let mut groups = HashMap::<LibraryGroupId, LibraryGroup>::new();
-        for target in targets {
-            let id = LibraryGroupId::from_target(target)?;
-            let id_clone = id.clone();
-            groups
-                .entry(id)
-                .or_insert(LibraryGroup {
-                    id: id_clone,
-                    slices: Vec::new(),
-                })
-                .slices
-                .push(Slice {
-                    target: target.clone(),
-                    profile: profile.to_owned(),
-                });
-        }
-
-        Ok(Self {
-            libraries: groups.into_values().collect(),
-        })
-    }
-
-    fn create(&self, temp_dir: &Path) -> Result<PathBuf> {
-        self.preview();
-
-        let temp_dest = self.create_xcframework(temp_dir)?;
-        self.patch_xcframework(&temp_dest)?;
-
-        let dest = PathBuf::from(XCFRAMEWORK_OUTPUT_PATH);
-        recreate_directory(&dest)?;
-        std::fs::rename(temp_dest, &dest).with_context(|| "Failed to move xcframework")?;
-
-        println!("xcframework created at {}", &dest.display());
-        Ok(dest)
-    }
-
-    fn preview(&self) {
-        println!("Creating xcframework to include the following targets:");
-        for lib in &self.libraries {
-            println!("  Platform: {}", lib.id);
-            for slice in &lib.slices {
-                println!("    - {}", slice.target);
-            }
-        }
-    }
-
-    fn create_xcframework(&self, temp_dir: &Path) -> Result<PathBuf> {
-        let temp_dest = temp_dir.join("libwordpressFFI.xcframework");
-        std::fs::remove_dir_all(&temp_dest).ok();
-
-        let library_args: Result<Vec<(PathBuf, PathBuf)>> = self
-            .libraries
-            .iter()
-            .map(|library| {
-                let lib = library.create(temp_dir)?;
-                let header = library.headers_dir()?;
-                Ok((lib, header))
-            })
-            .collect();
-        let library_args = library_args?;
-
-        let library_args = library_args.iter().flat_map(|(lib, headers)| {
-            [
-                "-library".as_ref(),
-                lib.as_os_str(),
-                "-headers".as_ref(),
-                headers.as_os_str(),
-            ]
-        });
-        Command::new("xcodebuild")
-            .arg("-create-xcframework")
-            .args(library_args)
-            .arg("-output")
-            .arg(&temp_dest)
-            .successful_output()?;
-
-        Ok(temp_dest)
-    }
-
-    // Fixes an issue including the XCFramework in an Xcode project that already contains an XCFramework: https://github.com/jessegrosjean/module-map-error
-    fn patch_xcframework(&self, temp_dir: &Path) -> Result<()> {
-        println!("Patching XCFramework to have a unique header directory");
-
-        for dir_entry in std::fs::read_dir(temp_dir)? {
-            let path = dir_entry.expect("Invalid Path").path();
-            if path.is_dir() {
-                let headers_dir = temp_dir.join(&path).join("Headers");
-                let non_lib_files: Vec<PathBuf> = std::fs::read_dir(&headers_dir)?
-                    .flat_map(|f| f.ok())
-                    .filter_map(|f| {
-                        if f.path().ends_with(".a") {
-                            None
-                        } else {
-                            Some(f.path())
-                        }
-                    })
-                    .collect();
-
-                let new_headers_dir = headers_dir.join("libwordpressFFI");
-                recreate_directory(&new_headers_dir)?;
-
-                for file in non_lib_files {
-                    std::fs::rename(&file, new_headers_dir.join(file.file_name().unwrap()))?;
-                }
-            }
-        }
-
-        Ok(())
-    }
-}
-
-impl LibraryGroup {
-    fn create(&self, temp_dir: &Path) -> Result<PathBuf> {
-        let mut libraries: Vec<PathBuf> = Vec::new();
-        for slice in &self.slices {
-            libraries.push(slice.create(temp_dir)?);
-        }
-
-        let dir = temp_dir.join(self.id.to_string());
-        recreate_directory(&dir)?;
-
-        let dest = dir.join(LIBRARY_FILENAME);
-        Command::new("xcrun")
-            .arg("lipo")
-            .arg("-create")
-            .args(libraries)
-            .arg("-output")
-            .arg(&dest)
-            .successful_output()?;
-
-        Ok(dest)
-    }
-
-    fn headers_dir(&self) -> Result<PathBuf> {
-        let slice = self
-            .slices
-            .first()
-            .with_context(|| "No slices in library group")?;
-        let path = slice.built_product_dir().join("swift-bindings/headers");
-        if !path.exists() {
-            anyhow::bail!("Headers not found: {}", path.display())
-        }
-        Ok(path)
-    }
-}
-
-impl Slice {
-    fn create(&self, temp_dir: &Path) -> Result<PathBuf> {
-        let libs = self.built_libraries();
-
-        // If there are more static libraries (a.k.a cargo packages), we'll
-        // need to bundle them together into one static library.
-        // At the moment, we only have one libwp_api, so we can just copy it.
-        assert!(
-            libs.len() == 1,
-            "Expected exactly one library for each slice"
-        );
-
-        let lib = &libs[0];
-        if !lib.exists() {
-            anyhow::bail!("Library not found: {}", lib.display())
-        }
-
-        let dir = temp_dir.join(&self.target);
-        recreate_directory(&dir)?;
-
-        let dest = dir.join(LIBRARY_FILENAME);
-        std::fs::copy(lib, &dest)
-            .with_context(|| format!("Failed to copy {} to {}", lib.display(), dest.display()))?;
-
-        Ok(dest)
-    }
-
-    /// Returns the directory where the built static libraries are located.
-    fn built_product_dir(&self) -> PathBuf {
-        let mut target_dir: PathBuf = ["target", &self.target].iter().collect();
-        if self.profile == "dev" {
-            target_dir.push("debug");
-        } else {
-            target_dir.push(&self.profile);
-        }
-
-        target_dir
-    }
-
-    fn built_libraries(&self) -> Vec<PathBuf> {
-        vec![self.built_product_dir().join("libwp_api.a")]
-    }
-}
-
-#[derive(Debug, PartialEq, Eq, Hash, Clone)]
-struct LibraryGroupId {
-    os: ApplePlatform,
-    is_sim: bool,
-}
-
-#[derive(Debug, PartialEq, Eq, Hash, Clone)]
-enum ApplePlatform {
-    MacOS,
-    #[allow(clippy::upper_case_acronyms)]
-    IOS,
-    TvOS,
-    WatchOS,
-}
-
-impl TryFrom<&str> for ApplePlatform {
-    type Error = anyhow::Error;
-
-    fn try_from(s: &str) -> std::result::Result<Self, anyhow::Error> {
-        match s {
-            "darwin" => Ok(ApplePlatform::MacOS),
-            "ios" => Ok(ApplePlatform::IOS),
-            "tvos" => Ok(ApplePlatform::TvOS),
-            "watchos" => Ok(ApplePlatform::WatchOS),
-            _ => anyhow::bail!("Unknown Apple platform: {}", s),
-        }
-    }
-}
-
-impl Display for ApplePlatform {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        let name = match self {
-            ApplePlatform::MacOS => "macos",
-            ApplePlatform::IOS => "ios",
-            ApplePlatform::TvOS => "tvos",
-            ApplePlatform::WatchOS => "watchos",
-        };
-        write!(f, "{}", name)
-    }
-}
-
-impl LibraryGroupId {
-    fn from_target(target: &str) -> Result<Self> {
-        let mut parts = target.split('-');
-        _ /* arch */= parts.next();
-        if parts.next() != Some("apple") {
-            anyhow::bail!("{} is not an Apple platform", target)
-        }
-
-        let os: ApplePlatform = parts
-            .next()
-            .with_context(|| format!("No OS in target: {}", target))?
-            .try_into()?;
-
-        let output = Command::new("rustc")
-            .env("RUSTC_BOOTSTRAP", "1")
-            .args([
-                "-Z",
-                "unstable-options",
-                "--print",
-                "target-spec-json",
-                "--target",
-            ])
-            .arg(target)
-            .successful_output()?;
-        let json = serde_json::from_slice::<serde_json::Value>(&output.stdout)
-            .with_context(|| "Failed to parse command output as JSON")?;
-        let llvm_target = json
-            .get("llvm-target")
-            .and_then(|t| t.as_str())
-            .with_context(|| "No llvm-target in command output")?;
-
-        Ok(Self {
-            os,
-            is_sim: llvm_target.ends_with("-simulator"),
-        })
-    }
-}
-
-impl Display for LibraryGroupId {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", self.os)?;
-
-        if self.is_sim {
-            write!(f, "-sim")
-        } else {
-            Ok(())
-        }
-    }
-}
-
-trait ExecuteCommand {
-    fn successful_output(&mut self) -> Result<std::process::Output>;
-}
-
-impl ExecuteCommand for Command {
-    fn successful_output(&mut self) -> Result<std::process::Output> {
-        let output = self
-            .output()
-            .with_context(|| format!("Command failed: $ {:?}", self))?;
-        if output.status.success() {
-            Ok(output)
-        } else {
-            anyhow::bail!(
-                "Command failed with exit code: {}\nstdout: {:?}\nstderr: {:?}\n$ {:?}",
-                output.status,
-                String::from_utf8_lossy(&output.stdout),
-                String::from_utf8_lossy(&output.stderr),
-                self
-            )
-        }
-    }
-}
-
-fn recreate_directory(dir: &PathBuf) -> Result<()> {
-    if dir.exists() {
-        std::fs::remove_dir_all(dir)
-            .with_context(|| format!("Failed to remove directory at {:?}", dir))?;
-    }
-
-    std::fs::create_dir_all(dir).with_context(|| format!("Failed to create directory: {:?}", dir))
-}

From 3b149f18e0b1d43bb4337e9960dbd6e4142cb0e4 Mon Sep 17 00:00:00 2001
From: Tony Li <tony.li@automattic.com>
Date: Thu, 19 Dec 2024 11:28:51 +1300
Subject: [PATCH 2/3] Update to the latest uniffi-swift-helper

---
 Cargo.lock         |  4 ++--
 Makefile           | 18 +++++++-----------
 wp_api/uniffi.toml |  1 +
 3 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 332ab8262..d87628747 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2899,7 +2899,7 @@ dependencies = [
 [[package]]
 name = "uniffi-swift-helper"
 version = "0.1.0"
-source = "git+https://github.com/automattic/uniffi-swift-helper.git?branch=real-stuff#d48ae27a66727a8fcc526e3325c2a35a8ca9eeda"
+source = "git+https://github.com/automattic/uniffi-swift-helper.git?branch=real-stuff#dea8a44077fab77d4f2857f98adb1fb92e8cda12"
 dependencies = [
  "anyhow",
  "cargo_metadata 0.19.1",
@@ -2907,7 +2907,7 @@ dependencies = [
  "pathdiff",
  "rinja",
  "serde_json",
- "tempfile",
+ "toml 0.8.15",
  "uniffi",
  "uniffi_bindgen",
 ]
diff --git a/Makefile b/Makefile
index 03cb753b5..88c01ce56 100644
--- a/Makefile
+++ b/Makefile
@@ -69,14 +69,14 @@ endif
 
 # Creating xcframework for one single platform, including real device and simulator.
 xcframework-only-macos:
-	cargo run -q --bin swift_helper_cli build --package wp_api --profile $(CARGO_PROFILE) --ffi-module-name libwordpressFFI --only-macos
+	cargo run -q --bin swift_helper_cli build --profile $(CARGO_PROFILE) --only-macos
 
 xcframework-only-ios:
-	cargo run -q --bin swift_helper_cli build --package wp_api --profile $(CARGO_PROFILE) --ffi-module-name libwordpressFFI --only-ios
+	cargo run -q --bin swift_helper_cli build --profile $(CARGO_PROFILE) --only-ios
 
 # Creating xcframework for all platforms.
 xcframework-all:
-	cargo run -q --bin swift_helper_cli build --package wp_api --profile $(CARGO_PROFILE) --ffi-module-name libwordpressFFI
+	cargo run -q --bin swift_helper_cli build --profile $(CARGO_PROFILE)
 
 ifeq ($(SKIP_PACKAGE_WP_API),true)
 xcframework:
@@ -93,17 +93,13 @@ xcframework-package-checksum:
 	swift package compute-checksum libwordpressFFI.xcframework.zip | tee libwordpressFFI.xcframework.zip.checksum.txt
 
 generate-swift-package-manifest:
-	cargo run -q --bin swift_helper_cli generate-package --package wp_api --ffi-module-name libwordpressFFI --project-name wordpress-rs --package-name-map wp_api:WordpressAPI
+	cargo run -q --bin swift_helper_cli generate-package --project-name wordpress-rs
 
 docker-image-swift:
 	docker build -t wordpress-rs-swift -f Dockerfile.swift .
 
 swift-linux-library:
-	cargo build --release --package wp_api
-	./scripts/swift-bindings.sh target/release/libwp_api.a
-	mkdir -p target/release/libwordpressFFI-linux
-	cp target/release/swift-bindings/Headers/* target/release/libwordpressFFI-linux/
-	cp target/release/libwp_api.a target/release/libwordpressFFI-linux/
+	cargo run -q --bin swift_helper_cli build --profile $(CARGO_PROFILE)
 
 swift-example-app: swift-example-app-mac swift-example-app-ios
 
@@ -119,8 +115,8 @@ test-swift:
 test-swift-linux: docker-image-swift
 	docker run $(docker_opts_shared) -it wordpress-rs-swift make test-swift-linux-in-docker
 
-test-swift-linux-in-docker: swift-linux-library
-	swift test -Xlinker -Ltarget/release/libwordpressFFI-linux -Xlinker -lwp_api
+test-swift-linux-in-docker: swift-linux-library generate-swift-package-manifest
+	swift test -Xlinker -Ltarget/libwordpressFFI/linux -Xlinker -lwordpressFFI
 
 test-swift-darwin: xcframework
 	swift test
diff --git a/wp_api/uniffi.toml b/wp_api/uniffi.toml
index 09850341f..f5d2ec62a 100644
--- a/wp_api/uniffi.toml
+++ b/wp_api/uniffi.toml
@@ -10,3 +10,4 @@ ffi_module_filename = "wp_api_uniffi"
 generate_module_map = false
 generate_immutable_records = true
 experimental_sendable_value_types = true
+wp_spm_public_module_name = "WordPressAPI"

From fb90e1ba1ff31ce25e7b42ba9c240d305425067b Mon Sep 17 00:00:00 2001
From: Tony Li <tony.li@automattic.com>
Date: Thu, 19 Dec 2024 11:29:08 +1300
Subject: [PATCH 3/3] Remove /Package.resolved from git

---
 .gitignore       |  1 +
 Package.resolved | 87 ------------------------------------------------
 2 files changed, 1 insertion(+), 87 deletions(-)
 delete mode 100644 Package.resolved

diff --git a/.gitignore b/.gitignore
index 6d1c4e7c0..e30c380ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,7 @@ DerivedData
 fastlane/report.xml
 libwordPressFFI.xcframework*
 /Package.swift
+/Package.resolved
 
 # Auto-generated Swift Files
 native/swift/Sources/wordpress-api-wrapper/*.swift
diff --git a/Package.resolved b/Package.resolved
deleted file mode 100644
index 1ec466e70..000000000
--- a/Package.resolved
+++ /dev/null
@@ -1,87 +0,0 @@
-{
-  "originHash" : "4c30bcea863fdb29514c7daf20b8911f79465cc6626c1c7fdc311c43d9a8367a",
-  "pins" : [
-    {
-      "identity" : "collectionconcurrencykit",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git",
-      "state" : {
-        "revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95",
-        "version" : "0.2.0"
-      }
-    },
-    {
-      "identity" : "cryptoswift",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/krzyzanowskim/CryptoSwift.git",
-      "state" : {
-        "revision" : "c9c3df6ab812de32bae61fc0cd1bf6d45170ebf0",
-        "version" : "1.8.2"
-      }
-    },
-    {
-      "identity" : "sourcekitten",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/jpsim/SourceKitten.git",
-      "state" : {
-        "revision" : "fd4df99170f5e9d7cf9aa8312aa8506e0e7a44e7",
-        "version" : "0.35.0"
-      }
-    },
-    {
-      "identity" : "swift-argument-parser",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/apple/swift-argument-parser.git",
-      "state" : {
-        "revision" : "0fbc8848e389af3bb55c182bc19ca9d5dc2f255b",
-        "version" : "1.4.0"
-      }
-    },
-    {
-      "identity" : "swift-syntax",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/swiftlang/swift-syntax.git",
-      "state" : {
-        "revision" : "cb53fa1bd3219b0b23ded7dfdd3b2baff266fd25",
-        "version" : "600.0.0"
-      }
-    },
-    {
-      "identity" : "swiftlint",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/realm/SwiftLint",
-      "state" : {
-        "revision" : "25f2776977e663305bee71309ea1e34d435065f1",
-        "version" : "0.57.1"
-      }
-    },
-    {
-      "identity" : "swiftytexttable",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/scottrhoyt/SwiftyTextTable.git",
-      "state" : {
-        "revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3",
-        "version" : "0.9.0"
-      }
-    },
-    {
-      "identity" : "swxmlhash",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/drmohundro/SWXMLHash.git",
-      "state" : {
-        "revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f",
-        "version" : "7.0.2"
-      }
-    },
-    {
-      "identity" : "yams",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/jpsim/Yams.git",
-      "state" : {
-        "revision" : "9234124cff5e22e178988c18d8b95a8ae8007f76",
-        "version" : "5.1.2"
-      }
-    }
-  ],
-  "version" : 3
-}