@@ -698,13 +698,28 @@ public class BuildPlan: SPMBuildCore.BuildPlan {
698
698
libraryBinaryPaths: Set < AbsolutePath > ,
699
699
availableTools: [ String : AbsolutePath ]
700
700
) {
701
- /* Prior to tools-version 5.9, we used to errorneously recursively traverse plugin dependencies and statically include their
701
+ /* Prior to tools-version 5.9, we used to errorneously recursively traverse executable/ plugin dependencies and statically include their
702
702
targets. For compatibility reasons, we preserve that behavior for older tools-versions. */
703
- let shouldExcludePlugins : Bool
703
+ let shouldExcludeExecutablesAndPlugins : Bool
704
704
if let toolsVersion = self . graph. package ( for: product) ? . manifest. toolsVersion {
705
- shouldExcludePlugins = toolsVersion >= . v5_9
705
+ shouldExcludeExecutablesAndPlugins = toolsVersion >= . v5_9
706
706
} else {
707
- shouldExcludePlugins = false
707
+ shouldExcludeExecutablesAndPlugins = false
708
+ }
709
+
710
+ // For test targets, we need to consider the first level of transitive dependencies since the first level is always test targets.
711
+ let topLevelDependencies : [ PackageModel . Target ]
712
+ if product. type == . test {
713
+ topLevelDependencies = product. targets. flatMap { $0. underlyingTarget. dependencies } . compactMap {
714
+ switch $0 {
715
+ case . product:
716
+ return nil
717
+ case . target( let target, _) :
718
+ return target
719
+ }
720
+ }
721
+ } else {
722
+ topLevelDependencies = [ ]
708
723
}
709
724
710
725
// Sort the product targets in topological order.
@@ -713,10 +728,19 @@ public class BuildPlan: SPMBuildCore.BuildPlan {
713
728
switch dependency {
714
729
// Include all the dependencies of a target.
715
730
case . target( let target, _) :
716
- if target. type == . macro {
731
+ let isTopLevel = topLevelDependencies. contains ( target. underlyingTarget) || product. targets. contains ( target)
732
+ let topLevelIsExecutable = isTopLevel && product. type == . executable
733
+ let topLevelIsMacro = isTopLevel && product. type == . macro
734
+ let topLevelIsPlugin = isTopLevel && product. type == . plugin
735
+ let topLevelIsTest = isTopLevel && product. type == . test
736
+
737
+ if !topLevelIsMacro && !topLevelIsTest && target. type == . macro {
738
+ return [ ]
739
+ }
740
+ if shouldExcludeExecutablesAndPlugins, !topLevelIsPlugin && !topLevelIsTest && target. type == . plugin {
717
741
return [ ]
718
742
}
719
- if shouldExcludePlugins , target. type == . plugin {
743
+ if shouldExcludeExecutablesAndPlugins , !topLevelIsExecutable && topLevelIsTest && target. type == . executable {
720
744
return [ ]
721
745
}
722
746
return target. dependencies. filter { $0. satisfies ( self . buildEnvironment) }
@@ -733,7 +757,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan {
733
757
case . library( . automatic) , . library( . static) :
734
758
return productDependencies
735
759
case . plugin:
736
- return shouldExcludePlugins ? [ ] : productDependencies
760
+ return shouldExcludeExecutablesAndPlugins ? [ ] : productDependencies
737
761
case . library( . dynamic) , . test, . executable, . snippet, . macro:
738
762
return [ ]
739
763
}
0 commit comments