From d077b46968ea604d8bdaf4e933bbea36c508a336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Pi=C3=B1era?= Date: Wed, 29 Oct 2025 12:37:05 +0100 Subject: [PATCH 1/2] feat: Add support for Swift Package Manager traits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add PackageTrait model and integrate it into PackageInfo to support Swift Package Manager's traits feature, which allows packages to define conditional compilation flags and behavior. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- Sources/XcodeGraph/PackageInfo.swift | 11 ++++++++++- Sources/XcodeGraph/PackageTrait.swift | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Sources/XcodeGraph/PackageTrait.swift diff --git a/Sources/XcodeGraph/PackageInfo.swift b/Sources/XcodeGraph/PackageInfo.swift index 7be49ca1..54036c86 100644 --- a/Sources/XcodeGraph/PackageInfo.swift +++ b/Sources/XcodeGraph/PackageInfo.swift @@ -13,6 +13,9 @@ public struct PackageInfo: Equatable, Hashable { /// The targets declared in the manifest. public let targets: [Target] + /// The traits the package supports + public let traits: [PackageTrait] + /// The declared platforms in the manifest. public let platforms: [Platform] @@ -46,6 +49,7 @@ public struct PackageInfo: Equatable, Hashable { name: String, products: [Product], targets: [Target], + traits: [PackageTrait], platforms: [Platform], cLanguageStandard: String?, cxxLanguageStandard: String?, @@ -55,6 +59,7 @@ public struct PackageInfo: Equatable, Hashable { self.name = name self.products = products self.targets = targets + self.traits = traits self.platforms = platforms self.cLanguageStandard = cLanguageStandard self.cxxLanguageStandard = cxxLanguageStandard @@ -588,7 +593,8 @@ extension PackageInfo: Codable { } private enum CodingKeys: String, CodingKey { - case name, products, targets, platforms, cLanguageStandard, cxxLanguageStandard, swiftLanguageVersions, toolsVersion + case name, products, targets, platforms, cLanguageStandard, cxxLanguageStandard, swiftLanguageVersions, toolsVersion, + traits } public init(from decoder: Decoder) throws { @@ -615,6 +621,7 @@ extension PackageInfo: Codable { ) } self.toolsVersion = toolsVersion + traits = try values.decode([PackageTrait].self, forKey: .traits) } public func encode(to encoder: any Encoder) throws { @@ -795,6 +802,7 @@ extension PackageInfo.Target.TargetType { name: String = "Package", products: [Product] = [], targets: [Target] = [], + traits: [PackageTrait] = [], platforms: [Platform] = [], cLanguageStandard: String? = nil, cxxLanguageStandard: String? = nil, @@ -805,6 +813,7 @@ extension PackageInfo.Target.TargetType { name: name, products: products, targets: targets, + traits: traits, platforms: platforms, cLanguageStandard: cLanguageStandard, cxxLanguageStandard: cxxLanguageStandard, diff --git a/Sources/XcodeGraph/PackageTrait.swift b/Sources/XcodeGraph/PackageTrait.swift new file mode 100644 index 00000000..c4dd682a --- /dev/null +++ b/Sources/XcodeGraph/PackageTrait.swift @@ -0,0 +1,10 @@ +public struct PackageTrait: Equatable, Hashable, Codable { + /// The list of traits that are enabled by default. + public let enabledTraits: [String] + + /// The name of the trait. When a trait just includes enabled traits, this name takes the value of "default" + public let name: String + + /// Trait description + public let description: String? +} From 25faaf76cdf290e9f9de3eb9d94659dca9943896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Pi=C3=B1era?= Date: Wed, 29 Oct 2025 13:47:46 +0100 Subject: [PATCH 2/2] Fix tests --- Sources/XcodeGraph/PackageInfo.swift | 7 ++++--- Tests/XcodeGraphTests/Models/PackageInfoTests.swift | 7 +++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Sources/XcodeGraph/PackageInfo.swift b/Sources/XcodeGraph/PackageInfo.swift index 54036c86..781c00e0 100644 --- a/Sources/XcodeGraph/PackageInfo.swift +++ b/Sources/XcodeGraph/PackageInfo.swift @@ -14,7 +14,7 @@ public struct PackageInfo: Equatable, Hashable { public let targets: [Target] /// The traits the package supports - public let traits: [PackageTrait] + public let traits: [PackageTrait]? /// The declared platforms in the manifest. public let platforms: [Platform] @@ -49,7 +49,7 @@ public struct PackageInfo: Equatable, Hashable { name: String, products: [Product], targets: [Target], - traits: [PackageTrait], + traits: [PackageTrait]?, platforms: [Platform], cLanguageStandard: String?, cxxLanguageStandard: String?, @@ -621,7 +621,7 @@ extension PackageInfo: Codable { ) } self.toolsVersion = toolsVersion - traits = try values.decode([PackageTrait].self, forKey: .traits) + traits = try values.decodeIfPresent([PackageTrait].self, forKey: .traits) } public func encode(to encoder: any Encoder) throws { @@ -630,6 +630,7 @@ extension PackageInfo: Codable { try container.encode(products, forKey: .products) try container.encode(targets, forKey: .targets) try container.encode(platforms, forKey: .platforms) + try container.encode(traits, forKey: .traits) try container.encodeIfPresent(cLanguageStandard, forKey: .cLanguageStandard) try container.encodeIfPresent(cxxLanguageStandard, forKey: .cxxLanguageStandard) try container.encodeIfPresent(swiftLanguageVersions, forKey: .swiftLanguageVersions) diff --git a/Tests/XcodeGraphTests/Models/PackageInfoTests.swift b/Tests/XcodeGraphTests/Models/PackageInfoTests.swift index c8d45ce0..12bbbd47 100644 --- a/Tests/XcodeGraphTests/Models/PackageInfoTests.swift +++ b/Tests/XcodeGraphTests/Models/PackageInfoTests.swift @@ -54,6 +54,13 @@ struct PackageInfoTests { checksum: nil ), ], + traits: [ + PackageTrait( + enabledTraits: ["Tuist"], + name: "Tuist", + description: "This is the default Tuist trait" + ), + ], platforms: [ PackageInfo.Platform(platformName: "iOS", version: "17.2", options: []), ],