Skip to content

Commit 975523d

Browse files
authored
Improve check for unsafe flags (#2853)
We prohibit unsafe flags in package dependencies, but the check was only looking at targets which are direct dependencies of a product, not transitive ones. rdar://problem/66499615 (cherry picked from commit 6f469cf)
1 parent 5be7f49 commit 975523d

File tree

4 files changed

+22
-6
lines changed

4 files changed

+22
-6
lines changed

Sources/PackageGraph/PackageGraphLoader.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ private final class ResolvedTargetBuilder: ResolvedBuilder<ResolvedTarget> {
541541

542542
func diagnoseInvalidUseOfUnsafeFlags(_ product: ResolvedProduct) {
543543
// Diagnose if any target in this product uses an unsafe flag.
544-
for target in product.targets {
544+
for target in product.recursiveTargetDependencies() {
545545
let declarations = target.underlyingTarget.buildSettings.assignments.keys
546546
for decl in declarations {
547547
if BuildSettings.Declaration.unsafeSettings.contains(decl) {

Sources/PackageModel/ResolvedModels.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,12 @@ public final class ResolvedProduct: ObjectIdentifierProtocol, CustomStringConver
235235
// contain Swift code we don't know about as part of this build).
236236
return targets.contains { $0.underlyingTarget is SwiftTarget }
237237
}
238+
239+
/// Returns the recursive target dependencies.
240+
public func recursiveTargetDependencies() -> [ResolvedTarget] {
241+
let recursiveDependencies = targets.lazy.flatMap { $0.recursiveTargetDependencies() }
242+
return Array(Set(targets).union(recursiveDependencies))
243+
}
238244
}
239245

240246
extension ResolvedTarget.Dependency: CustomStringConvertible {

Tests/PackageGraphTests/PackageGraphTests.swift

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -880,9 +880,11 @@ class PackageGraphTests: XCTestCase {
880880
func testUnsafeFlags() throws {
881881
let fs = InMemoryFileSystem(emptyFiles:
882882
"/Foo/Sources/Foo/foo.swift",
883+
"/Foo/Sources/Foo2/foo.swift",
883884
"/Bar/Sources/Bar/bar.swift",
884885
"/Bar/Sources/Bar2/bar.swift",
885886
"/Bar/Sources/Bar3/bar.swift",
887+
"/Bar/Sources/TransitiveBar/bar.swift",
886888
"<end>"
887889
)
888890

@@ -899,14 +901,16 @@ class PackageGraphTests: XCTestCase {
899901
],
900902
targets: [
901903
TargetDescription(name: "Foo", dependencies: ["Bar"]),
904+
TargetDescription(name: "Foo2", dependencies: ["TransitiveBar"]),
902905
]),
903906
Manifest.createV4Manifest(
904907
name: "Bar",
905908
path: "/Bar",
906909
url: "/Bar",
907910
packageKind: .local,
908911
products: [
909-
ProductDescription(name: "Bar", targets: ["Bar", "Bar2", "Bar3"])
912+
ProductDescription(name: "Bar", targets: ["Bar", "Bar2", "Bar3"]),
913+
ProductDescription(name: "TransitiveBar", targets: ["TransitiveBar"]),
910914
],
911915
targets: [
912916
TargetDescription(
@@ -926,14 +930,19 @@ class PackageGraphTests: XCTestCase {
926930
TargetDescription(
927931
name: "Bar3"
928932
),
933+
TargetDescription(
934+
name: "TransitiveBar",
935+
dependencies: ["Bar2"]
936+
),
929937
]),
930938
]
931939
)
932940

933-
XCTAssertEqual(diagnostics.diagnostics.count, 2)
941+
XCTAssertEqual(diagnostics.diagnostics.count, 3)
934942
DiagnosticsEngineTester(diagnostics, ignoreNotes: true) { result in
935-
result.check(diagnostic: .contains("the target 'Bar' in product 'Bar' contains unsafe build flags"), behavior: .error)
936-
result.check(diagnostic: .contains("the target 'Bar2' in product 'Bar' contains unsafe build flags"), behavior: .error)
943+
result.checkUnordered(diagnostic: .contains("the target 'Bar2' in product 'TransitiveBar' contains unsafe build flags"), behavior: .error)
944+
result.checkUnordered(diagnostic: .contains("the target 'Bar' in product 'Bar' contains unsafe build flags"), behavior: .error)
945+
result.checkUnordered(diagnostic: .contains("the target 'Bar2' in product 'Bar' contains unsafe build flags"), behavior: .error)
937946
}
938947
}
939948

Tests/WorkspaceTests/WorkspaceTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3835,7 +3835,8 @@ final class WorkspaceTests: XCTestCase {
38353835
// We should only see errors about use of unsafe flag in the version-based dependency.
38363836
workspace.checkPackageGraph(roots: ["Foo", "Bar"]) { (graph, diagnostics) in
38373837
DiagnosticsEngineTester(diagnostics, ignoreNotes: true) { result in
3838-
result.check(diagnostic: .equal("the target 'Baz' in product 'Baz' contains unsafe build flags"), behavior: .error)
3838+
result.checkUnordered(diagnostic: .equal("the target 'Baz' in product 'Baz' contains unsafe build flags"), behavior: .error)
3839+
result.checkUnordered(diagnostic: .equal("the target 'Bar' in product 'Baz' contains unsafe build flags"), behavior: .error)
38393840
}
38403841
}
38413842
}

0 commit comments

Comments
 (0)