Skip to content
This repository was archived by the owner on Feb 26, 2026. It is now read-only.

Commit 8230c15

Browse files
authored
feat: add dependencies with traits to PackageInfo (#441)
1 parent b1dec8d commit 8230c15

4 files changed

Lines changed: 148 additions & 18 deletions

File tree

‎Package.resolved‎

Lines changed: 13 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Sources/XcodeGraph/PackageInfo.swift‎

Lines changed: 123 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ public struct PackageInfo: Equatable, Hashable {
1616
/// The traits the package supports
1717
public let traits: [PackageTrait]?
1818

19+
/// The declared package dependencies.
20+
public let dependencies: [PackageDependency]
21+
1922
/// The declared platforms in the manifest.
2023
public let platforms: [Platform]
2124

@@ -33,9 +36,6 @@ public struct PackageInfo: Equatable, Hashable {
3336

3437
// Ignored fields
3538

36-
// /// The declared package dependencies.
37-
// let dependencies: [PackageDependencyDescription]
38-
3939
// /// The pkg-config name of a system package.
4040
// let pkgConfig: String?
4141

@@ -50,6 +50,7 @@ public struct PackageInfo: Equatable, Hashable {
5050
products: [Product],
5151
targets: [Target],
5252
traits: [PackageTrait]?,
53+
dependencies: [PackageDependency],
5354
platforms: [Platform],
5455
cLanguageStandard: String?,
5556
cxxLanguageStandard: String?,
@@ -60,6 +61,7 @@ public struct PackageInfo: Equatable, Hashable {
6061
self.products = products
6162
self.targets = targets
6263
self.traits = traits
64+
self.dependencies = dependencies
6365
self.platforms = platforms
6466
self.cLanguageStandard = cLanguageStandard
6567
self.cxxLanguageStandard = cxxLanguageStandard
@@ -109,6 +111,119 @@ extension PackageInfo {
109111
}
110112
}
111113

114+
// MARK: - PackageDependency
115+
116+
/// A trait enabled for a package dependency, optionally with a condition.
117+
public struct PackageDependencyTrait: Equatable, Hashable, Codable, Sendable {
118+
/// The name of the trait.
119+
public let name: String
120+
121+
/// The condition under which this trait is enabled.
122+
/// When nil, the trait is unconditionally enabled.
123+
/// When set, contains the names of traits that must be enabled for this trait to be active.
124+
public let condition: Set<String>?
125+
126+
public init(name: String, condition: Set<String>? = nil) {
127+
self.name = name
128+
self.condition = condition
129+
}
130+
131+
private struct TraitCondition: Codable {
132+
let traits: Set<String>?
133+
}
134+
135+
private enum CodingKeys: String, CodingKey {
136+
case name
137+
case condition
138+
}
139+
140+
public init(from decoder: Decoder) throws {
141+
let container = try decoder.container(keyedBy: CodingKeys.self)
142+
name = try container.decode(String.self, forKey: .name)
143+
if let conditionData = try container.decodeIfPresent(TraitCondition.self, forKey: .condition) {
144+
condition = conditionData.traits
145+
} else {
146+
condition = nil
147+
}
148+
}
149+
150+
public func encode(to encoder: Encoder) throws {
151+
var container = encoder.container(keyedBy: CodingKeys.self)
152+
try container.encode(name, forKey: .name)
153+
if let condition {
154+
try container.encode(TraitCondition(traits: condition), forKey: .condition)
155+
}
156+
}
157+
}
158+
159+
/// A package dependency with its identity and enabled traits.
160+
public struct PackageDependency: Equatable, Hashable, Codable, Sendable {
161+
/// The identity of the package dependency.
162+
public let identity: String
163+
164+
/// The traits enabled for this dependency, with optional conditions.
165+
public let traits: [PackageDependencyTrait]
166+
167+
public init(identity: String, traits: [PackageDependencyTrait]) {
168+
self.identity = identity
169+
self.traits = traits
170+
}
171+
172+
private enum CodingKeys: String, CodingKey {
173+
case fileSystem
174+
case sourceControl
175+
case registry
176+
}
177+
178+
private struct FileSystemDependency: Codable {
179+
let identity: String
180+
let traits: [PackageDependencyTrait]?
181+
}
182+
183+
private struct SourceControlDependency: Codable {
184+
let identity: String
185+
let traits: [PackageDependencyTrait]?
186+
}
187+
188+
private struct RegistryDependency: Codable {
189+
let identity: String
190+
let traits: [PackageDependencyTrait]?
191+
}
192+
193+
public init(from decoder: Decoder) throws {
194+
let container = try decoder.container(keyedBy: CodingKeys.self)
195+
196+
if let fileSystemDeps = try container.decodeIfPresent([FileSystemDependency].self, forKey: .fileSystem),
197+
let dep = fileSystemDeps.first
198+
{
199+
identity = dep.identity
200+
traits = dep.traits ?? []
201+
} else if let sourceControlDeps = try container.decodeIfPresent([SourceControlDependency].self, forKey: .sourceControl),
202+
let dep = sourceControlDeps.first
203+
{
204+
identity = dep.identity
205+
traits = dep.traits ?? []
206+
} else if let registryDeps = try container.decodeIfPresent([RegistryDependency].self, forKey: .registry),
207+
let dep = registryDeps.first
208+
{
209+
identity = dep.identity
210+
traits = dep.traits ?? []
211+
} else {
212+
throw DecodingError.dataCorrupted(
213+
DecodingError.Context(
214+
codingPath: decoder.codingPath,
215+
debugDescription: "Expected fileSystem, sourceControl, or registry dependency"
216+
)
217+
)
218+
}
219+
}
220+
221+
public func encode(to encoder: Encoder) throws {
222+
var container = encoder.container(keyedBy: CodingKeys.self)
223+
try container.encode([FileSystemDependency(identity: identity, traits: traits)], forKey: .fileSystem)
224+
}
225+
}
226+
112227
extension PackageInfo {
113228
/// A package dependency of a Swift package.
114229
///
@@ -638,7 +753,7 @@ extension PackageInfo: Codable {
638753

639754
private enum CodingKeys: String, CodingKey {
640755
case name, products, targets, platforms, cLanguageStandard, cxxLanguageStandard, swiftLanguageVersions, toolsVersion,
641-
traits
756+
traits, dependencies
642757
}
643758

644759
public init(from decoder: Decoder) throws {
@@ -666,6 +781,7 @@ extension PackageInfo: Codable {
666781
}
667782
self.toolsVersion = toolsVersion
668783
traits = try values.decodeIfPresent([PackageTrait].self, forKey: .traits)
784+
dependencies = try values.decodeIfPresent([PackageDependency].self, forKey: .dependencies) ?? []
669785
}
670786

671787
public func encode(to encoder: any Encoder) throws {
@@ -675,6 +791,7 @@ extension PackageInfo: Codable {
675791
try container.encode(targets, forKey: .targets)
676792
try container.encode(platforms, forKey: .platforms)
677793
try container.encode(traits, forKey: .traits)
794+
try container.encode(dependencies, forKey: .dependencies)
678795
try container.encodeIfPresent(cLanguageStandard, forKey: .cLanguageStandard)
679796
try container.encodeIfPresent(cxxLanguageStandard, forKey: .cxxLanguageStandard)
680797
try container.encodeIfPresent(swiftLanguageVersions, forKey: .swiftLanguageVersions)
@@ -848,6 +965,7 @@ extension PackageInfo.Target.TargetType {
848965
products: [Product] = [],
849966
targets: [Target] = [],
850967
traits: [PackageTrait] = [],
968+
dependencies: [PackageDependency] = [],
851969
platforms: [Platform] = [],
852970
cLanguageStandard: String? = nil,
853971
cxxLanguageStandard: String? = nil,
@@ -859,6 +977,7 @@ extension PackageInfo.Target.TargetType {
859977
products: products,
860978
targets: targets,
861979
traits: traits,
980+
dependencies: dependencies,
862981
platforms: platforms,
863982
cLanguageStandard: cLanguageStandard,
864983
cxxLanguageStandard: cxxLanguageStandard,
Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
public struct PackageTrait: Equatable, Hashable, Codable {
1+
public struct PackageTrait: Equatable, Hashable, Codable, Sendable {
22
/// The list of traits that are enabled by default.
33
public let enabledTraits: [String]
44

@@ -7,4 +7,14 @@ public struct PackageTrait: Equatable, Hashable, Codable {
77

88
/// Trait description
99
public let description: String?
10+
11+
public init(
12+
enabledTraits: [String],
13+
name: String,
14+
description: String?
15+
) {
16+
self.enabledTraits = enabledTraits
17+
self.name = name
18+
self.description = description
19+
}
1020
}

‎Tests/XcodeGraphTests/Models/PackageInfoTests.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct PackageInfoTests {
6161
description: "This is the default Tuist trait"
6262
),
6363
],
64+
dependencies: [],
6465
platforms: [
6566
PackageInfo.Platform(platformName: "iOS", version: "17.2", options: []),
6667
],

0 commit comments

Comments
 (0)