Skip to content

Commit 377a87e

Browse files
authored
feat: added CocoaPods support (#1)
* feat: added CocoaPods support * refactor: disable testing related podspecs for now * chore: fixed build failure * chore: fixed script permission
1 parent 5cc5919 commit 377a87e

File tree

14 files changed

+260
-5
lines changed

14 files changed

+260
-5
lines changed

.github/config/spellcheck-wordlist.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,5 @@ customizable
5454
enum
5555
enums
5656
conformances
57+
Podfile
58+
cocoapods

.github/workflows/main.yml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,21 @@ jobs:
7878
]
7979
}
8080
81+
cocoapods-test:
82+
name: CocoaPods
83+
uses: SwiftyLab/ci/.github/workflows/cocoapods.yml@main
84+
strategy:
85+
matrix:
86+
platforms: ['macos tvos', 'ios']
87+
with:
88+
os: macos-13
89+
xcode: latest
90+
platforms: ${{ matrix.platforms }}
91+
8192
ci:
8293
name: CI
8394
if: github.event_name == 'push'
84-
needs: [analyze, spell-check, swift-package-test]
95+
needs: [analyze, spell-check, swift-package-test, cocoapods-test]
8596
uses: SwiftyLab/ci/.github/workflows/ci.yml@main
8697

8798
cd:
@@ -91,8 +102,9 @@ jobs:
91102
github.event_name == 'workflow_dispatch' &&
92103
github.event.inputs.release == 'true' &&
93104
(needs.ci.result == 'success' || needs.ci.result == 'skipped') &&
94-
(needs.swift-package-test.result == 'success' || needs.swift-package-test.result == 'skipped')
95-
needs: [analyze, spell-check, swift-package-test, ci]
105+
(needs.swift-package-test.result == 'success' || needs.swift-package-test.result == 'skipped') &&
106+
(needs.cocoapods-test.result == 'success' || needs.cocoapods-test.result == 'skipped')
107+
needs: [analyze, spell-check, swift-package-test, cocoapods-test, ci]
96108
uses: SwiftyLab/ci/.github/workflows/cd.yml@main
97109
with:
98110
version: ${{ github.event.inputs.version }}

MetaCodable.podspec

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Pod::Spec.new do |s|
2+
require_relative 'Utils/spec'
3+
s.extend MetaCodable::Spec
4+
s.define(false)
5+
s.default_subspec = 'Macro'
6+
7+
s.subspec 'Macro' do |ms|
8+
ms.dependency 'MetaCodableMacro', "= #{s.version}"
9+
end
10+
11+
s.subspec 'HelperCoders' do |ms|
12+
ms.dependency 'MetaCodableHelperCoders', "= #{s.version}"
13+
end
14+
15+
s.test_spec do |ts|
16+
ts.source_files = "Tests/#{s.name}Tests/HelperCoders/**/*.swift"
17+
# ts.dependency 'MetaCodableMacroPluginCore', "= #{s.version}"
18+
# ts.dependency 'MetaCodableMacroPlugin', "= #{s.version}"
19+
ts.dependency 'MetaCodable/Macro', "= #{s.version}"
20+
ts.dependency 'MetaCodable/HelperCoders', "= #{s.version}"
21+
# ts.dependency 'SwiftSyntax/MacrosTestSupport', s.swift_syntax_constraint
22+
23+
macro_spec = Pod::Specification.from_file(File.join(File.dirname(__FILE__), 'MetaCodableMacro.podspec'))
24+
ts.pod_target_xcconfig = macro_spec.attributes_hash['user_target_xcconfig']
25+
end
26+
end

MetaCodableHelperCoders.podspec

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Pod::Spec.new do |s|
2+
require_relative 'Utils/spec'
3+
s.extend MetaCodable::Spec
4+
s.module_name = "HelperCoders"
5+
s.define
6+
s.dependency 'MetaCodableMacro', "= #{s.version}"
7+
end

MetaCodableMacro.podspec

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
Pod::Spec.new do |s|
2+
require_relative 'Utils/spec'
3+
s.extend MetaCodable::Spec
4+
s.module_name = "MetaCodable"
5+
s.define
6+
7+
sources_dir = 'Sources'
8+
plugin_module = 'MacroPlugin'
9+
manifest_file = 'Package.swift'
10+
plugin_core = 'PluginCore'
11+
12+
script_path = 'Utils/macro_plugin_build.sh'
13+
config = ENV['METACODABLE_COCOAPODS_LINT'] ? "debug" : "release"
14+
preserved_sources = "{#{manifest_file},#{sources_dir}/{#{plugin_module},#{plugin_core}}/**/*.swift,#{script_path}}"
15+
inputs = Dir.glob(preserved_sources).map { |path| "$(PODS_TARGET_SRCROOT)/#{path}" }
16+
build_path = "${PODS_BUILD_DIR}/Macros/#{plugin_module}"
17+
plugin_path = "#{build_path}/#{config}/#{plugin_module}##{plugin_module}"
18+
plugin_output = "$(PODS_BUILD_DIR)/Macros/#{plugin_module}/#{config}/#{plugin_module}"
19+
script = <<-SCRIPT
20+
echo "env -i PATH=\\"$PATH\\" SRCROOT=\\"$PODS_TARGET_SRCROOT\\" BUILD_DIR=\\"$PODS_BUILD_DIR\\" TOOLCHAIN=\\"$DT_TOOLCHAIN_DIR\\" CONFIG=#{config} $METACODABLE_PLUGIN_BUILD_ENVIRONMENT \\"${PODS_TARGET_SRCROOT}/#{script_path}\\""
21+
env -i PATH="$PATH" SRCROOT="$PODS_TARGET_SRCROOT" BUILD_DIR="$PODS_BUILD_DIR" TOOLCHAIN="$DT_TOOLCHAIN_DIR" CONFIG=#{config} $METACODABLE_PLUGIN_BUILD_ENVIRONMENT "${PODS_TARGET_SRCROOT}/#{script_path}"
22+
SCRIPT
23+
24+
s.preserve_paths = "*.md", "LICENSE", manifest_file, "#{sources_dir}/{#{plugin_module},#{plugin_core}}", script_path
25+
s.script_phase = {
26+
:name => 'Build MetaCodable macro plugin',
27+
:script => script,
28+
:input_files => inputs, :output_files => [plugin_output],
29+
:execution_position => :before_compile
30+
}
31+
32+
s.user_target_xcconfig = {
33+
'OTHER_SWIFT_FLAGS' => "-Xfrontend -load-plugin-executable -Xfrontend #{plugin_path}",
34+
'METACODABLE_PLUGIN_BUILD_ENVIRONMENT' => 'METACODABLE_BEING_USED_FROM_COCOAPODS=true'
35+
}
36+
end

Package.swift

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// swift-tools-version: 5.9
22

3+
import Foundation
34
import PackageDescription
45
import CompilerPluginSupport
56

@@ -78,8 +79,29 @@ let package = Package(
7879
]
7980
)
8081

82+
extension Package.Dependency.Kind {
83+
var repoName: String? {
84+
guard
85+
case let .sourceControl(
86+
name: _, location: location, requirement: _
87+
) = self,
88+
let location = URL(string: location),
89+
let name = location.lastPathComponent.split(separator: ".").first
90+
else { return nil }
91+
return String(name)
92+
}
93+
}
94+
95+
var unusedDeps: [String] = []
96+
var includeTargets: [String] = []
97+
var includeProducts: [String] = []
98+
99+
if Context.environment["METACODABLE_CI"] == nil {
100+
unusedDeps.append(contentsOf: ["swift-format", "swift-docc-plugin"])
101+
}
102+
81103
if Context.environment["SWIFT_SYNTAX_EXTENSION_MACRO_FIXED"] != nil {
82-
package.dependencies.remove(at: 0)
104+
package.dependencies.removeAll { $0.kind.repoName == "swift-syntax" }
83105
package.dependencies.append(
84106
.package(
85107
url: "https://github.com/soumyamahunt/swift-syntax.git",
@@ -94,3 +116,46 @@ if Context.environment["SWIFT_SYNTAX_EXTENSION_MACRO_FIXED"] != nil {
94116
target.swiftSettings = settings
95117
}
96118
}
119+
120+
if Context.environment["METACODABLE_BEING_USED_FROM_COCOAPODS"] != nil {
121+
includeTargets.append(contentsOf: ["PluginCore", "MacroPlugin"])
122+
includeProducts.append("MacroPlugin")
123+
package.products.append(.executable(name: "MacroPlugin", targets: ["MacroPlugin"]))
124+
package.targets = package.targets.compactMap { target in
125+
guard target.type == .macro else { return target }
126+
return .executableTarget(
127+
name: target.name,
128+
dependencies: target.dependencies,
129+
path: target.path,
130+
exclude: target.exclude,
131+
sources: target.sources,
132+
resources: target.resources,
133+
publicHeadersPath: target.publicHeadersPath,
134+
cSettings: target.cSettings,
135+
cxxSettings: target.cxxSettings,
136+
swiftSettings: target.swiftSettings,
137+
linkerSettings: target.linkerSettings,
138+
plugins: target.plugins
139+
)
140+
}
141+
142+
if Context.environment["METACODABLE_COCOAPODS_PROTOCOL_PLUGIN"] != nil {
143+
includeTargets.append("ProtocolGen")
144+
includeProducts.append("ProtocolGen")
145+
package.products.append(
146+
.executable(name: "ProtocolGen", targets: ["ProtocolGen"])
147+
)
148+
} else {
149+
unusedDeps.append("swift-argument-parser")
150+
}
151+
}
152+
153+
package.dependencies.removeAll { unusedDeps.contains($0.kind.repoName ?? "") }
154+
155+
if !includeTargets.isEmpty {
156+
package.targets.removeAll { !includeTargets.contains($0.name) }
157+
}
158+
159+
if !includeProducts.isEmpty {
160+
package.products.removeAll { !includeProducts.contains($0.name) }
161+
}

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
[![API Docs](http://img.shields.io/badge/Read_the-docs-2196f3.svg)](https://swiftpackageindex.com/SwiftyLab/MetaCodable/documentation/metacodable)
44
[![Swift Package Manager Compatible](https://img.shields.io/github/v/tag/SwiftyLab/MetaCodable?label=SPM&color=orange)](https://badge.fury.io/gh/SwiftyLab%2FMetaCodable)
5+
[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/MetaCodable.svg?label=CocoaPods&color=C90005)](https://badge.fury.io/co/MetaCodable)
56
[![Swift](https://img.shields.io/badge/Swift-5.9+-orange)](https://img.shields.io/badge/Swift-5-DE5D43)
67
[![Platforms](https://img.shields.io/badge/Platforms-all-sucess)](https://img.shields.io/badge/Platforms-all-sucess)
78
[![CI/CD](https://github.com/SwiftyLab/MetaCodable/actions/workflows/main.yml/badge.svg)](https://github.com/SwiftyLab/MetaCodable/actions/workflows/main.yml)
@@ -37,7 +38,7 @@ Supercharge `Swift`'s `Codable` implementations with macros.
3738

3839
| Platform | Minimum Swift Version | Installation | Status |
3940
| --- | --- | --- | --- |
40-
| iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 6.0+ | 5.9 | Swift Package Manager | Fully Tested |
41+
| iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 6.0+ | 5.9 | Swift Package Manager, CocoaPods | Fully Tested |
4142
| Linux | 5.9 | Swift Package Manager | Fully Tested |
4243
| Windows | 5.9.1 | Swift Package Manager | Fully Tested |
4344

@@ -60,6 +61,16 @@ Then you can add the `MetaCodable` module product as dependency to the `target`s
6061
.product(name: "MetaCodable", package: "MetaCodable"),
6162
```
6263

64+
</details>
65+
<details>
66+
<summary><h3>CocoaPods</h3></summary>
67+
68+
[CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate `MetaCodable` into your Xcode project using CocoaPods, specify it in your `Podfile`:
69+
70+
```ruby
71+
pod 'MetaCodable'
72+
```
73+
6374
</details>
6475

6576
## Usage

Sources/HelperCoders/HelperCoders.docc/HelperCoders.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ Level up ``/MetaCodable``'s generated implementations with helpers assisting com
3636
.product(name: "HelperCoders", package: "MetaCodable"),
3737
```
3838
}
39+
40+
@Tab("CocoaPods") {
41+
42+
[CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate `HelperCoders` into your Xcode project using CocoaPods, specify it in your `Podfile`:
43+
44+
```ruby
45+
pod 'MetaCodable/HelperCoders'
46+
```
47+
}
3948
}
4049

4150
## Topics

Sources/MetaCodable/MetaCodable.docc/MetaCodable.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ Supercharge `Swift`'s `Codable` implementations with macros.
4848
.product(name: "MetaCodable", package: "MetaCodable"),
4949
```
5050
}
51+
52+
@Tab("CocoaPods") {
53+
54+
[CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate `MetaCodable` into your Xcode project using CocoaPods, specify it in your `Podfile`:
55+
56+
```ruby
57+
pod 'MetaCodable'
58+
```
59+
}
5160
}
5261

5362
## Topics
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Pod::Spec.new do |s|
2+
require_relative 'Utils/spec'
3+
s.extend MetaCodable::Spec
4+
s.module_name = "MacroPlugin"
5+
s.define
6+
s.dependency 'MetaCodableMacroPluginCore', "= #{s.version}"
7+
s.dependency 'SwiftSyntax/Lib', s.swift_syntax_constraint
8+
s.dependency 'SwiftSyntax/Macros', s.swift_syntax_constraint
9+
s.dependency 'SwiftSyntax/CompilerPlugin', s.swift_syntax_constraint
10+
end

0 commit comments

Comments
 (0)