From 56ac4278e57582d03ebed7cf1da5d8937527c479 Mon Sep 17 00:00:00 2001 From: Joe Heck Date: Fri, 15 Aug 2025 14:58:27 -0700 Subject: [PATCH 1/2] adds traits to dependency output in show-dependencies --json and --text --- .../Commands/Utilities/DependenciesSerializer.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Sources/Commands/Utilities/DependenciesSerializer.swift b/Sources/Commands/Utilities/DependenciesSerializer.swift index d58e5c58162..31f82582013 100644 --- a/Sources/Commands/Utilities/DependenciesSerializer.swift +++ b/Sources/Commands/Utilities/DependenciesSerializer.swift @@ -34,7 +34,14 @@ final class PlainTextDumper: DependenciesDumper { let pkgVersion = package.manifest.version?.description ?? "unspecified" - stream.send("\(hanger)\(package.identity.description)<\(package.manifest.packageLocation)@\(pkgVersion)>\n") + let traitsEnabled: String + if let enabled = package.enabledTraits, !enabled.isEmpty { + traitsEnabled = "(traits: \(package.enabledTraits?.joined(separator: ", ") ?? ""))" + } else { + traitsEnabled = "" + } + + stream.send("\(hanger)\(package.identity.description)<\(package.manifest.packageLocation)@\(pkgVersion)>\(traitsEnabled)\n") if !package.dependencies.isEmpty { let replacement = (index == packages.count - 1) ? " " : "│ " @@ -130,6 +137,7 @@ final class JSONDumper: DependenciesDumper { "url": .string(package.manifest.packageLocation), "version": .string(package.manifest.version?.description ?? "unspecified"), "path": .string(package.path.pathString), + "traits": .array(package.enabledTraits?.map { .string($0) } ?? []), "dependencies": .array(package.dependencies.compactMap { graph.packages[$0] }.map(convert)), ]) } From 3d29dbe876a2ff829fc6bfdb07f63515a3b1264a Mon Sep 17 00:00:00 2001 From: Joe Heck Date: Tue, 26 Aug 2025 10:39:02 -0700 Subject: [PATCH 2/2] reset tests to validate dependency data with traits using swift-testing --- Tests/CommandsTests/PackageCommandTests.swift | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index ce4a501fda7..492360468af 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -1315,6 +1315,55 @@ struct PackageCommandTests { } } + @Test( + .tags( + .Feature.Command.Package.ShowDependencies, + ), + arguments: getBuildData(for: SupportedBuildSystemOnAllPlatforms), + ) + func showDependenciesWithTraits( + data: BuildData, + ) async throws { + try await fixture(name: "Traits") { fixturePath in + let packageRoot = fixturePath.appending("Example") + let (textOutput, _) = try await execute( + ["show-dependencies", "--format=text"], + packagePath: packageRoot, + configuration: data.config, + buildSystem: data.buildSystem, + ) + #expect(textOutput.contains("(traits: Package3Trait3)")) + + let (jsonOutput, _) = try await execute( + ["show-dependencies", "--format=json"], + packagePath: packageRoot, + configuration: data.config, + buildSystem: data.buildSystem, + ) + let json = try JSON(bytes: ByteString(encodingAsUTF8: jsonOutput)) + guard case .dictionary(let contents) = json else { + Issue.record("unexpected result") + return + } + guard case .string(let name)? = contents["name"] else { + Issue.record("unexpected result") + return + } + #expect(name == "TraitsExample") + + // verify the traits JSON entry lists each of the traits in the fixture + guard case .array(let traitsProperty)? = contents["traits"] else { + Issue.record("unexpected result") + return + } + #expect(traitsProperty.contains(.string("Package1"))) + #expect(traitsProperty.contains(.string("Package2"))) + #expect(traitsProperty.contains(.string("Package3"))) + #expect(traitsProperty.contains(.string("Package4"))) + #expect(traitsProperty.contains(.string("BuildCondition1"))) + } + } + @Test( arguments: getBuildData(for: SupportedBuildSystemOnAllPlatforms), )