From d19f9b2082fae14ea36062f7e3c95469b6b5f8fc Mon Sep 17 00:00:00 2001 From: tom doron Date: Thu, 28 Oct 2021 12:56:30 -0700 Subject: [PATCH] unwind target based dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit motivation: target based dependencies implementation of unused products never materialized. we need to revisit this topic, but until then we would like to simplify the codebase by removing the partial implementation changes: * undo changes from Finish SE‐0226 (Ignore Unused Products) #2749 * adjust call-sites and test which were added or modified after Finish SE‐0226 (Ignore Unused Products) #2749 was merged --- .../Commands/Snippets/Cards/SnippetCard.swift | 2 +- Sources/Commands/SwiftBuildTool.swift | 2 +- Sources/Commands/SwiftRunTool.swift | 8 +- Sources/Commands/SwiftTool.swift | 14 +- .../DependencyResolutionNode.swift | 2 + Sources/PackageGraph/DependencyResolver.swift | 13 +- Sources/PackageGraph/GraphLoadingNode.swift | 17 +- Sources/PackageGraph/PackageContainer.swift | 18 +- .../PackageGraph/PackageGraph+Loading.swift | 34 +- Sources/PackageGraph/PackageGraphRoot.swift | 25 +- .../PackageModel+Extensions.swift | 15 +- .../Pubgrub/Incompatibility.swift | 25 +- .../Pubgrub/PartialSolution.swift | 29 +- .../Pubgrub/PubgrubDependencyResolver.swift | 346 ++++----- Sources/PackageGraph/Pubgrub/Term.swift | 36 +- .../PackageLoading/ManifestJSONParser.swift | 24 +- Sources/PackageLoading/ManifestLoader.swift | 12 +- Sources/PackageLoading/PackageBuilder.swift | 29 +- Sources/PackageModel/Manifest.swift | 80 +- .../PackageDependencyDescription.swift | 55 +- Sources/PackageRegistry/RegistryManager.swift | 2 +- Sources/SPMTestSupport/MockDependency.swift | 37 +- .../SPMTestSupport/MockManifestLoader.swift | 4 +- .../SPMTestSupport/MockPackageContainer.swift | 10 +- ...ckageDependencyDescriptionExtensions.swift | 77 +- Sources/SPMTestSupport/misc.swift | 3 +- .../FileSystemPackageContainer.swift | 10 +- .../ResolverPrecomputationProvider.swift | 14 +- .../SourceControlPackageContainer.swift | 57 +- Sources/Workspace/Workspace.swift | 170 ++--- Tests/BuildTests/BuildPlanTests.swift | 3 +- .../DependencyResolverPerfTests.swift | 3 +- Tests/PackageGraphTests/PubgrubTests.swift | 719 ++++++++---------- .../PD_4_2_LoadingTests.swift | 6 +- .../PackageBuilderTests.swift | 1 - Tests/PackageModelTests/ManifestTests.swift | 9 +- .../ManifestSourceGenerationTests.swift | 4 +- .../PackageContainerProviderTests.swift | 13 +- Tests/WorkspaceTests/WorkspaceTests.swift | 121 +-- 39 files changed, 979 insertions(+), 1070 deletions(-) diff --git a/Sources/Commands/Snippets/Cards/SnippetCard.swift b/Sources/Commands/Snippets/Cards/SnippetCard.swift index 1f9af16931e..ab524bca617 100644 --- a/Sources/Commands/Snippets/Cards/SnippetCard.swift +++ b/Sources/Commands/Snippets/Cards/SnippetCard.swift @@ -87,7 +87,7 @@ struct SnippetCard: Card { func runExample() throws { print("Building '\(snippet.path)'\n") - let buildSystem = try swiftTool.createBuildSystem(explicitProduct: snippet.name) + let buildSystem = try swiftTool.createBuildSystem() try buildSystem.build(subset: .product(snippet.name)) let executablePath = try swiftTool.buildParameters().buildPath.appending(component: snippet.name) if let exampleTarget = try buildSystem.getPackageGraph().allTargets.first(where: { $0.name == snippet.name }) { diff --git a/Sources/Commands/SwiftBuildTool.swift b/Sources/Commands/SwiftBuildTool.swift index 15370980f5c..740bae0dddd 100644 --- a/Sources/Commands/SwiftBuildTool.swift +++ b/Sources/Commands/SwiftBuildTool.swift @@ -104,7 +104,7 @@ public struct SwiftBuildTool: SwiftCommand { guard let subset = options.buildSubset(observabilityScope: swiftTool.observabilityScope) else { throw ExitCode.failure } - let buildSystem = try swiftTool.createBuildSystem(explicitProduct: options.product) + let buildSystem = try swiftTool.createBuildSystem() do { try buildSystem.build(subset: subset) } catch _ as Diagnostics { diff --git a/Sources/Commands/SwiftRunTool.swift b/Sources/Commands/SwiftRunTool.swift index 8b1bb79009d..5c64ca73f8c 100644 --- a/Sources/Commands/SwiftRunTool.swift +++ b/Sources/Commands/SwiftRunTool.swift @@ -111,9 +111,7 @@ public struct SwiftRunTool: SwiftCommand { case .repl: // Load a custom package graph which has a special product for REPL. let graphLoader = { - try swiftTool.loadPackageGraph( - explicitProduct: self.options.executable, - createREPLProduct: true) + try swiftTool.loadPackageGraph(createREPLProduct: true) } let buildParameters = try swiftTool.buildParameters() @@ -145,7 +143,7 @@ public struct SwiftRunTool: SwiftCommand { case .debugger: do { - let buildSystem = try swiftTool.createBuildSystem(explicitProduct: options.executable) + let buildSystem = try swiftTool.createBuildSystem() let productName = try findProductName(in: buildSystem.getPackageGraph()) if options.shouldBuildTests { try buildSystem.build(subset: .allIncludingTests) @@ -189,7 +187,7 @@ public struct SwiftRunTool: SwiftCommand { swiftTool.redirectStdoutToStderr() do { - let buildSystem = try swiftTool.createBuildSystem(explicitProduct: options.executable) + let buildSystem = try swiftTool.createBuildSystem() let productName = try findProductName(in: buildSystem.getPackageGraph()) if options.shouldBuildTests { try buildSystem.build(subset: .allIncludingTests) diff --git a/Sources/Commands/SwiftTool.swift b/Sources/Commands/SwiftTool.swift index 541c148b53e..beb69c3b70e 100644 --- a/Sources/Commands/SwiftTool.swift +++ b/Sources/Commands/SwiftTool.swift @@ -694,11 +694,8 @@ public class SwiftTool { /// Fetch and load the complete package graph. /// - /// - Parameters: - /// - explicitProduct: The product specified on the command line to a “swift run” or “swift build” command. This allows executables from dependencies to be run directly without having to hook them up to any particular target. @discardableResult func loadPackageGraph( - explicitProduct: String? = nil, createMultipleTestProducts: Bool = false, createREPLProduct: Bool = false ) throws -> PackageGraph { @@ -708,7 +705,6 @@ public class SwiftTool { // Fetch and load the package graph. let graph = try workspace.loadPackageGraph( rootInput: getWorkspaceRoot(), - explicitProduct: explicitProduct, createMultipleTestProducts: createMultipleTestProducts, createREPLProduct: createREPLProduct, forceResolvedVersions: options.forceResolvedVersions, @@ -806,9 +802,9 @@ public class SwiftTool { return true } - func createBuildOperation(explicitProduct: String? = nil, cacheBuildManifest: Bool = true) throws -> BuildOperation { + func createBuildOperation(cacheBuildManifest: Bool = true) throws -> BuildOperation { // Load a custom package graph which has a special product for REPL. - let graphLoader = { try self.loadPackageGraph(explicitProduct: explicitProduct) } + let graphLoader = { try self.loadPackageGraph() } // Construct the build operation. let buildOp = try BuildOperation( @@ -827,11 +823,11 @@ public class SwiftTool { return buildOp } - func createBuildSystem(explicitProduct: String? = nil, buildParameters: BuildParameters? = nil) throws -> BuildSystem { + func createBuildSystem(buildParameters: BuildParameters? = nil) throws -> BuildSystem { let buildSystem: BuildSystem switch options.buildSystem { case .native: - let graphLoader = { try self.loadPackageGraph(explicitProduct: explicitProduct) } + let graphLoader = { try self.loadPackageGraph() } let pluginInvoker = { try self.invokePlugins(graph: $0) } buildSystem = try BuildOperation( buildParameters: buildParameters ?? self.buildParameters(), @@ -844,7 +840,7 @@ public class SwiftTool { observabilityScope: self.observabilityScope ) case .xcode: - let graphLoader = { try self.loadPackageGraph(explicitProduct: explicitProduct, createMultipleTestProducts: true) } + let graphLoader = { try self.loadPackageGraph(createMultipleTestProducts: true) } // FIXME: Implement the custom build command provider also. buildSystem = try XcodeBuildSystem( buildParameters: buildParameters ?? self.buildParameters(), diff --git a/Sources/PackageGraph/DependencyResolutionNode.swift b/Sources/PackageGraph/DependencyResolutionNode.swift index 70ec821f8f9..76a5fd7d5cf 100644 --- a/Sources/PackageGraph/DependencyResolutionNode.swift +++ b/Sources/PackageGraph/DependencyResolutionNode.swift @@ -12,6 +12,7 @@ import TSCBasic import PackageModel import struct TSCUtility.Version +/* /// A node in the dependency resolution graph. /// /// See the documentation of each case for more detailed descriptions of each kind and how they interact. @@ -133,3 +134,4 @@ extension DependencyResolutionNode: CustomStringConvertible { return "\(package.name)\(productFilter)" } } +*/ diff --git a/Sources/PackageGraph/DependencyResolver.swift b/Sources/PackageGraph/DependencyResolver.swift index 2b555361f59..a0ec6413100 100644 --- a/Sources/PackageGraph/DependencyResolver.swift +++ b/Sources/PackageGraph/DependencyResolver.swift @@ -13,7 +13,7 @@ import PackageModel import TSCBasic public protocol DependencyResolver { - typealias Binding = (package: PackageReference, binding: BoundVersion, products: ProductFilter) + typealias Binding = (package: PackageReference, binding: BoundVersion) typealias Delegate = DependencyResolverDelegate } @@ -55,15 +55,15 @@ public struct TracingDependencyResolverDelegate: DependencyResolverDelegate { } public func willResolve(term: Term) { - self.log("resolving: \(term.node.package.identity)") + self.log("resolving: \(term.package.identity)") } public func didResolve(term: Term, version: Version, duration: DispatchTimeInterval) { - self.log("resolved: \(term.node.package.identity) @ \(version)") + self.log("resolved: \(term.package.identity) @ \(version)") } public func derived(term: Term) { - self.log("derived: \(term.node.package.identity)") + self.log("derived: \(term.package.identity)") } public func conflict(conflict: Incompatibility) { @@ -88,7 +88,7 @@ public struct TracingDependencyResolverDelegate: DependencyResolverDelegate { public func solved(result: [DependencyResolver.Binding]) { self.log("solved:") - for (package, binding, _) in result { + for (package, binding) in result { self.log("\(package) \(binding)") } } @@ -134,8 +134,7 @@ public struct MultiplexResolverDelegate: DependencyResolverDelegate { underlying.forEach { $0.failedToResolve(incompatibility: incompatibility) } } - public func solved(result: [(package: PackageReference, binding: BoundVersion, products: ProductFilter)]) { + public func solved(result: [(package: PackageReference, binding: BoundVersion)]) { underlying.forEach { $0.solved(result: result) } } - } diff --git a/Sources/PackageGraph/GraphLoadingNode.swift b/Sources/PackageGraph/GraphLoadingNode.swift index 21eabee9eea..311a96af5e6 100644 --- a/Sources/PackageGraph/GraphLoadingNode.swift +++ b/Sources/PackageGraph/GraphLoadingNode.swift @@ -17,6 +17,7 @@ import TSCBasic /// This node uses the product filter that was already finalized during resolution. /// /// - SeeAlso: DependencyResolutionNode +// FIXME: tomer deprecate or replace withe some other manifest envelope public struct GraphLoadingNode: Equatable, Hashable { /// The package identity. @@ -25,28 +26,20 @@ public struct GraphLoadingNode: Equatable, Hashable { /// The package manifest. public let manifest: Manifest - /// The product filter applied to the package. - public let productFilter: ProductFilter - - public init(identity: PackageIdentity, manifest: Manifest, productFilter: ProductFilter) { + public init(identity: PackageIdentity, manifest: Manifest) { self.identity = identity self.manifest = manifest - self.productFilter = productFilter + //self.productFilter = productFilter } /// Returns the dependencies required by this node. internal func requiredDependencies() -> [PackageDependency] { - return manifest.dependenciesRequired(for: productFilter) + return self.manifest.requiredDependencies() } } extension GraphLoadingNode: CustomStringConvertible { public var description: String { - switch productFilter { - case .everything: - return self.manifest.name - case .specific(let set): - return "\(self.manifest.name)[\(set.sorted().joined(separator: ", "))]" - } + return self.identity.description } } diff --git a/Sources/PackageGraph/PackageContainer.swift b/Sources/PackageGraph/PackageContainer.swift index c59e376ef4e..2e57d608624 100644 --- a/Sources/PackageGraph/PackageContainer.swift +++ b/Sources/PackageGraph/PackageContainer.swift @@ -68,7 +68,7 @@ public protocol PackageContainer { /// - Precondition: `versions.contains(version)` /// - Throws: If the version could not be resolved; this will abort /// dependency resolution completely. - func getDependencies(at version: Version, productFilter: ProductFilter) throws -> [PackageContainerConstraint] + func getDependencies(at version: Version) throws -> [PackageContainerConstraint] /// Fetch the declared dependencies for a particular revision. /// @@ -77,12 +77,12 @@ public protocol PackageContainer { /// /// - Throws: If the revision could not be resolved; this will abort /// dependency resolution completely. - func getDependencies(at revision: String, productFilter: ProductFilter) throws -> [PackageContainerConstraint] + func getDependencies(at revision: String) throws -> [PackageContainerConstraint] /// Fetch the dependencies of an unversioned package container. /// /// NOTE: This method should not be called on a versioned container. - func getUnversionedDependencies(productFilter: ProductFilter) throws -> [PackageContainerConstraint] + func getUnversionedDependencies() throws -> [PackageContainerConstraint] /// Get the updated identifier at a bound version. /// @@ -113,27 +113,23 @@ public struct PackageContainerConstraint: Equatable, Hashable { /// The constraint requirement. public let requirement: PackageRequirement - /// The required products. - public let products: ProductFilter - /// Create a constraint requiring the given `container` satisfying the /// `requirement`. - public init(package: PackageReference, requirement: PackageRequirement, products: ProductFilter) { + public init(package: PackageReference, requirement: PackageRequirement) { self.package = package self.requirement = requirement - self.products = products } /// Create a constraint requiring the given `container` satisfying the /// `versionRequirement`. - public init(package: PackageReference, versionRequirement: VersionSetSpecifier, products: ProductFilter) { - self.init(package: package, requirement: .versionSet(versionRequirement), products: products) + public init(package: PackageReference, versionRequirement: VersionSetSpecifier) { + self.init(package: package, requirement: .versionSet(versionRequirement)) } } extension PackageContainerConstraint: CustomStringConvertible { public var description: String { - return "Constraint(\(self.package), \(requirement), \(products)" + return "Constraint(\(self.package), \(requirement)" } } diff --git a/Sources/PackageGraph/PackageGraph+Loading.swift b/Sources/PackageGraph/PackageGraph+Loading.swift index 6b887c6b546..465c83d923e 100644 --- a/Sources/PackageGraph/PackageGraph+Loading.swift +++ b/Sources/PackageGraph/PackageGraph+Loading.swift @@ -43,7 +43,7 @@ extension PackageGraph { let successors: (GraphLoadingNode) -> [GraphLoadingNode] = { node in node.requiredDependencies().compactMap{ dependency in return manifestMap[dependency.identity].map { manifest in - GraphLoadingNode(identity: dependency.identity, manifest: manifest, productFilter: dependency.productFilter) + GraphLoadingNode(identity: dependency.identity, manifest: manifest) } } } @@ -54,11 +54,11 @@ extension PackageGraph { manifestMap[$0.identity] }) let rootManifestNodes = root.packages.map { identity, package in - GraphLoadingNode(identity: identity, manifest: package.manifest, productFilter: .everything) + GraphLoadingNode(identity: identity, manifest: package.manifest) } let rootDependencyNodes = root.dependencies.lazy.compactMap { (dependency: PackageDependency) -> GraphLoadingNode? in manifestMap[dependency.identity].map { - GraphLoadingNode(identity: dependency.identity, manifest: $0, productFilter: dependency.productFilter) + GraphLoadingNode(identity: dependency.identity, manifest: $0) } } let inputManifests = rootManifestNodes + rootDependencyNodes @@ -76,13 +76,15 @@ extension PackageGraph { allNodes = try topologicalSort(inputManifests, successors: successors) } + // FIXME: tomer simplify + /* var flattenedManifests: [PackageIdentity: GraphLoadingNode] = [:] for node in allNodes { if let existing = flattenedManifests[node.identity] { let merged = GraphLoadingNode( identity: node.identity, - manifest: node.manifest, - productFilter: existing.productFilter.union(node.productFilter) + manifest: node.manifest//, + //productFilter: existing.productFilter.union(node.productFilter) ) flattenedManifests[node.identity] = merged } else { @@ -91,7 +93,8 @@ extension PackageGraph { } // sort by identity allNodes = flattenedManifests.keys.sorted().map { flattenedManifests[$0]! } // force unwrap fine since we are iterating on keys - + */ + // Create the packages. var manifestToPackage: [Manifest: Package] = [:] for node in allNodes { @@ -110,7 +113,7 @@ extension PackageGraph { let builder = PackageBuilder( identity: node.identity, manifest: manifest, - productFilter: node.productFilter, + //productFilter: node.productFilter, path: packagePath, additionalFileRules: additionalFileRules, binaryArtifacts: binaryArtifacts, @@ -209,7 +212,7 @@ private func createResolvedPackages( let allowedToOverride = rootManifestSet.contains(node.manifest) return ResolvedPackageBuilder( package, - productFilter: node.productFilter, + //productFilter: node.productFilter, isAllowedToVendUnsafeProducts: isAllowedToVendUnsafeProducts, allowedToOverride: allowedToOverride ) @@ -234,7 +237,7 @@ private func createResolvedPackages( var dependenciesByNameForTargetDependencyResolution = [String: ResolvedPackageBuilder]() // Establish the manifest-declared package dependencies. - package.manifest.dependenciesRequired(for: packageBuilder.productFilter).forEach { dependency in + package.manifest.requiredDependencies().forEach { dependency in // FIXME: change this validation logic to use identity instead of location let dependencyLocation: String switch dependency { @@ -481,6 +484,7 @@ private func createResolvedPackages( } /// A generic builder for `Resolved` models. +// FIXME: can we deprecate this? seems like adding very little value private class ResolvedBuilder { /// The constructed object, available after the first call to `construct()`. private var _constructedObject: T? @@ -530,6 +534,7 @@ private final class ResolvedProductBuilder: ResolvedBuilder { } /// Builder for resolved target. +// FIXME: can we deprecate this? seems like adding very little value private final class ResolvedTargetBuilder: ResolvedBuilder { /// Enumeration to represent target dependencies. @@ -592,14 +597,12 @@ private final class ResolvedTargetBuilder: ResolvedBuilder { } /// Builder for resolved package. +// FIXME: can we deprecate this? seems like adding very little value private final class ResolvedPackageBuilder: ResolvedBuilder { /// The package reference. let package: Package - /// The product filter applied to the package. - let productFilter: ProductFilter - /// The targets in the package. var targets: [ResolvedTargetBuilder] = [] @@ -613,9 +616,8 @@ private final class ResolvedPackageBuilder: ResolvedBuilder { let allowedToOverride: Bool - init(_ package: Package, productFilter: ProductFilter, isAllowedToVendUnsafeProducts: Bool, allowedToOverride: Bool) { + init(_ package: Package, isAllowedToVendUnsafeProducts: Bool, allowedToOverride: Bool) { self.package = package - self.productFilter = productFilter self.isAllowedToVendUnsafeProducts = isAllowedToVendUnsafeProducts self.allowedToOverride = allowedToOverride } @@ -624,8 +626,8 @@ private final class ResolvedPackageBuilder: ResolvedBuilder { return ResolvedPackage( package: package, dependencies: try dependencies.map{ try $0.construct() }, - targets: try targets.map{ try $0.construct() }, - products: try products.map{ try $0.construct() } + targets: try self.targets.map{ try $0.construct() }, + products: try self.products.map{ try $0.construct() } ) } } diff --git a/Sources/PackageGraph/PackageGraphRoot.swift b/Sources/PackageGraph/PackageGraphRoot.swift index 1bca3aa683a..056581efc60 100644 --- a/Sources/PackageGraph/PackageGraphRoot.swift +++ b/Sources/PackageGraph/PackageGraphRoot.swift @@ -52,7 +52,7 @@ public struct PackageGraphRoot { // FIXME: This API behavior wrt to non-found manifests is fragile, but required by IDEs // it may lead to incorrect assumption in downstream code which may expect an error if a manifest was not found // we should refactor this API to more clearly return errors for inputs that do not have a corresponding manifest - public init(input: PackageGraphRootInput, manifests: [AbsolutePath: Manifest], explicitProduct: String? = nil) { + public init(input: PackageGraphRootInput, manifests: [AbsolutePath: Manifest]) { self.packages = input.packages.reduce(into: .init(), { partial, inputPath in if let manifest = manifests[inputPath] { let packagePath = manifest.path.parentDirectory @@ -60,35 +60,20 @@ public struct PackageGraphRoot { partial[identity] = (.root(identity: identity, path: packagePath), manifest) } }) - - // FIXME: Deprecate special casing once the manifest supports declaring used executable products. - // Special casing explicit products like this is necessary to pass the test suite and satisfy backwards compatibility. - // However, changing the dependencies based on the command line arguments may force pins to temporarily change, - // which can become a nuissance. - // Such pin switching can currently be worked around by declaring the executable product as a dependency of a dummy target. - // But in the future it might be worth providing a way of declaring them in the manifest without a dummy target, - // at which time the current special casing can be deprecated. - var adjustedDependencies = input.dependencies - if let product = explicitProduct { - for dependency in manifests.values.lazy.map({ $0.dependenciesRequired(for: .everything) }).joined() { - adjustedDependencies.append(dependency.filtered(by: .specific([product]))) - } - } - - self.dependencies = adjustedDependencies + + self.dependencies = input.dependencies } /// Returns the constraints imposed by root manifests + dependencies. public func constraints() throws -> [PackageContainerConstraint] { let constraints = self.packageReferences.map { - PackageContainerConstraint(package: $0, requirement: .unversioned, products: .everything) + PackageContainerConstraint(package: $0, requirement: .unversioned) } let depend = try dependencies.map{ PackageContainerConstraint( package: $0.createPackageRef(), - requirement: try $0.toConstraintRequirement(), - products: $0.productFilter + requirement: try $0.toConstraintRequirement() ) } return constraints + depend diff --git a/Sources/PackageGraph/PackageModel+Extensions.swift b/Sources/PackageGraph/PackageModel+Extensions.swift index 6baf229b7b0..e1c6f99f2fb 100644 --- a/Sources/PackageGraph/PackageModel+Extensions.swift +++ b/Sources/PackageGraph/PackageModel+Extensions.swift @@ -35,16 +35,18 @@ extension PackageDependency { extension Manifest { /// Constructs constraints of the dependencies in the raw package. - public func dependencyConstraints(productFilter: ProductFilter) throws -> [PackageContainerConstraint] { - return try dependenciesRequired(for: productFilter).map({ - return PackageContainerConstraint( + public func dependencyConstraints() throws -> [PackageContainerConstraint] { + return try self.requiredDependencies().map{ + PackageContainerConstraint( package: $0.createPackageRef(), - requirement: try $0.toConstraintRequirement(), - products: $0.productFilter) - }) + requirement: try $0.toConstraintRequirement()//, + //products: $0.productFilter + ) + } } } +/* extension PackageContainerConstraint { /// Constructs a structure of dependency nodes in a package. /// - returns: An array of ``DependencyResolutionNode`` @@ -67,3 +69,4 @@ extension PackageContainerConstraint { } } } +*/ diff --git a/Sources/PackageGraph/Pubgrub/Incompatibility.swift b/Sources/PackageGraph/Pubgrub/Incompatibility.swift index c29728c026f..93c4f997801 100644 --- a/Sources/PackageGraph/Pubgrub/Incompatibility.swift +++ b/Sources/PackageGraph/Pubgrub/Incompatibility.swift @@ -9,8 +9,8 @@ */ import Basics -import TSCBasic import PackageModel +import TSCBasic /// A set of terms that are incompatible with each other and can therefore not /// all be true at the same time. In dependency resolution, these are derived @@ -24,12 +24,12 @@ public struct Incompatibility: Equatable, Hashable { self.cause = cause } - public init(_ terms: Term..., root: DependencyResolutionNode, cause: Cause = .root) throws { + public init(_ terms: Term..., root: PackageReference, cause: Cause = .root) throws { let termSet = OrderedSet(terms) try self.init(termSet, root: root, cause: cause) } - public init(_ terms: OrderedSet, root: DependencyResolutionNode, cause: Cause) throws { + public init(_ terms: OrderedSet, root: PackageReference, cause: Cause) throws { if terms.isEmpty { self.init(terms: terms, cause: cause) return @@ -39,8 +39,8 @@ public struct Incompatibility: Equatable, Hashable { // always be selected. var terms = terms if terms.count > 1, cause.isConflict, - terms.contains(where: { $0.isPositive && $0.node == root }) { - terms = OrderedSet(terms.filter { !$0.isPositive || $0.node != root }) + terms.contains(where: { $0.isPositive && $0.package == root }) { + terms = OrderedSet(terms.filter { !$0.isPositive || $0.package != root }) } let normalizedTerms = try normalize(terms: terms.contents) @@ -96,7 +96,7 @@ extension Incompatibility { /// The incompatibility represents a package's dependency on another /// package. - case dependency(node: DependencyResolutionNode) + case dependency(package: PackageReference) /// The incompatibility was derived from two others during conflict /// resolution. @@ -133,24 +133,23 @@ extension Incompatibility { /// same incompatibility, but have these combined by intersecting their version /// requirements to a^1.5.0. fileprivate func normalize(terms: [Term]) throws -> [Term] { - - let dict = try terms.reduce(into: OrderedDictionary()) { + let dict = try terms.reduce(into: OrderedDictionary()) { res, term in // Don't try to intersect if this is the first time we're seeing this package. - guard let previous = res[term.node] else { - res[term.node] = (term.requirement, term.isPositive) + guard let previous = res[term.package] else { + res[term.package] = (term.requirement, term.isPositive) return } guard let intersection = term.intersect(withRequirement: previous.req, andPolarity: previous.polarity) else { throw InternalError(""" - Attempting to create an incompatibility with terms for \(term.node) \ + Attempting to create an incompatibility with terms for \(term.package) \ intersecting versions \(previous) and \(term.requirement). These are \ mutually exclusive and can't be intersected, making this incompatibility \ irrelevant. """) } - res[term.node] = (intersection.requirement, intersection.isPositive) + res[term.package] = (intersection.requirement, intersection.isPositive) } - return dict.map { Term(node: $0, requirement: $1.req, isPositive: $1.polarity) } + return dict.map { Term(package: $0, requirement: $1.req, isPositive: $1.polarity) } } diff --git a/Sources/PackageGraph/Pubgrub/PartialSolution.swift b/Sources/PackageGraph/Pubgrub/PartialSolution.swift index 044a1694dfa..2c2ccef5da3 100644 --- a/Sources/PackageGraph/Pubgrub/PartialSolution.swift +++ b/Sources/PackageGraph/Pubgrub/PartialSolution.swift @@ -9,28 +9,29 @@ */ import Basics +import PackageModel import TSCBasic import struct TSCUtility.Version /// The partial solution is a constantly updated solution used throughout the /// dependency resolution process, tracking know assignments. public struct PartialSolution { - var root: DependencyResolutionNode? + var root: PackageReference? - /// All known assigments. + /// All known assignments. public private(set) var assignments: [Assignment] /// All known decisions. - public private(set) var decisions: [DependencyResolutionNode: Version] = [:] + public private(set) var decisions: [PackageReference: Version] = [:] /// The intersection of all positive assignments for each package, minus any /// negative assignments that refer to that package. - public private(set) var _positive: OrderedDictionary = [:] + public private(set) var _positive: OrderedDictionary = [:] /// Union of all negative assignments for a package. /// /// Only present if a package has no positive assignment. - public private(set) var _negative: [DependencyResolutionNode: Term] = [:] + public private(set) var _negative: [PackageReference: Term] = [:] /// The current decision level. public var decisionLevel: Int { @@ -46,7 +47,7 @@ public struct PartialSolution { /// A list of all packages that have been assigned, but are not yet satisfied. public var undecided: [Term] { - return _positive.values.filter { !decisions.keys.contains($0.node) } + return _positive.values.filter { !decisions.keys.contains($0.package) } } /// Create a new derivation assignment and add it to the partial solution's @@ -59,9 +60,9 @@ public struct PartialSolution { /// Create a new decision assignment and add it to the partial solution's /// list of known assignments. - public mutating func decide(_ node: DependencyResolutionNode, at version: Version) { - decisions[node] = version - let term = Term(node, .exact(version)) + public mutating func decide(_ package: PackageReference, at version: Version) { + decisions[package] = version + let term = Term(package, .exact(version)) let decision = Assignment.decision(term, decisionLevel: decisionLevel) self.assignments.append(decision) register(decision) @@ -70,10 +71,10 @@ public struct PartialSolution { /// Populates the _positive and _negative poperties with the assignment. private mutating func register(_ assignment: Assignment) { let term = assignment.term - let pkg = term.node + let pkg = term.package if let positive = _positive[pkg] { - _positive[term.node] = positive.intersect(with: term) + _positive[term.package] = positive.intersect(with: term) return } @@ -93,7 +94,7 @@ public struct PartialSolution { var assignedTerm: Term? for assignment in assignments { - guard assignment.term.node == term.node else { + guard assignment.term.package == term.package else { continue } assignedTerm = assignedTerm.flatMap{ $0.intersect(with: assignment.term) } ?? assignment.term @@ -120,7 +121,7 @@ public struct PartialSolution { for (idx, remove) in toBeRemoved.reversed() { let assignment = assignments.remove(at: idx) if assignment.isDecision { - decisions.removeValue(forKey: remove.term.node) + decisions.removeValue(forKey: remove.term.package) } } @@ -139,7 +140,7 @@ public struct PartialSolution { /// Returns the set relation of the partial solution with the given term. func relation(with term: Term) -> Term.SetRelation { - let pkg = term.node + let pkg = term.package if let positive = _positive[pkg] { return positive.relation(with: term) } else if let negative = _negative[pkg] { diff --git a/Sources/PackageGraph/Pubgrub/PubgrubDependencyResolver.swift b/Sources/PackageGraph/Pubgrub/PubgrubDependencyResolver.swift index 0378e592604..84b6f100523 100644 --- a/Sources/PackageGraph/Pubgrub/PubgrubDependencyResolver.swift +++ b/Sources/PackageGraph/Pubgrub/PubgrubDependencyResolver.swift @@ -23,24 +23,24 @@ public struct PubgrubDependencyResolver { /// the mutable state that get computed internal final class State { /// The root package reference. - let root: DependencyResolutionNode + let root: PackageReference /// The list of packages that are overridden in the graph. A local package reference will /// always override any other kind of package reference and branch-based reference will override /// version-based reference. - let overriddenPackages: [PackageReference: (version: BoundVersion, products: ProductFilter)] + let overriddenPackages: [PackageReference: BoundVersion] /// A collection of all known incompatibilities matched to the packages they /// refer to. This means an incompatibility can occur several times. - public private(set) var incompatibilities: [DependencyResolutionNode: [Incompatibility]] = [:] + public private(set) var incompatibilities: [PackageReference: [Incompatibility]] = [:] /// The current best guess for a solution satisfying all requirements. public private(set) var solution: PartialSolution private let lock = Lock() - init(root: DependencyResolutionNode, - overriddenPackages: [PackageReference: (version: BoundVersion, products: ProductFilter)] = [:], + init(root: PackageReference, + overriddenPackages: [PackageReference: BoundVersion] = [:], solution: PartialSolution = PartialSolution()) { self.root = root self.overriddenPackages = overriddenPackages @@ -50,7 +50,7 @@ public struct PubgrubDependencyResolver { func addIncompatibility(_ incompatibility: Incompatibility, at location: LogLocation) { self.lock.withLock { // log("incompat: \(incompatibility) \(location)") - for package in incompatibility.terms.map({ $0.node }) { + for package in incompatibility.terms.map({ $0.package }) { if let incompats = self.incompatibilities[package] { if !incompats.contains(incompatibility) { self.incompatibilities[package]!.append(incompatibility) @@ -63,23 +63,23 @@ public struct PubgrubDependencyResolver { } /// Find all incompatibilities containing a positive term for a given package. - func positiveIncompatibilities(for node: DependencyResolutionNode) -> [Incompatibility]? { + func positiveIncompatibilities(for package: PackageReference) -> [Incompatibility]? { self.lock.withLock { - guard let all = self.incompatibilities[node] else { + guard let all = self.incompatibilities[package] else { return nil } return all.filter { - $0.terms.first { $0.node == node }!.isPositive + $0.terms.first { $0.package == package }!.isPositive } } } - func decide(_ node: DependencyResolutionNode, at version: Version) { - let term = Term(node, .exact(version)) + func decide(_ package: PackageReference, at version: Version) { + let term = Term(package, .exact(version)) self.lock.withLock { // FIXME: Shouldn't we check this _before_ making a decision? assert(term.isValidDecision(for: self.solution)) - self.solution.decide(node, at: version) + self.solution.decide(package, at: version) } } @@ -131,10 +131,10 @@ public struct PubgrubDependencyResolver { /// Execute the resolution algorithm to find a valid assignment of versions. public func solve(constraints: [Constraint]) -> Result<[DependencyResolver.Binding], Error> { - let root = DependencyResolutionNode.root(package: .root( + let root = PackageReference.root( identity: .plain(""), path: .root - )) + ) do { // strips state @@ -165,7 +165,7 @@ public struct PubgrubDependencyResolver { /// Find a set of dependencies that fit the given constraints. If dependency /// resolution is unable to provide a result, an error is thrown. /// - Warning: It is expected that the root package reference has been set before this is called. - internal func solve(root: DependencyResolutionNode, constraints: [Constraint]) throws -> (bindings: [DependencyResolver.Binding], state: State) { + internal func solve(root: PackageReference, constraints: [Constraint]) throws -> (bindings: [DependencyResolver.Binding], state: State) { // first process inputs let inputs = try self.processInputs(root: root, with: constraints) @@ -196,10 +196,9 @@ public struct PubgrubDependencyResolver { try self.run(state: state) let decisions = state.solution.assignments.filter { $0.isDecision } - var flattenedAssignments: [PackageReference: (binding: BoundVersion, products: ProductFilter)] = [:] - for assignment in decisions { - if assignment.term.node == state.root { - continue + var finalAssignments: [DependencyResolver.Binding] = try decisions.compactMap { assignment in + guard assignment.term.package != root else { + return nil } let boundVersion: BoundVersion @@ -210,32 +209,19 @@ public struct PubgrubDependencyResolver { throw InternalError("unexpected requirement value for assignment \(assignment.term)") } - let products = assignment.term.node.productFilter - // TODO: replace with async/await when available - let container = try temp_await { provider.getContainer(for: assignment.term.node.package, completion: $0) } - let identifier = try container.underlying.getUpdatedIdentifier(at: boundVersion) + let container = try temp_await { provider.getContainer(for: assignment.term.package, completion: $0) } + let updatedPackage = try container.underlying.getUpdatedIdentifier(at: boundVersion) - if var existing = flattenedAssignments[identifier] { - assert(existing.binding == boundVersion, "Two products in one package resolved to different versions: \(existing.products)@\(existing.binding) vs \(products)@\(boundVersion)") - existing.products.formUnion(products) - flattenedAssignments[identifier] = existing - } else { - flattenedAssignments[identifier] = (binding: boundVersion, products: products) - } + return (package: updatedPackage, binding: boundVersion) } - var finalAssignments: [DependencyResolver.Binding] - = flattenedAssignments.keys.sorted(by: { $0.name < $1.name }).map { package in - let details = flattenedAssignments[package]! - return (package: package, binding: details.binding, products: details.products) - } // Add overridden packages to the result. - for (package, override) in state.overriddenPackages { + for (package, overrideVersion) in state.overriddenPackages { // TODO: replace with async/await when available let container = try temp_await { provider.getContainer(for: package, completion: $0) } - let identifier = try container.underlying.getUpdatedIdentifier(at: override.version) - finalAssignments.append((identifier, override.version, override.products)) + let updatedPackage = try container.underlying.getUpdatedIdentifier(at: overrideVersion) + finalAssignments.append((updatedPackage, overrideVersion)) } self.delegate?.solved(result: finalAssignments) @@ -244,10 +230,10 @@ public struct PubgrubDependencyResolver { } private func processInputs( - root: DependencyResolutionNode, + root: PackageReference, with constraints: [Constraint] ) throws -> ( - overriddenPackages: [PackageReference: (version: BoundVersion, products: ProductFilter)], + overriddenPackages: [PackageReference: BoundVersion], rootIncompatibilities: [Incompatibility] ) { // The list of constraints that we'll be working with. We start with the input constraints @@ -258,12 +244,12 @@ public struct PubgrubDependencyResolver { // The list of packages that are overridden in the graph. A local package reference will // always override any other kind of package reference and branch-based reference will override // version-based reference. - var overriddenPackages: [PackageReference: (version: BoundVersion, products: ProductFilter)] = [:] + var overriddenPackages: [PackageReference: BoundVersion] = [:] // The list of version-based references reachable via local and branch-based references. // These are added as top-level incompatibilities since they always need to be statisfied. // Some of these might be overridden as we discover local and branch-based references. - var versionBasedDependencies: [DependencyResolutionNode: [VersionBasedConstraint]] = [:] + var versionBasedDependencies: [PackageReference: [VersionBasedConstraint]] = [:] // Process unversioned constraints in first phase. We go through all of the unversioned packages // and collect them and their dependencies. This gives us the complete list of unversioned @@ -273,32 +259,22 @@ public struct PubgrubDependencyResolver { constraints.remove(constraint) // Mark the package as overridden. - if var existing = overriddenPackages[constraint.package] { - assert(existing.version == .unversioned, "Overridden package is not unversioned: \(constraint.package)@\(existing.version)") - existing.products.formUnion(constraint.products) - overriddenPackages[constraint.package] = existing - } else { - overriddenPackages[constraint.package] = (version: .unversioned, products: constraint.products) - } + overriddenPackages[constraint.package] = .unversioned - for node in constraint.nodes() { - // Process dependencies of this package. - // - // We collect all version-based dependencies in a separate structure so they can - // be process at the end. This allows us to override them when there is a non-version - // based (unversioned/branch-based) constraint present in the graph. - // TODO: replace with async/await when available - let container = try temp_await { provider.getContainer(for: node.package, completion: $0) } - for dependency in try container.underlying.getUnversionedDependencies(productFilter: node.productFilter) { - if let versionedBasedConstraints = VersionBasedConstraint.constraints(dependency) { - for constraint in versionedBasedConstraints { - versionBasedDependencies[node, default: []].append(constraint) - } - } else if !overriddenPackages.keys.contains(dependency.package) { - // Add the constraint if its not already present. This will ensure we don't - // end up looping infinitely due to a cycle (which are diagnosed seperately). - constraints.append(dependency) - } + // Process dependencies of this package. + // + // We collect all version-based dependencies in a separate structure so they can + // be process at the end. This allows us to override them when there is a non-version + // based (unversioned/branch-based) constraint present in the graph. + // TODO: replace with async/await when available + let container = try temp_await { provider.getContainer(for: constraint.package, completion: $0) } + for dependency in try container.underlying.getUnversionedDependencies() { + if let versionedBasedConstraint = VersionBasedConstraint(dependency) { + versionBasedDependencies[constraint.package, default: []].append(versionedBasedConstraint) + } else if !overriddenPackages.keys.contains(dependency.package) { + // Add the constraint if its not already present. This will ensure we don't + // end up looping infinitely due to a cycle (which are diagnosed seperately). + constraints.append(dependency) } } } @@ -314,7 +290,7 @@ public struct PubgrubDependencyResolver { let package = constraint.package // Check if there is an existing value for this package in the overridden packages. - switch overriddenPackages[package]?.version { + switch overriddenPackages[package] { case .excluded?, .version?: // These values are not possible. throw InternalError("Unexpected value for overriden package \(package) in \(overriddenPackages)") @@ -331,7 +307,6 @@ public struct PubgrubDependencyResolver { } case nil: break - } // Process dependencies of this package, similar to the first phase but branch-based dependencies @@ -348,37 +323,26 @@ public struct PubgrubDependencyResolver { revisionForDependencies = pinRevision.identifier // Mark the package as overridden with the pinned revision and record the branch as well. - overriddenPackages[package] = (version: .revision(revisionForDependencies, branch: revision), products: constraint.products) + overriddenPackages[package] = .revision(revisionForDependencies, branch: revision) } else { revisionForDependencies = revision // Mark the package as overridden. - overriddenPackages[package] = (version: .revision(revision), products: constraint.products) + overriddenPackages[package] = .revision(revision) } - for node in constraint.nodes() { - var unprocessedDependencies = try container.underlying.getDependencies( - at: revisionForDependencies, - productFilter: constraint.products - ) - if let sharedRevision = node.revisionLock(revision: revision) { - unprocessedDependencies.append(sharedRevision) - } - for dependency in unprocessedDependencies { - switch dependency.requirement { - case .versionSet(let req): - for node in dependency.nodes() { - let versionedBasedConstraint = VersionBasedConstraint(node: node, req: req) - versionBasedDependencies[node, default: []].append(versionedBasedConstraint) - } - case .revision: - constraints.append(dependency) - case .unversioned: - throw DependencyResolverError.revisionDependencyContainsLocalPackage( - dependency: package.name, - localPackage: dependency.package.name - ) - } + for dependency in try container.underlying.getDependencies(at: revisionForDependencies) { + switch dependency.requirement { + case .versionSet(let requirement): + let versionedBasedConstraint = VersionBasedConstraint(package: dependency.package, requirement: requirement) + versionBasedDependencies[package, default: []].append(versionedBasedConstraint) + case .revision: + constraints.append(dependency) + case .unversioned: + throw DependencyResolverError.revisionDependencyContainsLocalPackage( + dependency: package.name, + localPackage: dependency.package.name + ) } } } @@ -387,13 +351,10 @@ public struct PubgrubDependencyResolver { // list. Add them to our version-based dependency list. for dependency in constraints { switch dependency.requirement { - case .versionSet(let req): - for node in dependency.nodes() { - let versionedBasedConstraint = VersionBasedConstraint(node: node, req: req) - // FIXME: It would be better to record where this constraint came from, instead of just - // using root. - versionBasedDependencies[root, default: []].append(versionedBasedConstraint) - } + case .versionSet(let requirement): + let versionedBasedConstraint = VersionBasedConstraint(package: dependency.package, requirement: requirement) + // FIXME: It would be better to record where this constraint came from, instead of just using root. + versionBasedDependencies[root, default: []].append(versionedBasedConstraint) case .revision, .unversioned: throw InternalError("Unexpected revision/unversioned requirement in the constraints list: \(constraints)") } @@ -401,15 +362,15 @@ public struct PubgrubDependencyResolver { // Finally, compute the root incompatibilities (which will be all version-based). var rootIncompatibilities: [Incompatibility] = [] - for (node, constraints) in versionBasedDependencies { + for (package, constraints) in versionBasedDependencies { for constraint in constraints { - if overriddenPackages.keys.contains(constraint.node.package) { continue } + if overriddenPackages.keys.contains(constraint.package) { continue } let incompat = try Incompatibility( Term(root, .exact("1.0.0")), - Term(not: constraint.node, constraint.requirement), + Term(not: constraint.package, constraint.requirement), root: root, - cause: .dependency(node: node) + cause: .dependency(package: package) ) rootIncompatibilities.append(incompat) } @@ -423,13 +384,13 @@ public struct PubgrubDependencyResolver { /// After this method returns `solution` is either populated with a list of /// final version assignments or an error is thrown. private func run(state: State) throws { - var next: DependencyResolutionNode? = state.root + var next: PackageReference? = state.root while let nxt = next { - try self.propagate(state: state, node: nxt) + try self.propagate(state: state, package: nxt) // initiate prefetch of known packages that will be used to make the decision on the next step - self.provider.prefetch(containers: state.solution.undecided.map { $0.node.package }) + self.provider.prefetch(containers: state.solution.undecided.map { $0.package }) // If decision making determines that no more decisions are to be // made, it returns nil to signal that version solving is done. @@ -442,8 +403,8 @@ public struct PubgrubDependencyResolver { /// partial solution. /// If a conflict is found, the conflicting incompatibility is returned to /// resolve the conflict on. - internal func propagate(state: State, node: DependencyResolutionNode) throws { - var changed: OrderedSet = [node] + internal func propagate(state: State, package: PackageReference) throws { + var changed: OrderedSet = [package] while !changed.isEmpty { let package = changed.removeFirst() @@ -500,7 +461,7 @@ public struct PubgrubDependencyResolver { self.delegate?.derived(term: unsatisfiedTerm.inverse) state.derive(unsatisfiedTerm.inverse, cause: incompatibility) - return .almostSatisfied(node: unsatisfiedTerm.node) + return .almostSatisfied(package: unsatisfiedTerm.package) } // Based on: @@ -561,7 +522,7 @@ public struct PubgrubDependencyResolver { let priorCause = _mostRecentSatisfier.cause! var newTerms = incompatibility.terms.filter { $0 != mostRecentTerm } - newTerms += priorCause.terms.filter { $0.node != _mostRecentSatisfier.term.node } + newTerms += priorCause.terms.filter { $0.package != _mostRecentSatisfier.term.package } if let _difference = difference { newTerms.append(_difference.inverse) @@ -590,8 +551,8 @@ public struct PubgrubDependencyResolver { /// Does a given incompatibility specify that version solving has entirely /// failed, meaning this incompatibility is either empty or only for the root /// package. - private func isCompleteFailure(_ incompatibility: Incompatibility, root: DependencyResolutionNode) -> Bool { - return incompatibility.terms.isEmpty || (incompatibility.terms.count == 1 && incompatibility.terms.first?.node == root) + private func isCompleteFailure(_ incompatibility: Incompatibility, root: PackageReference) -> Bool { + return incompatibility.terms.isEmpty || (incompatibility.terms.count == 1 && incompatibility.terms.first?.package == root) } private func computeCounts(for terms: [Term], completion: @escaping (Result<[Term: Int], Error>) -> Void) { @@ -604,7 +565,7 @@ public struct PubgrubDependencyResolver { terms.forEach { term in sync.enter() - provider.getContainer(for: term.node.package) { result in + provider.getContainer(for: term.package) { result in defer { sync.leave() } results[term] = result.flatMap { container in Result(catching: { try container.versionCount(term.requirement) }) } } @@ -619,7 +580,7 @@ public struct PubgrubDependencyResolver { } } - internal func makeDecision(state: State, completion: @escaping (Result) -> Void) { + internal func makeDecision(state: State, completion: @escaping (Result) -> Void) { // If there are no more undecided terms, version solving is complete. let undecided = state.solution.undecided guard !undecided.isEmpty else { @@ -636,18 +597,18 @@ public struct PubgrubDependencyResolver { let pkgTerm = undecided.min { counts[$0]! < counts[$1]! }! self.delegate?.willResolve(term: pkgTerm) // at this point the container is cached - let container = try self.provider.getCachedContainer(for: pkgTerm.node.package) + let container = try self.provider.getCachedContainer(for: pkgTerm.package) // Get the best available version for this package. guard let version = try container.getBestAvailableVersion(for: pkgTerm) else { state.addIncompatibility(try Incompatibility(pkgTerm, root: state.root, cause: .noAvailableVersion), at: .decisionMaking) - return completion(.success(pkgTerm.node)) + return completion(.success(pkgTerm.package)) } // Add all of this version's dependencies as incompatibilities. let depIncompatibilities = try container.incompatibilites( at: version, - node: pkgTerm.node, + package: pkgTerm.package, overriddenPackages: state.overriddenPackages, root: state.root ) @@ -663,17 +624,17 @@ public struct PubgrubDependencyResolver { // are satisfied because we _know_ that the terms matching // this package will be satisfied if we make this version // as a decision. - $0.node == pkgTerm.node || state.solution.satisfies($0) + $0.package == pkgTerm.package || state.solution.satisfies($0) } } // Decide this version if there was no conflict with its dependencies. if !haveConflict { self.delegate?.didResolve(term: pkgTerm, version: version, duration: start.distance(to: .now())) - state.decide(pkgTerm.node, at: version) + state.decide(pkgTerm.package, at: version) } - completion(.success(pkgTerm.node)) + completion(.success(pkgTerm.package)) } catch { completion(.failure(error)) } @@ -682,16 +643,16 @@ public struct PubgrubDependencyResolver { } private struct DiagnosticReportBuilder { - let rootNode: DependencyResolutionNode - let incompatibilities: [DependencyResolutionNode: [Incompatibility]] + let rootPackage: PackageReference + let incompatibilities: [PackageReference: [Incompatibility]] private var lines: [(number: Int, message: String)] = [] private var derivations: [Incompatibility: Int] = [:] private var lineNumbers: [Incompatibility: Int] = [:] private let provider: ContainerProvider - init(root: DependencyResolutionNode, incompatibilities: [DependencyResolutionNode: [Incompatibility]], provider: ContainerProvider) { - self.rootNode = root + init(root: PackageReference, incompatibilities: [PackageReference: [Incompatibility]], provider: ContainerProvider) { + self.rootPackage = root self.incompatibilities = incompatibilities self.provider = provider } @@ -849,7 +810,7 @@ private struct DiagnosticReportBuilder { private func description(for incompatibility: Incompatibility) throws -> String { switch incompatibility.cause { - case .dependency(node: _): + case .dependency(package: _): assert(incompatibility.terms.count == 2) let depender = incompatibility.terms.first! let dependee = incompatibility.terms.last! @@ -863,13 +824,13 @@ private struct DiagnosticReportBuilder { assert(incompatibility.terms.count == 1) let term = incompatibility.terms.first! assert(term.isPositive) - return "no versions of \(term.node.nameForDiagnostics) match the requirement \(term.requirement)" + return "no versions of '\(term.package.identity)' match the requirement \(term.requirement)" case .root: // FIXME: This will never happen I think. assert(incompatibility.terms.count == 1) let term = incompatibility.terms.first! assert(term.isPositive) - return "\(term.node.nameForDiagnostics) is \(term.requirement)" + return "'\(term.package.identity)' is \(term.requirement)" case .conflict: break case .versionBasedDependencyContainsUnversionedDependency(let versionedDependency, let unversionedDependency): @@ -886,16 +847,16 @@ private struct DiagnosticReportBuilder { let terms = incompatibility.terms if terms.count == 1 { let term = terms.first! - let prefix = try hasEffectivelyAnyRequirement(term) ? term.node.nameForDiagnostics : description(for: term, normalizeRange: true) + let prefix = try hasEffectivelyAnyRequirement(term) ? "'\(term.package.identity)'" : description(for: term, normalizeRange: true) return "\(prefix) " + (term.isPositive ? "cannot be used" : "is required") } else if terms.count == 2 { let term1 = terms.first! let term2 = terms.last! if term1.isPositive == term2.isPositive { if term1.isPositive { - return "\(term1.node.nameForDiagnostics) is incompatible with \(term2.node.nameForDiagnostics)" + return "'\(term1.package.identity)' is incompatible with '\(term2.package.identity)'" } else { - return "either \(term1.node.nameForDiagnostics) or \(term2)" + return "either '\(term1.package.identity)' or \(term2)" } } } @@ -926,7 +887,7 @@ private struct DiagnosticReportBuilder { return false case .range(let range): // container expected to be cached at this point - guard let container = try? provider.getCachedContainer(for: term.node.package) else { + guard let container = try? provider.getCachedContainer(for: term.package) else { return false } let bounds = try container.computeBounds(for: range) @@ -958,36 +919,36 @@ private struct DiagnosticReportBuilder { // FIXME: This is duplicated and wrong. private func isFailure(_ incompatibility: Incompatibility) -> Bool { - return incompatibility.terms.count == 1 && incompatibility.terms.first?.node.package.identity == .plain("") + return incompatibility.terms.count == 1 && incompatibility.terms.first?.package.identity == .plain("") } private func description(for term: Term, normalizeRange: Bool = false) throws -> String { - let name = term.node.nameForDiagnostics + let name = term.package.identity.description switch term.requirement { - case .any: return name - case .empty: return "no version of \(name)" + case .any: return "'\(name)'" + case .empty: return "no version of '\(name)'" case .exact(let version): // For the root package, don't output the useless version 1.0.0. - if term.node == rootNode { + if term.package == self.rootPackage { return "root" } - return "\(name) \(version)" + return "'\(name)' \(version)" case .range(let range): // container expected to be cached at this point - guard normalizeRange, let container = try? provider.getCachedContainer(for: term.node.package) else { - return "\(name) \(range.description)" + guard normalizeRange, let container = try? provider.getCachedContainer(for: term.package) else { + return "'\(name)' \(range.description)" } switch try container.computeBounds(for: range) { case (true, true): - return "\(name) \(range.description)" + return "'\(name)' \(range.description)" case (false, false): - return name + return "'\(name)'" case (true, false): - return "\(name) >= \(range.lowerBound)" + return "'\(name)' >= \(range.lowerBound)" case (false, true): - return "\(name) < \(range.upperBound)" + return "'\(name)' < \(range.upperBound)" } case .ranges(let ranges): let ranges = "{" + ranges.map { @@ -996,7 +957,7 @@ private struct DiagnosticReportBuilder { } return $0.lowerBound.description + "..<" + $0.upperBound.description }.joined(separator: ", ") + "}" - return "\(name) \(ranges)" + return "'\(name)' \(ranges)" } } @@ -1157,22 +1118,19 @@ private final class PubGrubPackageContainer { /// Returns the incompatibilities of a package at the given version. func incompatibilites( at version: Version, - node: DependencyResolutionNode, - overriddenPackages: [PackageReference: (version: BoundVersion, products: ProductFilter)], - root: DependencyResolutionNode + package: PackageReference, + overriddenPackages: [PackageReference: BoundVersion], + root: PackageReference ) throws -> [Incompatibility] { // FIXME: It would be nice to compute bounds for this as well. if !self.underlying.isToolsVersionCompatible(at: version) { let requirement = try self.computeIncompatibleToolsVersionBounds(fromVersion: version) let toolsVersion = try self.underlying.toolsVersion(for: version) - return [try Incompatibility(Term(node, requirement), root: root, cause: .incompatibleToolsVersion(toolsVersion))] + return [try Incompatibility(Term(package, requirement), root: root, cause: .incompatibleToolsVersion(toolsVersion))] } - var unprocessedDependencies = try self.underlying.getDependencies(at: version, productFilter: node.productFilter) - if let sharedVersion = node.versionLock(version: version) { - unprocessedDependencies.append(sharedVersion) - } var constraints: [PackageContainerConstraint] = [] + let unprocessedDependencies = try self.underlying.getDependencies(at: version) for dep in unprocessedDependencies { // Version-based packages are not allowed to contain unversioned dependencies. guard case .versionSet = dep.requirement else { @@ -1180,7 +1138,7 @@ private final class PubGrubPackageContainer { versionedDependency: package, unversionedDependency: dep.package ) - return [try Incompatibility(Term(node, .exact(version)), root: root, cause: cause)] + return [try Incompatibility(Term(package, .exact(version)), root: root, cause: cause)] } // Skip if this package is overriden. @@ -1207,23 +1165,22 @@ private final class PubGrubPackageContainer { // Since the pinned version is most likely to succeed, we don't compute bounds for its // incompatibilities. - return try Array(constraints.map { (constraint: PackageContainerConstraint) -> [Incompatibility] in - guard case .versionSet(let vs) = constraint.requirement else { + return try constraints.map { constraint in + guard case .versionSet(let versionSet) = constraint.requirement else { throw InternalError("Unexpected unversioned requirement: \(constraint)") } - return try constraint.nodes().map { dependencyNode in - var terms: OrderedSet = [] - terms.append(Term(node, .exact(version))) - terms.append(Term(not: dependencyNode, vs)) - return try Incompatibility(terms, root: root, cause: .dependency(node: node)) - } - }.joined()) + var terms: OrderedSet = [] + terms.append(Term(self.underlying.package, .exact(version))) + terms.append(Term(not: constraint.package, versionSet)) + return try Incompatibility(terms, root: root, cause: .dependency(package: self.underlying.package)) + } } - let (lowerBounds, upperBounds) = try self.computeBounds(for: node, - constraints: constraints, - startingWith: version, - products: node.productFilter) + let (lowerBounds, upperBounds) = try self.computeBounds( + for: package, + constraints: constraints, + startingWith: version + ) return try constraints.map { constraint in var terms: OrderedSet = [] @@ -1232,20 +1189,19 @@ private final class PubGrubPackageContainer { assert(lowerBound < upperBound) // We only have version-based requirements at this point. - guard case .versionSet(let vs) = constraint.requirement else { + guard case .versionSet(let versionSet) = constraint.requirement else { throw InternalError("Unexpected unversioned requirement: \(constraint)") } - for constraintNode in constraint.nodes() { - let requirement: VersionSetSpecifier = .range(lowerBound ..< upperBound) - terms.append(Term(node, requirement)) - terms.append(Term(not: constraintNode, vs)) + let requirement: VersionSetSpecifier = .range(lowerBound ..< upperBound) + terms.append(Term(self.underlying.package, requirement)) + terms.append(Term(not: constraint.package, versionSet)) - // Make a record for this dependency so we don't have to recompute the bounds when the selected version falls within the bounds. - self.emittedIncompatibilities[constraint.package] = requirement.union(emittedIncompatibilities[constraint.package] ?? .empty) - } + // Make a record for this dependency so we don't have to recompute the bounds when the selected version falls within the bounds. + self.emittedIncompatibilities[constraint.package] = requirement.union(emittedIncompatibilities[constraint.package] ?? .empty) - return try Incompatibility(terms, root: root, cause: .dependency(node: node)) + + return try Incompatibility(terms, root: root, cause: .dependency(package: self.underlying.package)) } } @@ -1256,10 +1212,9 @@ private final class PubGrubPackageContainer { /// above or below the given version. As with regular version ranges, the lower bound is /// inclusive and the upper bound is exclusive. private func computeBounds( - for node: DependencyResolutionNode, + for package: PackageReference, constraints: [PackageContainerConstraint], - startingWith firstVersion: Version, - products: ProductFilter + startingWith firstVersion: Version ) throws -> (lowerBounds: [PackageReference: Version], upperBounds: [PackageReference: Version]) { let preloadCount = 3 @@ -1273,7 +1228,7 @@ private final class PubGrubPackageContainer { for version in versions { DispatchQueue.sharedConcurrent.async(group: sync) { if self.underlying.isToolsVersionCompatible(at: version) { - _ = try? self.underlying.getDependencies(at: version, productFilter: products) + _ = try? self.underlying.getDependencies(at: version) } } } @@ -1305,7 +1260,7 @@ private final class PubGrubPackageContainer { result[constraint.package] = bound } else { // Get the dependencies at this version. - if let currentDependencies = try? self.underlying.getDependencies(at: version, productFilter: products) { + if let currentDependencies = try? self.underlying.getDependencies(at: version/*, productFilter: products*/) { // Record this version as the bound for our list of dependencies, if appropriate. if currentDependencies.first(where: { $0.package == constraint.package }) != constraint { result[constraint.package] = bound @@ -1328,7 +1283,7 @@ private final class PubGrubPackageContainer { let versions: [Version] = try self.underlying.versionsAscending() guard let idx = versions.firstIndex(of: firstVersion) else { - throw InternalError("from version \(firstVersion) not found in \(node.package.name)") + throw InternalError("from version \(firstVersion) not found in \(package.identity)") } let sync = DispatchGroup() @@ -1346,7 +1301,7 @@ private final class PubGrubPackageContainer { // timeout is a function of # of versions since we need to make several git operations per tag/version let timeout = DispatchTimeInterval.seconds(60 + versions.count) guard case .success = sync.wait(timeout: .now() + timeout) else { - throw StringError("timeout computing '\(node.package.name)' bounds") + throw StringError("timeout computing '\(package.identity)' bounds") } return (lowerBounds, upperBounds) @@ -1452,7 +1407,7 @@ internal enum LogLocation: String { extension PubgrubDependencyResolver { public enum PubgrubError: Swift.Error, CustomStringConvertible { - case _unresolvable(Incompatibility, [DependencyResolutionNode: [Incompatibility]]) + case _unresolvable(Incompatibility, [PackageReference: [Incompatibility]]) case unresolvable(String) public var description: String { @@ -1473,7 +1428,7 @@ extension PubgrubDependencyResolver { } } - var incompatibilities: [DependencyResolutionNode: [Incompatibility]]? { + var incompatibilities: [PackageReference: [Incompatibility]]? { switch self { case ._unresolvable(_, let incompatibilities): return incompatibilities @@ -1486,18 +1441,18 @@ extension PubgrubDependencyResolver { extension PubgrubDependencyResolver { private struct VersionBasedConstraint { - let node: DependencyResolutionNode + let package: PackageReference let requirement: VersionSetSpecifier - init(node: DependencyResolutionNode, req: VersionSetSpecifier) { - self.node = node - self.requirement = req + init(package: PackageReference, requirement: VersionSetSpecifier) { + self.package = package + self.requirement = requirement } - internal static func constraints(_ constraint: Constraint) -> [VersionBasedConstraint]? { + internal init?(_ constraint: Constraint) { switch constraint.requirement { - case .versionSet(let req): - return constraint.nodes().map { VersionBasedConstraint(node: $0, req: req) } + case .versionSet(let requirement): + self.init(package: constraint.package, requirement: requirement) case .revision: return nil case .unversioned: @@ -1509,7 +1464,7 @@ extension PubgrubDependencyResolver { private enum PropagationResult { case conflict - case almostSatisfied(node: DependencyResolutionNode) + case almostSatisfied(package: PackageReference) case none } @@ -1524,8 +1479,9 @@ private extension PackageRequirement { } } +/* private extension DependencyResolutionNode { var nameForDiagnostics: String { return "'\(package.name)'" } -} +}*/ diff --git a/Sources/PackageGraph/Pubgrub/Term.swift b/Sources/PackageGraph/Pubgrub/Term.swift index 9d9b4ecc910..a91ead0fb81 100644 --- a/Sources/PackageGraph/Pubgrub/Term.swift +++ b/Sources/PackageGraph/Pubgrub/Term.swift @@ -8,47 +8,49 @@ See http://swift.org/CONTRIBUTORS.txt for Swift project authors */ +import PackageModel + /// A term represents a statement about a package that may be true or false. public struct Term: Equatable, Hashable { - public let node: DependencyResolutionNode + public let package: PackageReference public let requirement: VersionSetSpecifier public let isPositive: Bool - public init(node: DependencyResolutionNode, requirement: VersionSetSpecifier, isPositive: Bool) { - self.node = node + public init(package: PackageReference, requirement: VersionSetSpecifier, isPositive: Bool) { + self.package = package self.requirement = requirement self.isPositive = isPositive } - public init(_ node: DependencyResolutionNode, _ requirement: VersionSetSpecifier) { - self.init(node: node, requirement: requirement, isPositive: true) + public init(_ package: PackageReference, _ requirement: VersionSetSpecifier) { + self.init(package: package, requirement: requirement, isPositive: true) } /// Create a new negative term. - public init(not node: DependencyResolutionNode, _ requirement: VersionSetSpecifier) { - self.init(node: node, requirement: requirement, isPositive: false) + public init(not package: PackageReference, _ requirement: VersionSetSpecifier) { + self.init(package: package, requirement: requirement, isPositive: false) } /// The same term with an inversed `isPositive` value. public var inverse: Term { return Term( - node: node, - requirement: requirement, - isPositive: !isPositive) + package: self.package, + requirement: self.requirement, + isPositive: !self.isPositive) } /// Check if this term satisfies another term, e.g. if `self` is true, /// `other` must also be true. public func satisfies(_ other: Term) -> Bool { // TODO: This probably makes more sense as isSatisfied(by:) instead. - guard self.node == other.node else { return false } + guard self.package == other.package else { return false } return self.relation(with: other) == .subset } /// Create an intersection with another term. public func intersect(with other: Term) -> Term? { - guard self.node == other.node else { return nil } - return intersect(withRequirement: other.requirement, andPolarity: other.isPositive) + guard self.package == other.package else { return nil } + return self.intersect(withRequirement: other.requirement, andPolarity: other.isPositive) } /// Create an intersection with a requirement and polarity returning a new @@ -84,7 +86,7 @@ public struct Term: Equatable, Hashable { return nil } - return Term(node: node, requirement: versionIntersection, isPositive: isPositive) + return Term(package: self.package, requirement: versionIntersection, isPositive: isPositive) } public func difference(with other: Term) -> Term? { @@ -97,7 +99,7 @@ public struct Term: Equatable, Hashable { /// - There has to be no decision for it. /// - The package version has to match all assignments. public func isValidDecision(for solution: PartialSolution) -> Bool { - for assignment in solution.assignments where assignment.term.node == node { + for assignment in solution.assignments where assignment.term.package == package { assert(!assignment.isDecision, "Expected assignment to be a derivation.") guard satisfies(assignment.term) else { return false } } @@ -106,7 +108,7 @@ public struct Term: Equatable, Hashable { // From: https://github.com/dart-lang/pub/blob/master/lib/src/solver/term.dart public func relation(with other: Term) -> SetRelation { - if self.node != other.node { + if self.package != other.package { assertionFailure("attempting to compute relation between different packages \(self) \(other)") return .error } @@ -165,7 +167,7 @@ public struct Term: Equatable, Hashable { extension Term: CustomStringConvertible { public var description: String { - let pkg = "\(node)" + let pkg = "\(package.identity)" let req = requirement.description if !isPositive { diff --git a/Sources/PackageLoading/ManifestJSONParser.swift b/Sources/PackageLoading/ManifestJSONParser.swift index 5721e188c33..9d211bc1584 100644 --- a/Sources/PackageLoading/ManifestJSONParser.swift +++ b/Sources/PackageLoading/ManifestJSONParser.swift @@ -119,7 +119,7 @@ enum ManifestJSONParser { let identity: String = try kindJSON.get("identity") let requirementJSON: JSON = try kindJSON.get("requirement") let requirement = try PackageDependency.Registry.Requirement(v4: requirementJSON) - return .registry(identity: .plain(identity), requirement: requirement, productFilter: .everything) + return .registry(identity: .plain(identity), requirement: requirement) } else { throw InternalError("Unknown dependency type \(kindJSON)") } @@ -138,8 +138,8 @@ enum ManifestJSONParser { at: url, name: name, identityResolver: identityResolver, - fileSystem: fileSystem) - + fileSystem: fileSystem + ) default: let requirement = try PackageDependency.SourceControl.Requirement(v4: requirementJSON) return try Self.makeSourceControlDependency( @@ -148,7 +148,8 @@ enum ManifestJSONParser { name: name, requirement: requirement, identityResolver: identityResolver, - fileSystem: fileSystem) + fileSystem: fileSystem + ) } } } @@ -168,10 +169,11 @@ enum ManifestJSONParser { throw ManifestParseError.invalidManifestFormat("'\(path)' is not a valid path for path-based dependencies; use relative or absolute path instead.", diagnosticFile: nil) } let identity = try identityResolver.resolveIdentity(for: path) - return .fileSystem(identity: identity, - nameForTargetDependencyResolutionOnly: name, - path: path, - productFilter: .everything) + return .fileSystem( + identity: identity, + nameForTargetDependencyResolutionOnly: name, + path: path + ) } private static func makeSourceControlDependency( @@ -203,8 +205,7 @@ enum ManifestJSONParser { identity: identity, nameForTargetDependencyResolutionOnly: name, path: localPath, - requirement: requirement, - productFilter: .everything + requirement: requirement ) } else if let url = URL(string: location){ // in the future this will check with the registries for the identity of the URL @@ -213,8 +214,7 @@ enum ManifestJSONParser { identity: identity, nameForTargetDependencyResolutionOnly: name, url: url, - requirement: requirement, - productFilter: .everything + requirement: requirement ) } else { throw StringError("invalid location: \(location)") diff --git a/Sources/PackageLoading/ManifestLoader.swift b/Sources/PackageLoading/ManifestLoader.swift index 99e0749085d..c87faa6d975 100644 --- a/Sources/PackageLoading/ManifestLoader.swift +++ b/Sources/PackageLoading/ManifestLoader.swift @@ -47,7 +47,7 @@ public protocol ManifestLoaderProtocol { packageKind: PackageReference.Kind, packageLocation: String, version: Version?, - revision: String?, + //revision: String?, toolsVersion: ToolsVersion, identityResolver: IdentityResolver, fileSystem: FileSystem, @@ -169,7 +169,7 @@ public final class ManifestLoader: ManifestLoaderProtocol { packageKind: .root(packageLocation), packageLocation: packageLocation.pathString, version: nil, - revision: nil, + //revision: nil, toolsVersion: toolsVersion, identityResolver: identityResolver, fileSystem: fileSystem, @@ -188,7 +188,7 @@ public final class ManifestLoader: ManifestLoaderProtocol { packageKind: PackageReference.Kind, packageLocation: String, version: Version?, - revision: String?, + //revision: String?, toolsVersion: ToolsVersion, identityResolver: IdentityResolver, fileSystem: FileSystem, @@ -203,7 +203,7 @@ public final class ManifestLoader: ManifestLoaderProtocol { packageKind: packageKind, packageLocation: packageLocation, version: version, - revision: revision, + //revision: revision, toolsVersion: toolsVersion, identityResolver: identityResolver, fileSystem: fileSystem, @@ -221,7 +221,7 @@ public final class ManifestLoader: ManifestLoaderProtocol { packageKind: PackageReference.Kind, packageLocation: String, version: Version?, - revision: String?, + //revision: String?, toolsVersion: ToolsVersion, identityResolver: IdentityResolver, fileSystem: FileSystem, @@ -278,7 +278,7 @@ public final class ManifestLoader: ManifestLoaderProtocol { defaultLocalization: parsedManifest.defaultLocalization, platforms: parsedManifest.platforms, version: version, - revision: revision, + //revision: revision, toolsVersion: toolsVersion, pkgConfig: parsedManifest.pkgConfig, providers: parsedManifest.providers, diff --git a/Sources/PackageLoading/PackageBuilder.swift b/Sources/PackageLoading/PackageBuilder.swift index d96994bdb13..cf806c47f64 100644 --- a/Sources/PackageLoading/PackageBuilder.swift +++ b/Sources/PackageLoading/PackageBuilder.swift @@ -215,9 +215,6 @@ public final class PackageBuilder { /// The manifest for the package being constructed. private let manifest: Manifest - /// The product filter to apply to the package. - private let productFilter: ProductFilter - /// The path of the package. private let packagePath: AbsolutePath @@ -260,7 +257,7 @@ public final class PackageBuilder { public init( identity: PackageIdentity, manifest: Manifest, - productFilter: ProductFilter, + //productFilter: ProductFilter, path: AbsolutePath, additionalFileRules: [FileRuleDescription] = [], binaryArtifacts: [BinaryArtifact], @@ -273,7 +270,6 @@ public final class PackageBuilder { ) { self.identity = identity self.manifest = manifest - self.productFilter = productFilter self.packagePath = path self.additionalFileRules = additionalFileRules self.binaryArtifacts = binaryArtifacts @@ -320,7 +316,7 @@ public final class PackageBuilder { let builder = PackageBuilder( identity: identity, manifest: manifest, - productFilter: .everything, + //productFilter: .everything, path: path, binaryArtifacts: [], // this will fail for packages with binary artifacts, but this API is deprecated and the replacement API was fixed xcTestMinimumDeploymentTargets: xcTestMinimumDeploymentTargets, @@ -585,7 +581,8 @@ public final class PackageBuilder { // Create potential targets. let potentialTargets: [PotentialModule] - potentialTargets = try manifest.targetsRequired(for: productFilter).map({ target in + //potentialTargets = try manifest.targetsRequired(for: productFilter).map({ target in + potentialTargets = try manifest.requiredTargets().map({ target in let path = try findPath(for: target) return PotentialModule(name: target.name, path: path, type: target.type) }) @@ -611,7 +608,7 @@ public final class PackageBuilder { // Create targets from the provided potential targets. private func createModules(_ potentialModules: [PotentialModule]) throws -> [Target] { // Find if manifest references a target which isn't present on disk. - let allVisibleModuleNames = manifest.visibleModuleNames(for: productFilter) + let allVisibleModuleNames = manifest.visibleModuleNames //manifest.visibleModuleNames(for: productFilter) let potentialModulesName = Set(potentialModules.map({ $0.name })) let missingModuleNames = allVisibleModuleNames.subtracting(potentialModulesName) if let missingModuleName = missingModuleNames.first { @@ -1218,14 +1215,14 @@ public final class PackageBuilder { // First add explicit products. - let filteredProducts: [ProductDescription] + /*let filteredProducts: [ProductDescription] switch productFilter { case .everything: filteredProducts = self.manifest.products case .specific(let set): filteredProducts = self.manifest.products.filter { set.contains($0.name) } - } - for product in filteredProducts { + }*/ + for product in manifest.products { let targets = try modulesFrom(targetNames: product.targets, product: product.name) // Perform special validations if this product is exporting // a system library target. @@ -1379,17 +1376,17 @@ private struct PotentialModule: Hashable { private extension Manifest { /// Returns the names of all the visible targets in the manifest. - func visibleModuleNames(for productFilter: ProductFilter) -> Set { - let names = targetsRequired(for: productFilter).flatMap({ target in - [target.name] + target.dependencies.compactMap({ + var visibleModuleNames: Set { + let names = self.requiredTargets().flatMap{ target in + [target.name] + target.dependencies.compactMap{ switch $0 { case .target(let name, _): return name case .byName, .product: return nil } - }) - }) + } + } return Set(names) } } diff --git a/Sources/PackageModel/Manifest.swift b/Sources/PackageModel/Manifest.swift index b479b165720..f27b443480c 100644 --- a/Sources/PackageModel/Manifest.swift +++ b/Sources/PackageModel/Manifest.swift @@ -58,7 +58,7 @@ public final class Manifest { public let version: Version? /// The revision this package was loaded from, if known. - public let revision: String? + //public let revision: String? /// The tools version declared in the manifest. public let toolsVersion: ToolsVersion @@ -97,10 +97,10 @@ public final class Manifest { public let providers: [SystemPackageProviderDescription]? /// Targets required for building particular product filters. - private var _requiredTargets = ThreadSafeKeyValueStore() + //private var _requiredTargets = ThreadSafeKeyValueStore() /// Dependencies required for building particular product filters. - private var _requiredDependencies = ThreadSafeKeyValueStore() + //private var _requiredDependencies = ThreadSafeKeyValueStore() public init( name: String, @@ -110,7 +110,7 @@ public final class Manifest { defaultLocalization: String? = nil, platforms: [PlatformDescription], version: TSCUtility.Version? = nil, - revision: String? = nil, + //revision: String? = nil, toolsVersion: ToolsVersion, pkgConfig: String? = nil, providers: [SystemPackageProviderDescription]? = nil, @@ -128,7 +128,7 @@ public final class Manifest { self.defaultLocalization = defaultLocalization self.platforms = platforms self.version = version - self.revision = revision + //self.revision = revision self.toolsVersion = toolsVersion self.pkgConfig = pkgConfig self.providers = providers @@ -140,7 +140,73 @@ public final class Manifest { self.targets = targets self.targetMap = Dictionary(targets.lazy.map({ ($0.name, $0) }), uniquingKeysWith: { $1 }) } +} + +extension Manifest { + + /// Returns the targets required for building the provided products. + public func requiredTargets(for productsFilter: [ProductDescription]? = .none) -> [TargetDescription] { + if case .root = self.packageKind { + return self.targets + } + + let products = productsFilter ?? self.products + + let targetsByName = Dictionary(targets.map({ ($0.name, $0) }), uniquingKeysWith: { $1 }) + let productTargetNames = products.flatMap({ $0.targets }) + + let dependentTargetNames = transitiveClosure(productTargetNames, successors: { targetName in + + if let target = targetsByName[targetName] { + let dependencies: [String] = target.dependencies.compactMap { dependency in + switch dependency { + case .target(let name, _), .byName(let name, _): + return targetsByName.keys.contains(name) ? name : nil + default: + return nil + } + } + + let plugins: [String] = target.pluginUsages?.compactMap { pluginUsage in + switch pluginUsage { + case .plugin(name: let name, package: nil): + return targetsByName.keys.contains(name) ? name : nil + default: + return nil + } + } ?? [] + + return dependencies + plugins + } + + return [] + }) + let requiredTargetNames = Set(productTargetNames).union(dependentTargetNames) + let requiredTargets = requiredTargetNames.compactMap{ targetsByName[$0] } + return requiredTargets + } + + public func requiredDependencies(for productsFilter: [ProductDescription]? = .none) -> [PackageDependency] { + if self.packageKind.isRoot || self.toolsVersion < .v5_2 { + return self.dependencies + } + + var requiredDependencies: Set = [] + + for target in self.requiredTargets(for: productsFilter) { + for targetDependency in target.dependencies { + if let dependency = self.packageDependency(referencedBy: targetDependency) { + requiredDependencies.insert(dependency.identity) + } + } + } + + return self.dependencies.filter { requiredDependencies.contains($0.identity) } + + } + + /* /// Returns the targets required for a particular product filter. public func targetsRequired(for productFilter: ProductFilter) -> [TargetDescription] { #if ENABLE_TARGET_BASED_DEPENDENCY_RESOLUTION @@ -274,7 +340,7 @@ public final class Manifest { return nil } } - } + }*/ /// Finds the package dependency referenced by the specified target dependency. /// - Returns: Returns `nil` if the dependency is a target dependency, if it is a product dependency but has no @@ -298,6 +364,7 @@ public final class Manifest { }) } + /* /// Registers a required product with a particular dependency if possible, or registers it as unknown. /// /// - Parameters: @@ -382,6 +449,7 @@ public final class Manifest { return false } } + */ } extension Manifest: Hashable { diff --git a/Sources/PackageModel/Manifest/PackageDependencyDescription.swift b/Sources/PackageModel/Manifest/PackageDependencyDescription.swift index 46f46ea3a99..4bdf65179d2 100644 --- a/Sources/PackageModel/Manifest/PackageDependencyDescription.swift +++ b/Sources/PackageModel/Manifest/PackageDependencyDescription.swift @@ -21,7 +21,6 @@ public enum PackageDependency: Equatable { public let identity: PackageIdentity public let nameForTargetDependencyResolutionOnly: String? public let path: AbsolutePath - public let productFilter: ProductFilter } public struct SourceControl: Equatable, Encodable { @@ -29,7 +28,6 @@ public enum PackageDependency: Equatable { public let nameForTargetDependencyResolutionOnly: String? public let location: Location public let requirement: Requirement - public let productFilter: ProductFilter public enum Requirement: Equatable, Hashable { case exact(Version) @@ -47,7 +45,6 @@ public enum PackageDependency: Equatable { public struct Registry: Equatable, Encodable { public let identity: PackageIdentity public let requirement: Requirement - public let productFilter: ProductFilter /// The dependency requirement. public enum Requirement: Equatable, Hashable { @@ -98,54 +95,38 @@ public enum PackageDependency: Equatable { } } - public var productFilter: ProductFilter { - switch self { - case .fileSystem(let settings): - return settings.productFilter - case .sourceControl(let settings): - return settings.productFilter - case .registry(let settings): - return settings.productFilter - } - } - public func filtered(by productFilter: ProductFilter) -> Self { switch self { case .fileSystem(let settings): return .fileSystem( identity: settings.identity, nameForTargetDependencyResolutionOnly: settings.nameForTargetDependencyResolutionOnly, - path: settings.path, - productFilter: productFilter + path: settings.path ) case .sourceControl(let settings): return .sourceControl( identity: settings.identity, nameForTargetDependencyResolutionOnly: settings.nameForTargetDependencyResolutionOnly, location: settings.location, - requirement: settings.requirement, - productFilter: productFilter + requirement: settings.requirement ) case .registry(let settings): return .registry( identity: settings.identity, - requirement: settings.requirement, - productFilter: productFilter + requirement: settings.requirement ) } } public static func fileSystem(identity: PackageIdentity, nameForTargetDependencyResolutionOnly: String?, - path: AbsolutePath, - productFilter: ProductFilter + path: AbsolutePath ) -> Self { .fileSystem( .init( identity: identity, nameForTargetDependencyResolutionOnly: nameForTargetDependencyResolutionOnly, - path: path, - productFilter: productFilter + path: path ) ) } @@ -153,59 +134,49 @@ public enum PackageDependency: Equatable { public static func localSourceControl(identity: PackageIdentity, nameForTargetDependencyResolutionOnly: String?, path: AbsolutePath, - requirement: SourceControl.Requirement, - productFilter: ProductFilter + requirement: SourceControl.Requirement ) -> Self { .sourceControl( identity: identity, nameForTargetDependencyResolutionOnly: nameForTargetDependencyResolutionOnly, location: .local(path), - requirement: requirement, - productFilter: productFilter + requirement: requirement ) } public static func remoteSourceControl(identity: PackageIdentity, nameForTargetDependencyResolutionOnly: String?, url: Foundation.URL, - requirement: SourceControl.Requirement, - productFilter: ProductFilter + requirement: SourceControl.Requirement ) -> Self { .sourceControl( identity: identity, nameForTargetDependencyResolutionOnly: nameForTargetDependencyResolutionOnly, location: .remote(url), - requirement: requirement, - productFilter: productFilter + requirement: requirement ) } public static func sourceControl(identity: PackageIdentity, nameForTargetDependencyResolutionOnly: String?, location: SourceControl.Location, - requirement: SourceControl.Requirement, - productFilter: ProductFilter + requirement: SourceControl.Requirement ) -> Self { .sourceControl( .init( identity: identity, nameForTargetDependencyResolutionOnly: nameForTargetDependencyResolutionOnly, location: location, - requirement: requirement, - productFilter: productFilter + requirement: requirement ) ) } - public static func registry(identity: PackageIdentity, - requirement: Registry.Requirement, - productFilter: ProductFilter - ) -> Self { + public static func registry(identity: PackageIdentity, requirement: Registry.Requirement) -> Self { .registry( .init( identity: identity, - requirement: requirement, - productFilter: productFilter + requirement: requirement ) ) } diff --git a/Sources/PackageRegistry/RegistryManager.swift b/Sources/PackageRegistry/RegistryManager.swift index ded77f82a3b..b9c82621976 100644 --- a/Sources/PackageRegistry/RegistryManager.swift +++ b/Sources/PackageRegistry/RegistryManager.swift @@ -169,7 +169,7 @@ public final class RegistryManager { packageKind: .registry(package.identity), packageLocation: package.locationString, version: version, - revision: nil, + //revision: nil, toolsVersion: .currentToolsVersion, identityResolver: self.identityResolver, fileSystem: fileSystem, diff --git a/Sources/SPMTestSupport/MockDependency.swift b/Sources/SPMTestSupport/MockDependency.swift index 00543f6329f..6473cf8bd0b 100644 --- a/Sources/SPMTestSupport/MockDependency.swift +++ b/Sources/SPMTestSupport/MockDependency.swift @@ -18,12 +18,10 @@ public struct MockDependency { public let deprecatedName: String? public let location: Location - public let products: ProductFilter - init(deprecatedName: String? = nil, location: Location, products: ProductFilter = .everything) { + init(deprecatedName: String? = nil, location: Location) { self.deprecatedName = deprecatedName self.location = location - self.products = products } // TODO: refactor this when adding registry support @@ -36,8 +34,7 @@ public struct MockDependency { return .fileSystem( identity: identity, deprecatedName: self.deprecatedName, - path: remappedPath, - productFilter: self.products + path: remappedPath ) case .localSourceControl(let path, let requirement): let absolutePath = baseURL.appending(path) @@ -47,8 +44,7 @@ public struct MockDependency { identity: identity, deprecatedName: self.deprecatedName, path: remappedPath, - requirement: requirement, - productFilter: self.products + requirement: requirement ) case .remoteSourceControl(let url, let requirement): let remappedURLString = identityResolver.mappedLocation(for: url.absoluteString) @@ -60,34 +56,33 @@ public struct MockDependency { identity: identity, deprecatedName: self.deprecatedName, url: remappedURL, - requirement: requirement, - productFilter: self.products + requirement: requirement ) } } - public static func fileSystem(path: String, products: ProductFilter = .everything) -> MockDependency { - MockDependency(location: .fileSystem(path: RelativePath(path)), products: products) + public static func fileSystem(path: String) -> MockDependency { + MockDependency(location: .fileSystem(path: RelativePath(path))) } - public static func sourceControl(path: String, requirement: Requirement, products: ProductFilter = .everything) -> MockDependency { - .sourceControl(path: RelativePath(path), requirement: requirement, products: products) + public static func sourceControl(path: String, requirement: Requirement) -> MockDependency { + .sourceControl(path: RelativePath(path), requirement: requirement) } - public static func sourceControl(path: RelativePath, requirement: Requirement, products: ProductFilter = .everything) -> MockDependency { - MockDependency(location: .localSourceControl(path: path, requirement: requirement), products: products) + public static func sourceControl(path: RelativePath, requirement: Requirement) -> MockDependency { + MockDependency(location: .localSourceControl(path: path, requirement: requirement)) } - public static func sourceControlWithDeprecatedName(name: String, path: String, requirement: Requirement, products: ProductFilter = .everything) -> MockDependency { - MockDependency(deprecatedName: name, location: .localSourceControl(path: RelativePath(path), requirement: requirement), products: products) + public static func sourceControlWithDeprecatedName(name: String, path: String, requirement: Requirement) -> MockDependency { + MockDependency(deprecatedName: name, location: .localSourceControl(path: RelativePath(path), requirement: requirement)) } - public static func sourceControl(url: String, requirement: Requirement, products: ProductFilter = .everything) -> MockDependency { - .sourceControl(url: URL(string: url)!, requirement: requirement, products: products) + public static func sourceControl(url: String, requirement: Requirement) -> MockDependency { + .sourceControl(url: URL(string: url)!, requirement: requirement) } - public static func sourceControl(url: URL, requirement: Requirement, products: ProductFilter = .everything) -> MockDependency { - MockDependency(location: .remoteSourceControl(url: url, requirement: requirement), products: products) + public static func sourceControl(url: URL, requirement: Requirement) -> MockDependency { + MockDependency(location: .remoteSourceControl(url: url, requirement: requirement)) } public enum Location { diff --git a/Sources/SPMTestSupport/MockManifestLoader.swift b/Sources/SPMTestSupport/MockManifestLoader.swift index 9aebd20b7e0..86af5bbc22c 100644 --- a/Sources/SPMTestSupport/MockManifestLoader.swift +++ b/Sources/SPMTestSupport/MockManifestLoader.swift @@ -53,7 +53,7 @@ public final class MockManifestLoader: ManifestLoaderProtocol { packageKind: PackageReference.Kind, packageLocation: String, version: Version?, - revision: String?, + //revision: String?, toolsVersion: ToolsVersion, identityResolver: IdentityResolver, fileSystem: FileSystem, @@ -110,7 +110,7 @@ extension ManifestLoader { packageKind: packageKind, packageLocation: packageLocation, version: nil, - revision: nil, + //revision: nil, toolsVersion: toolsVersion, identityResolver: identityResolver, fileSystem: fileSystem, diff --git a/Sources/SPMTestSupport/MockPackageContainer.swift b/Sources/SPMTestSupport/MockPackageContainer.swift index f542bca64ae..fc83a467dd6 100644 --- a/Sources/SPMTestSupport/MockPackageContainer.swift +++ b/Sources/SPMTestSupport/MockPackageContainer.swift @@ -40,19 +40,19 @@ public class MockPackageContainer: PackageContainer { return _versions } - public func getDependencies(at version: Version, productFilter: ProductFilter) -> [MockPackageContainer.Constraint] { + public func getDependencies(at version: Version) -> [MockPackageContainer.Constraint] { requestedVersions.insert(version) - return getDependencies(at: version.description, productFilter: productFilter) + return getDependencies(at: version.description) } - public func getDependencies(at revision: String, productFilter: ProductFilter) -> [MockPackageContainer.Constraint] { + public func getDependencies(at revision: String) -> [MockPackageContainer.Constraint] { return dependencies[revision]!.map { value in let (package, requirement) = value - return MockPackageContainer.Constraint(package: package, requirement: requirement, products: productFilter) + return MockPackageContainer.Constraint(package: package, requirement: requirement) } } - public func getUnversionedDependencies(productFilter: ProductFilter) -> [MockPackageContainer.Constraint] { + public func getUnversionedDependencies() -> [MockPackageContainer.Constraint] { return unversionedDeps } diff --git a/Sources/SPMTestSupport/PackageDependencyDescriptionExtensions.swift b/Sources/SPMTestSupport/PackageDependencyDescriptionExtensions.swift index 7bfc2a5e467..8502746cdbe 100644 --- a/Sources/SPMTestSupport/PackageDependencyDescriptionExtensions.swift +++ b/Sources/SPMTestSupport/PackageDependencyDescriptionExtensions.swift @@ -13,53 +13,54 @@ import PackageModel import TSCBasic public extension PackageDependency { - static func fileSystem(identity: PackageIdentity? = nil, - deprecatedName: String? = nil, - path: AbsolutePath, - productFilter: ProductFilter = .everything + static func fileSystem( + identity: PackageIdentity? = nil, + deprecatedName: String? = nil, + path: AbsolutePath ) -> Self { let identity = identity ?? PackageIdentity(path: path) - return .fileSystem(identity: identity, - nameForTargetDependencyResolutionOnly: deprecatedName, - path: path, - productFilter: productFilter) + return .fileSystem( + identity: identity, + nameForTargetDependencyResolutionOnly: deprecatedName, + path: path + ) } - - static func localSourceControl(identity: PackageIdentity? = nil, - deprecatedName: String? = nil, - path: AbsolutePath, - requirement: SourceControl.Requirement, - productFilter: ProductFilter = .everything + + static func localSourceControl( + identity: PackageIdentity? = nil, + deprecatedName: String? = nil, + path: AbsolutePath, + requirement: SourceControl.Requirement ) -> Self { let identity = identity ?? PackageIdentity(path: path) - return .localSourceControl(identity: identity, - nameForTargetDependencyResolutionOnly: deprecatedName, - path: path, - requirement: requirement, - productFilter: productFilter) + return .localSourceControl( + identity: identity, + nameForTargetDependencyResolutionOnly: deprecatedName, + path: path, + requirement: requirement + ) } - - static func remoteSourceControl(identity: PackageIdentity? = nil, - deprecatedName: String? = nil, - url: Foundation.URL, - requirement: SourceControl.Requirement, - productFilter: ProductFilter = .everything + + static func remoteSourceControl( + identity: PackageIdentity? = nil, + deprecatedName: String? = nil, + url: Foundation.URL, + requirement: SourceControl.Requirement ) -> Self { let identity = identity ?? PackageIdentity(url: url) - return .remoteSourceControl(identity: identity, - nameForTargetDependencyResolutionOnly: deprecatedName, - url: url, - requirement: requirement, - productFilter: productFilter) + return .remoteSourceControl( + identity: identity, + nameForTargetDependencyResolutionOnly: deprecatedName, + url: url, + requirement: requirement + ) } - - static func registry(identity: String, - requirement: Registry.Requirement, - productFilter: ProductFilter = .everything - ) -> Self { - return .registry(identity: .plain(identity), - requirement: requirement, - productFilter: productFilter) + + static func registry(identity: String, requirement: Registry.Requirement) -> Self { + return .registry( + identity: .plain(identity), + requirement: requirement + ) } } diff --git a/Sources/SPMTestSupport/misc.swift b/Sources/SPMTestSupport/misc.swift index e90976590a9..085f5a1e91d 100644 --- a/Sources/SPMTestSupport/misc.swift +++ b/Sources/SPMTestSupport/misc.swift @@ -224,7 +224,6 @@ public func loadPackageGraph( fs: FileSystem, manifests: [Manifest], binaryArtifacts: [BinaryArtifact] = [], - explicitProduct: String? = nil, shouldCreateMultipleTestProducts: Bool = false, createREPLProduct: Bool = false, useXCBuildFileRules: Bool = false, @@ -237,7 +236,7 @@ public func loadPackageGraph( let packages = Array(rootManifests.keys) let input = PackageGraphRootInput(packages: packages) - let graphRoot = PackageGraphRoot(input: input, manifests: rootManifests, explicitProduct: explicitProduct) + let graphRoot = PackageGraphRoot(input: input, manifests: rootManifests) return try PackageGraph.load( root: graphRoot, diff --git a/Sources/Workspace/FileSystemPackageContainer.swift b/Sources/Workspace/FileSystemPackageContainer.swift index c0f14409b93..d9a75f527a2 100644 --- a/Sources/Workspace/FileSystemPackageContainer.swift +++ b/Sources/Workspace/FileSystemPackageContainer.swift @@ -58,7 +58,7 @@ internal struct FileSystemPackageContainer: PackageContainer { packageKind: self.package.kind, packageLocation: path.pathString, version: nil, - revision: nil, + //revision: nil, toolsVersion: toolsVersion, identityResolver: self.identityResolver, fileSystem: self.fileSystem, @@ -69,8 +69,8 @@ internal struct FileSystemPackageContainer: PackageContainer { } } - public func getUnversionedDependencies(productFilter: ProductFilter) throws -> [PackageContainerConstraint] { - return try loadManifest().dependencyConstraints(productFilter: productFilter) + public func getUnversionedDependencies() throws -> [PackageContainerConstraint] { + return try loadManifest().dependencyConstraints() } public func getUpdatedIdentifier(at boundVersion: BoundVersion) throws -> PackageReference { @@ -118,11 +118,11 @@ internal struct FileSystemPackageContainer: PackageContainer { fatalError("This should never be called") } - public func getDependencies(at version: Version, productFilter: ProductFilter) throws -> [PackageContainerConstraint] { + public func getDependencies(at version: Version) throws -> [PackageContainerConstraint] { fatalError("This should never be called") } - public func getDependencies(at revision: String, productFilter: ProductFilter) throws -> [PackageContainerConstraint] { + public func getDependencies(at revision: String) throws -> [PackageContainerConstraint] { fatalError("This should never be called") } } diff --git a/Sources/Workspace/ResolverPrecomputationProvider.swift b/Sources/Workspace/ResolverPrecomputationProvider.swift index 5827396f28f..f120672013e 100644 --- a/Sources/Workspace/ResolverPrecomputationProvider.swift +++ b/Sources/Workspace/ResolverPrecomputationProvider.swift @@ -60,7 +60,7 @@ struct ResolverPrecomputationProvider: PackageContainerProvider { ) { queue.async { // Start by searching manifests from the Workspace's resolved dependencies. - if let manifest = self.dependencyManifests.dependencies.first(where: { _, managed, _ in managed.packageRef == package }) { + if let manifest = self.dependencyManifests.dependencies.first(where: { _, managed in managed.packageRef == package }) { let container = LocalPackageContainer( package: package, manifest: manifest.manifest, @@ -120,20 +120,20 @@ private struct LocalPackageContainer: PackageContainer { return try self.versionsDescending() } - func getDependencies(at version: Version, productFilter: ProductFilter) throws -> [PackageContainerConstraint] { + func getDependencies(at version: Version) throws -> [PackageContainerConstraint] { // Because of the implementation of `reversedVersions`, we should only get the exact same version. guard case .checkout(.version(version, revision: _)) = dependency?.state else { throw InternalError("expected version checkout state, but state was \(String(describing: dependency?.state))") } - return try manifest.dependencyConstraints(productFilter: productFilter) + return try manifest.dependencyConstraints() } - func getDependencies(at revisionString: String, productFilter: ProductFilter) throws -> [PackageContainerConstraint] { + func getDependencies(at revisionString: String) throws -> [PackageContainerConstraint] { // Return the dependencies if the checkout state matches the revision. let revision = Revision(identifier: revisionString) switch dependency?.state { case .checkout(.branch(_, revision: revision)), .checkout(.revision(revision)): - return try manifest.dependencyConstraints(productFilter: productFilter) + return try manifest.dependencyConstraints() default: throw ResolverPrecomputationError.differentRequirement( package: self.package, @@ -143,7 +143,7 @@ private struct LocalPackageContainer: PackageContainer { } } - func getUnversionedDependencies(productFilter: ProductFilter) throws -> [PackageContainerConstraint] { + func getUnversionedDependencies() throws -> [PackageContainerConstraint] { // Throw an error when the dependency is not unversioned to fail resolution. guard dependency?.isCheckout != true else { throw ResolverPrecomputationError.differentRequirement( @@ -153,7 +153,7 @@ private struct LocalPackageContainer: PackageContainer { ) } - return try manifest.dependencyConstraints(productFilter: productFilter) + return try manifest.dependencyConstraints() } // Gets the package reference from the managed dependency or computes it for root packages. diff --git a/Sources/Workspace/SourceControlPackageContainer.swift b/Sources/Workspace/SourceControlPackageContainer.swift index 6a3b824cc9b..af72aa4d2d8 100644 --- a/Sources/Workspace/SourceControlPackageContainer.swift +++ b/Sources/Workspace/SourceControlPackageContainer.swift @@ -60,7 +60,7 @@ internal final class SourceControlPackageContainer: PackageContainer, CustomStri private let currentToolsVersion: ToolsVersion /// The cached dependency information. - private var dependenciesCache = [String: [ProductFilter: (Manifest, [Constraint])]] () + private var dependenciesCache = [String: (Manifest, [Constraint])] () private var dependenciesCacheLock = Lock() private var knownVersionsCache = ThreadSafeBox<[Version: String]>() @@ -164,13 +164,13 @@ internal final class SourceControlPackageContainer: PackageContainer, CustomStri } } - public func getDependencies(at version: Version, productFilter: ProductFilter) throws -> [Constraint] { + public func getDependencies(at version: Version) throws -> [Constraint] { do { - return try self.getCachedDependencies(forIdentifier: version.description, productFilter: productFilter) { + return try self.getCachedDependencies(forIdentifier: version.description) { guard let tag = try self.knownVersions()[version] else { throw StringError("unknown tag \(version)") } - return try self.loadDependencies(tag: tag, version: version, productFilter: productFilter) + return try self.loadDependencies(tag: tag, version: version) }.1 } catch { throw GetDependenciesError( @@ -182,12 +182,12 @@ internal final class SourceControlPackageContainer: PackageContainer, CustomStri } } - public func getDependencies(at revision: String, productFilter: ProductFilter) throws -> [Constraint] { + public func getDependencies(at revision: String) throws -> [Constraint] { do { - return try self.getCachedDependencies(forIdentifier: revision, productFilter: productFilter) { + return try self.getCachedDependencies(forIdentifier: revision) { // resolve the revision identifier and return its dependencies. let revision = try repository.resolveRevision(identifier: revision) - return try self.loadDependencies(at: revision, productFilter: productFilter) + return try self.loadDependencies(at: revision) }.1 } catch { // Examine the error to see if we can come up with a more informative and actionable error message. We know that the revision is expected to be a branch name or a hash (tags are handled through a different code path). @@ -229,15 +229,14 @@ internal final class SourceControlPackageContainer: PackageContainer, CustomStri private func getCachedDependencies( forIdentifier identifier: String, - productFilter: ProductFilter, getDependencies: () throws -> (Manifest, [Constraint]) ) throws -> (Manifest, [Constraint]) { - if let result = (self.dependenciesCacheLock.withLock { self.dependenciesCache[identifier, default: [:]][productFilter] }) { + if let result = (self.dependenciesCacheLock.withLock { self.dependenciesCache[identifier] }) { return result } let result = try getDependencies() self.dependenciesCacheLock.withLock { - self.dependenciesCache[identifier, default: [:]][productFilter] = result + self.dependenciesCache[identifier] = result } return result } @@ -245,24 +244,22 @@ internal final class SourceControlPackageContainer: PackageContainer, CustomStri /// Returns dependencies of a container at the given revision. private func loadDependencies( tag: String, - version: Version? = nil, - productFilter: ProductFilter + version: Version? = nil ) throws -> (Manifest, [Constraint]) { let manifest = try self.loadManifest(tag: tag, version: version) - return (manifest, try manifest.dependencyConstraints(productFilter: productFilter)) + return (manifest, try manifest.dependencyConstraints()) } /// Returns dependencies of a container at the given revision. private func loadDependencies( at revision: Revision, - version: Version? = nil, - productFilter: ProductFilter + version: Version? = nil ) throws -> (Manifest, [Constraint]) { let manifest = try self.loadManifest(at: revision, version: version) - return (manifest, try manifest.dependencyConstraints(productFilter: productFilter)) + return (manifest, try manifest.dependencyConstraints()) } - public func getUnversionedDependencies(productFilter: ProductFilter) throws -> [Constraint] { + public func getUnversionedDependencies() throws -> [Constraint] { // We just return an empty array if requested for unversioned dependencies. return [] } @@ -328,18 +325,20 @@ internal final class SourceControlPackageContainer: PackageContainer, CustomStri // Load the manifest. // FIXME: this should not block return try temp_await { - self.manifestLoader.load(at: AbsolutePath.root, - packageIdentity: self.package.identity, - packageKind: self.package.kind, - packageLocation: self.package.locationString, - version: version, - revision: nil, - toolsVersion: toolsVersion, - identityResolver: self.identityResolver, - fileSystem: fileSystem, - diagnostics: nil, - on: .sharedConcurrent, - completion: $0) + self.manifestLoader.load( + at: AbsolutePath.root, + packageIdentity: self.package.identity, + packageKind: self.package.kind, + packageLocation: self.package.locationString, + version: version, + //revision: nil, + toolsVersion: toolsVersion, + identityResolver: self.identityResolver, + fileSystem: fileSystem, + diagnostics: nil, + on: .sharedConcurrent, + completion: $0 + ) } } diff --git a/Sources/Workspace/Workspace.swift b/Sources/Workspace/Workspace.swift index e09d5fe7c69..1409b23dacc 100644 --- a/Sources/Workspace/Workspace.swift +++ b/Sources/Workspace/Workspace.swift @@ -138,11 +138,11 @@ private struct WorkspaceDependencyResolverDelegate: DependencyResolverDelegate { } func willResolve(term: Term) { - self.workspaceDelegate.willComputeVersion(package: term.node.package.identity, location: term.node.package.locationString) + self.workspaceDelegate.willComputeVersion(package: term.package.identity, location: term.package.locationString) } func didResolve(term: Term, version: Version, duration: DispatchTimeInterval) { - self.workspaceDelegate.didComputeVersion(package: term.node.package.identity, location: term.node.package.locationString, version: version.description, duration: duration) + self.workspaceDelegate.didComputeVersion(package: term.package.identity, location: term.package.locationString, version: version.description, duration: duration) } // noop @@ -151,7 +151,7 @@ private struct WorkspaceDependencyResolverDelegate: DependencyResolverDelegate { func satisfied(term: Term, by assignment: Assignment, incompatibility: Incompatibility) {} func partiallySatisfied(term: Term, by assignment: Assignment, incompatibility: Incompatibility, difference: Term) {} func failedToResolve(incompatibility: Incompatibility) {} - func solved(result: [(package: PackageReference, binding: BoundVersion, products: ProductFilter)]) {} + func solved(result: [(package: PackageReference, binding: BoundVersion)]) {} } /// A workspace represents the state of a working project directory. @@ -615,7 +615,7 @@ extension Workspace { } // If any products are required, the rest of the package graph will supply those constraints. - let constraint = PackageContainerConstraint(package: dependency.packageRef, requirement: requirement, products: .nothing) + let constraint = PackageContainerConstraint(package: dependency.packageRef, requirement: requirement) // Run the resolution. try self.resolve( @@ -751,7 +751,7 @@ extension Workspace { let resolver = try self.createResolver(pinsMap: pinsMap) self.activeResolver = resolver - let updateResults = resolveDependencies( + let updateResults = self.resolveDependencies( resolver: resolver, constraints: updateConstraints, diagnostics: diagnostics @@ -763,7 +763,7 @@ extension Workspace { guard !diagnostics.hasErrors else { return nil } if dryRun { - return diagnostics.wrap { return try computePackageStateChanges(root: graphRoot, resolvedDependencies: updateResults, updateBranches: true) } + return diagnostics.wrap { return try self.computePackageStateChanges(root: graphRoot, resolvedDependencies: updateResults, updateBranches: true) } } // Update the checkouts based on new dependency resolution. @@ -818,7 +818,6 @@ extension Workspace { @discardableResult public func loadPackageGraph( rootInput root: PackageGraphRootInput, - explicitProduct: String? = nil, createMultipleTestProducts: Bool = false, createREPLProduct: Bool = false, forceResolvedVersions: Bool = false, @@ -827,7 +826,6 @@ extension Workspace { ) throws -> PackageGraph { try self.loadPackageGraph( rootInput: root, - explicitProduct: explicitProduct, createMultipleTestProducts: createMultipleTestProducts, createREPLProduct: createREPLProduct, forceResolvedVersions: forceResolvedVersions, @@ -839,7 +837,6 @@ extension Workspace { @discardableResult public func loadPackageGraph( rootInput root: PackageGraphRootInput, - explicitProduct: String? = nil, createMultipleTestProducts: Bool = false, createREPLProduct: Bool = false, forceResolvedVersions: Bool = false, @@ -852,13 +849,11 @@ extension Workspace { if forceResolvedVersions { manifests = try self.resolveBasedOnResolvedVersionsFile( root: root, - explicitProduct: explicitProduct, diagnostics: observabilityScope.makeDiagnosticsEngine() ) } else { manifests = try self.resolve( root: root, - explicitProduct: explicitProduct, forceResolution: false, constraints: [], diagnostics: observabilityScope.makeDiagnosticsEngine() @@ -890,12 +885,10 @@ extension Workspace { @discardableResult public func loadPackageGraph( rootPath: AbsolutePath, - explicitProduct: String? = nil, diagnostics: DiagnosticsEngine ) throws -> PackageGraph { try self.loadPackageGraph( rootPath: rootPath, - explicitProduct: explicitProduct, observabilityScope: ObservabilitySystem(diagnosticEngine: diagnostics).topScope ) } @@ -903,12 +896,10 @@ extension Workspace { @discardableResult public func loadPackageGraph( rootPath: AbsolutePath, - explicitProduct: String? = nil, observabilityScope: ObservabilityScope ) throws -> PackageGraph { try self.loadPackageGraph( rootInput: PackageGraphRootInput(packages: [rootPath]), - explicitProduct: explicitProduct, observabilityScope: observabilityScope ) } @@ -1037,7 +1028,7 @@ extension Workspace { let builder = PackageBuilder( identity: identity, manifest: manifest, - productFilter: .everything, + //productFilter: .everything, path: path, binaryArtifacts: binaryArtifacts, xcTestMinimumDeploymentTargets: MinimumDeploymentTarget.default.xcTestMinimumDeploymentTargets, @@ -1333,13 +1324,13 @@ extension Workspace { let root: PackageGraphRoot /// The dependency manifests in the transitive closure of root manifest. - let dependencies: [(manifest: Manifest, dependency: ManagedDependency, productFilter: ProductFilter)] + let dependencies: [(manifest: Manifest, dependency: ManagedDependency)] let workspace: Workspace fileprivate init( root: PackageGraphRoot, - dependencies: [(manifest: Manifest, dependency: ManagedDependency, productFilter: ProductFilter)], + dependencies: [(manifest: Manifest, dependency: ManagedDependency)], workspace: Workspace ) { self.root = root @@ -1392,24 +1383,24 @@ extension Workspace { var inputIdentities: Set = [] let inputNodes: [GraphLoadingNode] = self.root.packages.map{ identity, package in inputIdentities.insert(package.reference) - let node = GraphLoadingNode(identity: identity, manifest: package.manifest, productFilter: .everything) + let node = GraphLoadingNode(identity: identity, manifest: package.manifest) return node } + self.root.dependencies.compactMap{ dependency in let package = dependency.createPackageRef() inputIdentities.insert(package) return manifestsMap[dependency.identity].map { manifest in - GraphLoadingNode(identity: dependency.identity, manifest: manifest, productFilter: dependency.productFilter) + GraphLoadingNode(identity: dependency.identity, manifest: manifest) } } // FIXME: this is dropping legitimate packages with equal identities and should be revised as part of the identity work var requiredIdentities: Set = [] _ = transitiveClosure(inputNodes) { node in - return node.manifest.dependenciesRequired(for: node.productFilter).compactMap{ dependency in + return node.manifest.requiredDependencies().compactMap{ dependency in let package = dependency.createPackageRef() requiredIdentities.insert(package) return manifestsMap[dependency.identity].map { manifest in - GraphLoadingNode(identity: dependency.identity, manifest: manifest, productFilter: dependency.productFilter) + GraphLoadingNode(identity: dependency.identity, manifest: manifest) } } } @@ -1440,7 +1431,7 @@ extension Workspace { func dependencyConstraints() throws -> [PackageContainerConstraint] { var allConstraints = [PackageContainerConstraint]() - for (externalManifest, managedDependency, productFilter) in dependencies { + for (externalManifest, managedDependency) in dependencies { // For edited packages, add a constraint with unversioned requirement so the // resolver doesn't try to resolve it. switch managedDependency.state { @@ -1453,13 +1444,13 @@ extension Workspace { ) let constraint = PackageContainerConstraint( package: ref, - requirement: .unversioned, - products: productFilter) + requirement: .unversioned + ) allConstraints.append(constraint) case .checkout, .local: break } - allConstraints += try externalManifest.dependencyConstraints(productFilter: productFilter) + allConstraints += try externalManifest.dependencyConstraints() } return allConstraints } @@ -1469,7 +1460,7 @@ extension Workspace { public func editedPackagesConstraints() -> [PackageContainerConstraint] { var constraints = [PackageContainerConstraint]() - for (_, managedDependency, productFilter) in dependencies { + for (_, managedDependency) in dependencies { switch managedDependency.state { case .checkout, .local: continue case .edited: break @@ -1482,8 +1473,8 @@ extension Workspace { ) let constraint = PackageContainerConstraint( package: ref, - requirement: .unversioned, - products: productFilter) + requirement: .unversioned + ) constraints.append(constraint) } return constraints @@ -1551,12 +1542,6 @@ extension Workspace { diagnostics: DiagnosticsEngine, automaticallyAddManagedDependencies: Bool = false ) throws -> DependencyManifests { - // Utility Just because a raw tuple cannot be hashable. - struct Key: Hashable { - let identity: PackageIdentity - let productFilter: ProductFilter - } - // Make a copy of dependencies as we might mutate them in the for loop. let dependenciesToCheck = Array(self.state.dependencies) // Remove any managed dependency which has become a root. @@ -1590,10 +1575,10 @@ extension Workspace { // Creates a map of loaded manifests. We do this to avoid reloading the shared nodes. var loadedManifests = firstLevelManifests // Compute the transitive closure of available dependencies. - let input = topLevelManifests.map { identity, manifest in KeyedPair(manifest, key: Key(identity: identity, productFilter: .everything)) } - let allManifestsWithPossibleDuplicates = try topologicalSort(input) { pair in + let input = topLevelManifests.map { identity, manifest in KeyedPair(manifest, key: identity) } + let allManifests = try topologicalSort(input) { pair in // optimization: preload manifest we know about in parallel - let dependenciesRequired = pair.item.dependenciesRequired(for: pair.key.productFilter) + let dependenciesRequired = pair.item.requiredDependencies() // prepopulate managed dependencies if we are asked to do so // FIXME: this seems like hack, needs further investigation why this is needed if automaticallyAddManagedDependencies { @@ -1605,47 +1590,38 @@ extension Workspace { let dependenciesToLoad = dependenciesRequired.map{ $0.createPackageRef() }.filter { !loadedManifests.keys.contains($0.identity) } let dependenciesManifests = try temp_await { self.loadManagedManifests(for: dependenciesToLoad, diagnostics: diagnostics, completion: $0) } dependenciesManifests.forEach { loadedManifests[$0.key] = $0.value } - return pair.item.dependenciesRequired(for: pair.key.productFilter).compactMap{ dependency in + return pair.item.requiredDependencies().compactMap{ dependency in loadedManifests[dependency.identity].flatMap { // we also compare the location as this function may attempt to load // dependencies that have the same identity but from a different location // which is an error case we diagnose an report about in the GraphLoading part which // is prepared to handle the case where not all manifest are available $0.packageLocation == dependency.locationString ? - KeyedPair($0, key: Key(identity: dependency.identity, productFilter: dependency.productFilter)) : nil + KeyedPair($0, key: dependency.identity) : nil } } } - // merge the productFilter of the same package (by identity) - var deduplication = [PackageIdentity: Int]() - var allManifests = [(identity: PackageIdentity, manifest: Manifest, productFilter: ProductFilter)]() - for pair in allManifestsWithPossibleDuplicates { - if let index = deduplication[pair.key.identity] { - let productFilter = allManifests[index].productFilter.merge(pair.key.productFilter) - allManifests[index] = (pair.key.identity, pair.item, productFilter) - } else { - deduplication[pair.key.identity] = allManifests.count - allManifests.append((pair.key.identity, pair.item, pair.key.productFilter)) - } - } - - let dependencyManifests = allManifests.filter{ !root.manifests.values.contains($0.manifest) } + let dependencyManifests: OrderedDictionary = allManifests + .filter{ !root.manifests.values.contains($0.item) } + .reduce(into: .init(), { partial, item in + partial[item.key] = item.item + }) // TODO: this check should go away when introducing explicit overrides // check for overrides attempts with same name but different path let rootManifestsByName = Array(root.manifests.values).spm_createDictionary{ ($0.name, $0) } - dependencyManifests.forEach { identity, manifest, _ in + dependencyManifests.forEach { identity, manifest in if let override = rootManifestsByName[manifest.name], override.packageLocation != manifest.packageLocation { diagnostics.emit(error: "unable to override package '\(manifest.name)' because its identity '\(PackageIdentity(urlString: manifest.packageLocation))' doesn't match override's identity (directory name) '\(PackageIdentity(urlString: override.packageLocation))'") } } - let dependencies = try dependencyManifests.map{ identity, manifest, productFilter -> (Manifest, ManagedDependency, ProductFilter) in + let dependencies = try dependencyManifests.map{ identity, manifest -> (Manifest, ManagedDependency) in guard let dependency = self.state.dependencies[identity] else { throw InternalError("dependency not found for \(identity) at \(manifest.packageLocation)") } - return (manifest, dependency, productFilter) + return (manifest, dependency) } return DependencyManifests(root: root, dependencies: dependencies, workspace: self) @@ -1739,18 +1715,19 @@ extension Workspace { // Load the manifest. // The delegate callback is only passed any diagnostics emitted during the parsing of the manifest, but they are also forwarded up to the caller. let manifestLoadingDiagnostics = DiagnosticsEngine(handlers: [{ diagnostics.emit($0) }], defaultLocation: diagnostics.defaultLocation) - manifestLoader.load(at: packagePath, - packageIdentity: packageIdentity, - packageKind: packageKind, - packageLocation: packageLocation, - version: version, - revision: nil, - toolsVersion: toolsVersion, - identityResolver: self.identityResolver, - fileSystem: localFileSystem, - diagnostics: manifestLoadingDiagnostics, - on: .sharedConcurrent) { result in - + manifestLoader.load( + at: packagePath, + packageIdentity: packageIdentity, + packageKind: packageKind, + packageLocation: packageLocation, + version: version, + //revision: nil, + toolsVersion: toolsVersion, + identityResolver: self.identityResolver, + fileSystem: localFileSystem, + diagnostics: manifestLoadingDiagnostics, + on: .sharedConcurrent + ) { result in switch result { // Diagnostics.fatalError indicates that a more specific diagnostic has already been added. case .failure(Diagnostics.fatalError): @@ -1938,7 +1915,7 @@ extension Workspace { private func parseArtifacts(from manifests: DependencyManifests) throws -> (local: [ManagedArtifact], remote: [RemoteArtifact]) { let packageAndManifests: [(reference: PackageReference, manifest: Manifest)] = manifests.root.packages.values + // Root package and manifests. - manifests.dependencies.map({ manifest, managed, _ in (managed.packageRef, manifest) }) // Dependency package and manifests. + manifests.dependencies.map({ manifest, managed in (managed.packageRef, manifest) }) // Dependency package and manifests. var localArtifacts: [ManagedArtifact] = [] var remoteArtifacts: [RemoteArtifact] = [] @@ -2227,22 +2204,13 @@ extension Workspace { try self.resolveBasedOnResolvedVersionsFile(root: root, diagnostics: diagnostics) } - /// Resolves the dependencies according to the entries present in the Package.resolved file. - /// - /// This method bypasses the dependency resolution and resolves dependencies - /// according to the information in the resolved file. - public func resolveBasedOnResolvedVersionsFile(root: PackageGraphRootInput, diagnostics: DiagnosticsEngine) throws { - try self.resolveBasedOnResolvedVersionsFile(root: root, explicitProduct: .none, diagnostics: diagnostics) - } - /// Resolves the dependencies according to the entries present in the Package.resolved file. /// /// This method bypasses the dependency resolution and resolves dependencies /// according to the information in the resolved file. @discardableResult - fileprivate func resolveBasedOnResolvedVersionsFile( + public func resolveBasedOnResolvedVersionsFile( root: PackageGraphRootInput, - explicitProduct: String?, diagnostics: DiagnosticsEngine ) throws -> DependencyManifests { // Ensure the cache path exists. @@ -2250,7 +2218,7 @@ extension Workspace { // FIXME: this should not block let rootManifests = try temp_await { self.loadRootManifests(packages: root.packages, diagnostics: diagnostics, completion: $0) } - let graphRoot = PackageGraphRoot(input: root, manifests: rootManifests, explicitProduct: explicitProduct) + let graphRoot = PackageGraphRoot(input: root, manifests: rootManifests) // Load the pins store or abort now. guard let pinsStore = diagnostics.wrap({ try self.pinsStore.load() }), !diagnostics.hasErrors else { @@ -2322,7 +2290,6 @@ extension Workspace { @discardableResult fileprivate func resolve( root: PackageGraphRootInput, - explicitProduct: String? = nil, forceResolution: Bool, constraints: [PackageContainerConstraint], diagnostics: DiagnosticsEngine, @@ -2339,7 +2306,7 @@ extension Workspace { let rootManifestsMinimumToolsVersion = rootManifests.values.map{ $0.toolsVersion }.min() ?? ToolsVersion.currentToolsVersion // Load the current manifests. - let graphRoot = PackageGraphRoot(input: root, manifests: rootManifests, explicitProduct: explicitProduct) + let graphRoot = PackageGraphRoot(input: root, manifests: rootManifests) let currentManifests = try self.loadDependencyManifests(root: graphRoot, diagnostics: diagnostics) guard !diagnostics.hasErrors else { return currentManifests @@ -2426,7 +2393,6 @@ extension Workspace { // we have the manifest files of all the dependencies. return try self.resolve( root: root, - explicitProduct: explicitProduct, forceResolution: forceResolution, constraints: constraints, diagnostics: diagnostics, @@ -2443,7 +2409,6 @@ extension Workspace { // try again with pins reset return try self.resolve( root: root, - explicitProduct: explicitProduct, forceResolution: forceResolution, constraints: constraints, diagnostics: diagnostics, @@ -2486,7 +2451,7 @@ extension Workspace { @discardableResult fileprivate func updateDependenciesCheckouts( root: PackageGraphRoot, - updateResults: [(PackageReference, BoundVersion, ProductFilter)], + updateResults: [(PackageReference, BoundVersion)], updateBranches: Bool = false, diagnostics: DiagnosticsEngine ) -> [(PackageReference, PackageStateChange)] { @@ -2513,9 +2478,9 @@ extension Workspace { diagnostics.wrap { switch state { case .added(let state): - _ = try self.updateDependency(package: packageRef, requirement: state.requirement, productFilter: state.products) + _ = try self.updateDependency(package: packageRef, requirement: state.requirement) case .updated(let state): - _ = try self.updateDependency(package: packageRef, requirement: state.requirement, productFilter: state.products) + _ = try self.updateDependency(package: packageRef, requirement: state.requirement) case .removed, .unchanged: break } } @@ -2531,8 +2496,7 @@ extension Workspace { private func updateDependency( package: PackageReference, - requirement: PackageStateChange.Requirement, - productFilter: ProductFilter + requirement: PackageStateChange.Requirement ) throws -> AbsolutePath { let checkoutState: CheckoutState @@ -2601,7 +2565,7 @@ extension Workspace { let computedConstraints = try root.constraints() + // Include constraints from the manifests in the graph root. - root.manifests.values.flatMap{ try $0.dependencyConstraints(productFilter: .everything) } + + root.manifests.values.flatMap{ try $0.dependencyConstraints() } + dependencyManifests.dependencyConstraints() + constraints @@ -2700,12 +2664,12 @@ extension Workspace { } } } + public struct State: Equatable { public let requirement: Requirement - public let products: ProductFilter - public init(requirement: Requirement, products: ProductFilter) { + + public init(requirement: Requirement) { self.requirement = requirement - self.products = products } } @@ -2747,7 +2711,7 @@ extension Workspace { /// Computes states of the packages based on last stored state. fileprivate func computePackageStateChanges( root: PackageGraphRoot, - resolvedDependencies: [(PackageReference, BoundVersion, ProductFilter)], + resolvedDependencies: [(PackageReference, BoundVersion)], updateBranches: Bool ) throws -> [(PackageReference, PackageStateChange)] { // Load pins store and managed dependencies. @@ -2755,7 +2719,7 @@ extension Workspace { var packageStateChanges: [PackageIdentity: (PackageReference, PackageStateChange)] = [:] // Set the states from resolved dependencies results. - for (packageRef, binding, products) in resolvedDependencies { + for (packageRef, binding) in resolvedDependencies { // Get the existing managed dependency for this package ref, if any. // first find by identity only since edit location may be different by design @@ -2783,11 +2747,11 @@ extension Workspace { case .local, .edited: packageStateChanges[packageRef.identity] = (packageRef, .unchanged) case .checkout: - let newState = PackageStateChange.State(requirement: .unversioned, products: products) + let newState = PackageStateChange.State(requirement: .unversioned) packageStateChanges[packageRef.identity] = (packageRef, .updated(newState)) } } else { - let newState = PackageStateChange.State(requirement: .unversioned, products: products) + let newState = PackageStateChange.State(requirement: .unversioned) packageStateChanges[packageRef.identity] = (packageRef, .added(newState)) } @@ -2824,11 +2788,11 @@ extension Workspace { packageStateChanges[packageRef.identity] = (packageRef, .unchanged) } else { // Otherwise, we need to update this dependency to this revision. - let newState = PackageStateChange.State(requirement: .revision(revision, branch: branch), products: products) + let newState = PackageStateChange.State(requirement: .revision(revision, branch: branch)) packageStateChanges[packageRef.identity] = (packageRef, .updated(newState)) } } else { - let newState = PackageStateChange.State(requirement: .revision(revision, branch: branch), products: products) + let newState = PackageStateChange.State(requirement: .revision(revision, branch: branch)) packageStateChanges[packageRef.identity] = (packageRef, .added(newState)) } @@ -2837,11 +2801,11 @@ extension Workspace { if case .checkout(let checkoutState) = currentDependency.state, case .version(version, _) = checkoutState { packageStateChanges[packageRef.identity] = (packageRef, .unchanged) } else { - let newState = PackageStateChange.State(requirement: .version(version), products: products) + let newState = PackageStateChange.State(requirement: .version(version)) packageStateChanges[packageRef.identity] = (packageRef, .updated(newState)) } } else { - let newState = PackageStateChange.State(requirement: .version(version), products: products) + let newState = PackageStateChange.State(requirement: .version(version)) packageStateChanges[packageRef.identity] = (packageRef, .added(newState)) } } @@ -2879,7 +2843,7 @@ extension Workspace { resolver: PubgrubDependencyResolver, constraints: [PackageContainerConstraint], diagnostics: DiagnosticsEngine - ) -> [(package: PackageReference, binding: BoundVersion, products: ProductFilter)] { + ) -> [(package: PackageReference, binding: BoundVersion)] { os_signpost(.begin, log: .swiftpm, name: SignpostName.resolution) let result = resolver.solve(constraints: constraints) diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index 27272e75277..7500e557f02 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -2313,7 +2313,8 @@ final class BuildPlanTests: XCTestCase { TargetDescription(name: "PkgB", dependencies: ["swiftlib"]), ]), ], - explicitProduct: "exe", + // FIXME: tomer + //explicitProduct: "exe", observabilityScope: observability.topScope ) XCTAssertNoDiagnostics(observability.diagnostics) diff --git a/Tests/PackageGraphPerformanceTests/DependencyResolverPerfTests.swift b/Tests/PackageGraphPerformanceTests/DependencyResolverPerfTests.swift index 621b376c9e2..b497b868ed4 100644 --- a/Tests/PackageGraphPerformanceTests/DependencyResolverPerfTests.swift +++ b/Tests/PackageGraphPerformanceTests/DependencyResolverPerfTests.swift @@ -138,9 +138,8 @@ private extension MockPackageContainer.Constraint { guard case .dictionary(let dict) = json else { fatalError() } guard case .string(let identifier)? = dict["identifier"] else { fatalError() } guard let requirement = dict["requirement"] else { fatalError() } - let products: ProductFilter = try! JSON(dict).get("products") let ref = PackageReference.localSourceControl(identity: .plain(identifier), path: .root) - self.init(package: ref, versionRequirement: VersionSetSpecifier(requirement), products: products) + self.init(package: ref, versionRequirement: VersionSetSpecifier(requirement)) } } diff --git a/Tests/PackageGraphTests/PubgrubTests.swift b/Tests/PackageGraphTests/PubgrubTests.swift index 33edda5000c..62dc706a164 100644 --- a/Tests/PackageGraphTests/PubgrubTests.swift +++ b/Tests/PackageGraphTests/PubgrubTests.swift @@ -60,9 +60,8 @@ let bRef = PackageReference.localSourceControl(identity: .plain("b"), path: .roo let cRef = PackageReference.localSourceControl(identity: .plain("c"), path: .root) let rootRef = PackageReference.root(identity: PackageIdentity("root"), path: .root) -let rootNode = DependencyResolutionNode.root(package: rootRef) -let rootCause = try! Incompatibility(Term(rootNode, .exact(v1)), root: rootNode) -let _cause = try! Incompatibility("cause@0.0.0", root: rootNode) +let rootCause = try! Incompatibility(Term(rootRef, .exact(v1)), root: rootRef) +let _cause = try! Incompatibility("cause@0.0.0", root: rootRef) final class PubgrubTests: XCTestCase { func testTermInverse() { @@ -137,10 +136,10 @@ final class PubgrubTests: XCTestCase { Term("¬a@1.0.0")) // Check difference. - let anyA = Term(.empty(package: "a"), .any) + let anyA = Term("a", .any) XCTAssertNil(Term("a^1.0.0").difference(with: anyA)) - let notEmptyA = Term(not: .empty(package: "a"), .empty) + let notEmptyA = Term(not: "a", .empty) XCTAssertNil(Term("a^1.0.0").difference(with: notEmptyA)) } @@ -189,16 +188,14 @@ final class PubgrubTests: XCTestCase { } func testIncompatibilityNormalizeTermsOnInit() throws { - let i1 = try Incompatibility(Term("a^1.0.0"), Term("a^1.5.0"), Term("¬b@1.0.0"), - root: rootNode) + let i1 = try Incompatibility(Term("a^1.0.0"), Term("a^1.5.0"), Term("¬b@1.0.0"), root: rootRef) XCTAssertEqual(i1.terms.count, 2) - let a1 = i1.terms.first { $0.node.package == "a" } - let b1 = i1.terms.first { $0.node.package == "b" } + let a1 = i1.terms.first { $0.package == "a" } + let b1 = i1.terms.first { $0.package == "b" } XCTAssertEqual(a1?.requirement, v1_5Range) XCTAssertEqual(b1?.requirement, .exact(v1)) - let i2 = try Incompatibility(Term("¬a^1.0.0"), Term("a^2.0.0"), - root: rootNode) + let i2 = try Incompatibility(Term("¬a^1.0.0"), Term("a^2.0.0"), root: rootRef) XCTAssertEqual(i2.terms.count, 1) let a2 = i2.terms.first XCTAssertEqual(a2?.requirement, v2Range) @@ -210,40 +207,40 @@ final class PubgrubTests: XCTestCase { .derivation("b@2.0.0", cause: _cause, decisionLevel: 0), .derivation("a^1.0.0", cause: _cause, decisionLevel: 0) ]) - let a1 = s1._positive.first { $0.key.package.identity == PackageIdentity("a") }?.value + let a1: Term? = s1._positive.first { $0.key.identity == PackageIdentity("a") }?.value XCTAssertEqual(a1?.requirement, v1_5Range) - let b1 = s1._positive.first { $0.key.package.identity == PackageIdentity("b") }?.value + let b1: Term? = s1._positive.first { $0.key.identity == PackageIdentity("b") }?.value XCTAssertEqual(b1?.requirement, .exact(v2)) let s2 = PartialSolution(assignments: [ .derivation("¬a^1.5.0", cause: _cause, decisionLevel: 0), .derivation("a^1.0.0", cause: _cause, decisionLevel: 0) ]) - let a2 = s2._positive.first { $0.key.package.identity == PackageIdentity("a") }?.value + let a2: Term? = s2._positive.first { $0.key.identity == PackageIdentity("a") }?.value XCTAssertEqual(a2?.requirement, .range(v1..2. Both should have the same // effect though. builder.serve("a", at: v1) - builder.serve("a", at: v2, with: ["a": ["b": (.versionSet(v1Range), .specific(["b"]))]]) - builder.serve("b", at: v1, with: ["b": ["a": (.versionSet(v1Range), .specific(["a"]))]]) + builder.serve("a", at: v2, with: ["b": (.versionSet(v1Range))]) + builder.serve("b", at: v1, with: ["a": (.versionSet(v1Range))]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "a": (.versionSet(v1to3Range), .specific(["a"])), + "a": (.versionSet(v1to3Range)), ]) let result = resolver.solve(constraints: dependencies) @@ -471,12 +465,12 @@ final class PubgrubTests: XCTestCase { func testResolutionConflictResolutionWithAPartialSatisfier() { builder.serve("foo", at: v1) builder.serve("foo", at: v1_1, with: [ - "foo": ["left": (.versionSet(v1Range), .specific(["left"]))], - "foo": ["right": (.versionSet(v1Range), .specific(["right"]))] + "left": (.versionSet(v1Range)), + "right": (.versionSet(v1Range)) ]) - builder.serve("left", at: v1, with: ["left": ["shared": (.versionSet(v1Range), .specific(["shared"]))]]) - builder.serve("right", at: v1, with: ["right": ["shared": (.versionSet(v1Range), .specific(["shared"]))]]) - builder.serve("shared", at: v1, with: ["shared": ["target": (.versionSet(v1Range), .specific(["target"]))]]) + builder.serve("left", at: v1, with: ["shared": (.versionSet(v1Range))]) + builder.serve("right", at: v1, with: ["shared": (.versionSet(v1Range))]) + builder.serve("shared", at: v1, with: ["target": (.versionSet(v1Range))]) builder.serve("shared", at: v2) builder.serve("target", at: v1) builder.serve("target", at: v2) @@ -487,8 +481,8 @@ final class PubgrubTests: XCTestCase { let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.versionSet(v1Range), .specific(["foo"])), - "target": (.versionSet(v2Range), .specific(["target"])), + "foo": (.versionSet(v1Range)), + "target": (.versionSet(v2Range)), ]) let result = resolver.solve(constraints: dependencies) @@ -499,11 +493,11 @@ final class PubgrubTests: XCTestCase { } func testCycle1() { - builder.serve("foo", at: v1_1, with: ["foo": ["foo": (.versionSet(v1Range), .specific(["foo"]))]]) + builder.serve("foo", at: v1_1, with: ["foo": (.versionSet(v1Range))]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.versionSet(v1Range), .specific(["foo"])) + "foo": (.versionSet(v1Range)) ]) let result = resolver.solve(constraints: dependencies) @@ -513,14 +507,14 @@ final class PubgrubTests: XCTestCase { } func testCycle2() { - builder.serve("foo", at: v1_1, with: ["foo": ["bar": (.versionSet(v1Range), .specific(["bar"]))]]) - builder.serve("bar", at: v1, with: ["bar": ["baz": (.versionSet(v1Range), .specific(["baz"]))]]) - builder.serve("baz", at: v1, with: ["baz": ["bam": (.versionSet(v1Range), .specific(["bam"]))]]) - builder.serve("bam", at: v1, with: ["bam": ["baz": (.versionSet(v1Range), .specific(["baz"]))]]) + builder.serve("foo", at: v1_1, with: ["bar": (.versionSet(v1Range))]) + builder.serve("bar", at: v1, with: ["baz": (.versionSet(v1Range))]) + builder.serve("baz", at: v1, with: ["bam": (.versionSet(v1Range))]) + builder.serve("bam", at: v1, with: ["baz": (.versionSet(v1Range))]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.versionSet(v1Range), .specific(["foo"])), + "foo": (.versionSet(v1Range)), ]) let result = resolver.solve(constraints: dependencies) @@ -534,18 +528,18 @@ final class PubgrubTests: XCTestCase { func testLocalPackageCycle() { builder.serve("foo", at: .unversioned, with: [ - "foo": ["bar": (.unversioned, .specific(["bar"]))], + "bar": (.unversioned), ]) builder.serve("bar", at: .unversioned, with: [ - "bar": ["baz": (.unversioned, .specific(["baz"]))], + "baz": (.unversioned), ]) builder.serve("baz", at: .unversioned, with: [ - "baz": ["foo": (.unversioned, .specific(["foo"]))], + "foo": (.unversioned), ]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.unversioned, .specific(["foo"])), + "foo": (.unversioned), ]) let result = resolver.solve(constraints: dependencies) @@ -558,18 +552,18 @@ final class PubgrubTests: XCTestCase { func testBranchBasedPackageCycle() { builder.serve("foo", at: .revision("develop"), with: [ - "foo": ["bar": (.revision("develop"), .specific(["bar"]))], + "bar": (.revision("develop")), ]) builder.serve("bar", at: .revision("develop"), with: [ - "bar": ["baz": (.revision("develop"), .specific(["baz"]))], + "baz": (.revision("develop")), ]) builder.serve("baz", at: .revision("develop"), with: [ - "baz": ["foo": (.revision("develop"), .specific(["foo"]))], + "foo": (.revision("develop")), ]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.revision("develop"), .specific(["foo"])), + "foo": (.revision("develop")), ]) let result = resolver.solve(constraints: dependencies) @@ -583,7 +577,7 @@ final class PubgrubTests: XCTestCase { func testNonExistentPackage() { let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "package": (.versionSet(.exact(v1)), .specific(["package"])), + "package": (.versionSet(.exact(v1))), ]) let result = resolver.solve(constraints: dependencies) @@ -597,8 +591,8 @@ final class PubgrubTests: XCTestCase { let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.unversioned, .specific(["foo"])), - "bar": (.versionSet(v1Range), .specific(["bar"])) + "foo": (.unversioned), + "bar": (.versionSet(v1Range)) ]) let result = resolver.solve(constraints: dependencies) @@ -610,7 +604,7 @@ final class PubgrubTests: XCTestCase { func testUnversioned2() { builder.serve("foo", at: .unversioned, with: [ - "foo": ["bar": (.versionSet(.range(v1..<"1.2.0")), .specific(["bar"]))] + "bar": (.versionSet(.range(v1..<"1.2.0"))) ]) builder.serve("bar", at: v1) builder.serve("bar", at: v1_1) @@ -620,8 +614,8 @@ final class PubgrubTests: XCTestCase { let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.unversioned, .specific(["foo"])), - "bar": (.versionSet(v1Range), .specific(["bar"])) + "foo": (.unversioned), + "bar": (.versionSet(v1Range)) ]) let result = resolver.solve(constraints: dependencies) @@ -634,13 +628,13 @@ final class PubgrubTests: XCTestCase { func testUnversioned3() { builder.serve("foo", at: .unversioned) builder.serve("bar", at: v1, with: [ - "bar": ["foo": (.versionSet(.exact(v1)), .specific(["foo"]))] + "foo": (.versionSet(.exact(v1))) ]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.unversioned, .specific(["foo"])), - "bar": (.versionSet(v1Range), .specific(["bar"])) + "foo": (.unversioned), + "bar": (.versionSet(v1Range)) ]) let result = resolver.solve(constraints: dependencies) @@ -653,13 +647,13 @@ final class PubgrubTests: XCTestCase { func testUnversioned4() { builder.serve("foo", at: .unversioned) builder.serve("bar", at: .revision("master"), with: [ - "bar": ["foo": (.versionSet(v1Range), .specific(["foo"]))] + "foo": (.versionSet(v1Range)) ]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.unversioned, .specific(["foo"])), - "bar": (.revision("master"), .specific(["bar"])) + "foo": (.unversioned), + "bar": (.revision("master")) ]) let result = resolver.solve(constraints: dependencies) @@ -673,13 +667,13 @@ final class PubgrubTests: XCTestCase { builder.serve("foo", at: .unversioned) builder.serve("foo", at: .revision("master")) builder.serve("bar", at: .revision("master"), with: [ - "bar": ["foo": (.revision("master"), .specific(["foo"]))] + "foo": (.revision("master")) ]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.unversioned, .specific(["foo"])), - "bar": (.revision("master"), .specific(["bar"])) + "foo": (.unversioned), + "bar": (.revision("master")) ]) let result = resolver.solve(constraints: dependencies) @@ -691,15 +685,15 @@ final class PubgrubTests: XCTestCase { func testUnversioned7() { builder.serve("local", at: .unversioned, with: [ - "local": ["remote": (.unversioned, .specific(["remote"]))] + "remote": (.unversioned) ]) builder.serve("remote", at: .unversioned) builder.serve("remote", at: v1) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "local": (.unversioned, .specific(["local"])), - "remote": (.versionSet(v1Range), .specific(["remote"])), + "local": (.unversioned), + "remote": (.versionSet(v1Range)), ]) let result = resolver.solve(constraints: dependencies) @@ -711,20 +705,18 @@ final class PubgrubTests: XCTestCase { func testUnversioned8() { builder.serve("entry", at: .unversioned, with: [ - "entry": [ - "remote": (.versionSet(v1Range), .specific(["remote"])), - "local": (.unversioned, .specific(["local"])), - ] + "remote": (.versionSet(v1Range)), + "local": (.unversioned), ]) builder.serve("local", at: .unversioned, with: [ - "local": ["remote": (.unversioned, .specific(["remote"]))] + "remote": (.unversioned) ]) builder.serve("remote", at: .unversioned) builder.serve("remote", at: v1) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "entry": (.unversioned, .specific(["entry"])), + "entry": (.unversioned), ]) let result = resolver.solve(constraints: dependencies) @@ -737,20 +729,18 @@ final class PubgrubTests: XCTestCase { func testUnversioned9() { builder.serve("entry", at: .unversioned, with: [ - "entry": [ - "local": (.unversioned, .specific(["local"])), - "remote": (.versionSet(v1Range), .specific(["remote"])), - ] + "local": (.unversioned), + "remote": (.versionSet(v1Range)), ]) builder.serve("local", at: .unversioned, with: [ - "local": ["remote": (.unversioned, .specific(["remote"]))] + "remote": (.unversioned) ]) builder.serve("remote", at: .unversioned) builder.serve("remote", at: v1) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "entry": (.unversioned, .specific(["entry"])), + "entry": (.unversioned), ]) let result = resolver.solve(constraints: dependencies) @@ -762,13 +752,13 @@ final class PubgrubTests: XCTestCase { } func testResolutionWithSimpleBranchBasedDependency() { - builder.serve("foo", at: .revision("master"), with: ["foo": ["bar": (.versionSet(v1Range), .specific(["bar"]))]]) + builder.serve("foo", at: .revision("master"), with: ["bar": (.versionSet(v1Range))]) builder.serve("bar", at: v1) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.revision("master"), .specific(["foo"])), - "bar": (.versionSet(v1Range), .specific(["bar"])) + "foo": (.revision("master")), + "bar": (.versionSet(v1Range)) ]) let result = resolver.solve(constraints: dependencies) @@ -779,12 +769,12 @@ final class PubgrubTests: XCTestCase { } func testResolutionWithSimpleBranchBasedDependency2() { - builder.serve("foo", at: .revision("master"), with: ["foo": ["bar": (.versionSet(v1Range), .specific(["bar"]))]]) + builder.serve("foo", at: .revision("master"), with: ["bar": (.versionSet(v1Range))]) builder.serve("bar", at: v1) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.revision("master"), .specific(["foo"])), + "foo": (.revision("master")), ]) let result = resolver.solve(constraints: dependencies) @@ -796,12 +786,12 @@ final class PubgrubTests: XCTestCase { func testResolutionWithOverridingBranchBasedDependency() { builder.serve("foo", at: .revision("master")) - builder.serve("bar", at: v1, with: ["bar": ["foo": (.versionSet(v1Range), .specific(["foo"]))]]) + builder.serve("bar", at: v1, with: ["foo": (.versionSet(v1Range))]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.revision("master"), .specific(["foo"])), - "bar": (.versionSet(.exact(v1)), .specific(["bar"])), + "foo": (.revision("master")), + "bar": (.versionSet(.exact(v1))), ]) let result = resolver.solve(constraints: dependencies) @@ -814,12 +804,12 @@ final class PubgrubTests: XCTestCase { func testResolutionWithOverridingBranchBasedDependency2() { builder.serve("foo", at: .revision("master")) - builder.serve("bar", at: v1, with: ["bar": ["foo": (.versionSet(v1Range), .specific(["foo"]))]]) + builder.serve("bar", at: v1, with: ["foo": (.versionSet(v1Range))]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "bar": (.versionSet(.exact(v1)), .specific(["bar"])), - "foo": (.revision("master"), .specific(["foo"])), + "bar": (.versionSet(.exact(v1))), + "foo": (.revision("master")), ]) let result = resolver.solve(constraints: dependencies) @@ -830,17 +820,17 @@ final class PubgrubTests: XCTestCase { } func testResolutionWithOverridingBranchBasedDependency3() { - builder.serve("foo", at: .revision("master"), with: ["foo": ["bar": (.revision("master"), .specific(["bar"]))]]) + builder.serve("foo", at: .revision("master"), with: ["bar": (.revision("master"))]) builder.serve("bar", at: .revision("master")) builder.serve("bar", at: v1) - builder.serve("baz", at: .revision("master"), with: ["baz": ["bar": (.versionSet(v1Range), .specific(["bar"]))]]) + builder.serve("baz", at: .revision("master"), with: ["bar": (.versionSet(v1Range))]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.revision("master"), .specific(["foo"])), - "baz": (.revision("master"), .specific(["baz"])), + "foo": (.revision("master")), + "baz": (.revision("master")), ]) let result = resolver.solve(constraints: dependencies) @@ -856,7 +846,7 @@ final class PubgrubTests: XCTestCase { let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.revision("master"), .specific(["foo"])) + "foo": (.revision("master")) ]) let result = resolver.solve(constraints: dependencies) @@ -864,14 +854,14 @@ final class PubgrubTests: XCTestCase { } func testResolutionWithRevisionConflict() { - builder.serve("foo", at: .revision("master"), with: ["foo": ["bar": (.revision("master"), .specific(["bar"]))]]) + builder.serve("foo", at: .revision("master"), with: ["bar": (.revision("master"))]) builder.serve("bar", at: .version(v1)) builder.serve("bar", at: .revision("master")) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "bar": (.versionSet(v1Range), .specific(["bar"])), - "foo": (.revision("master"), .specific(["foo"])), + "bar": (.versionSet(v1Range)), + "foo": (.revision("master")), ]) let result = resolver.solve(constraints: dependencies) @@ -885,17 +875,17 @@ final class PubgrubTests: XCTestCase { builder.serve("swift-nio", at: v1) builder.serve("swift-nio", at: .revision("master")) builder.serve("swift-nio-ssl", at: .revision("master"), with: [ - "swift-nio-ssl": ["swift-nio": (.versionSet(v2Range), .specific(["swift-nio"]))], + "swift-nio": (.versionSet(v2Range)), ]) builder.serve("foo", at: "1.0.0", with: [ - "foo": ["swift-nio": (.versionSet(v1Range), .specific(["swift-nio"]))], + "swift-nio": (.versionSet(v1Range)), ]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.versionSet(v1Range), .specific(["foo"])), - "swift-nio": (.revision("master"), .specific(["swift-nio"])), - "swift-nio-ssl": (.revision("master"), .specific(["swift-nio-ssl"])), + "foo": (.versionSet(v1Range)), + "swift-nio": (.revision("master")), + "swift-nio-ssl": (.revision("master")), ]) let result = resolver.solve(constraints: dependencies) @@ -910,29 +900,25 @@ final class PubgrubTests: XCTestCase { builder.serve("swift-nio", at: v1) builder.serve("swift-nio", at: .revision("master")) builder.serve("swift-nio-ssl", at: .revision("master"), with: [ - "swift-nio-ssl": ["swift-nio": (.versionSet(v2Range), .specific(["swift-nio"]))], + "swift-nio": (.versionSet(v2Range)), ]) builder.serve("nio-postgres", at: .revision("master"), with: [ - "nio-postgres": [ - "swift-nio": (.revision("master"), .specific(["swift-nio"])), - "swift-nio-ssl": (.revision("master"), .specific(["swift-nio-ssl"])), - ] + "swift-nio": (.revision("master")), + "swift-nio-ssl": (.revision("master")), ]) builder.serve("http-client", at: v1, with: [ - "http-client": [ - "swift-nio": (.versionSet(v1Range), .specific(["swift-nio"])), - "boring-ssl": (.versionSet(v1Range), .specific(["boring-ssl"])), - ] + "swift-nio": (.versionSet(v1Range)), + "boring-ssl": (.versionSet(v1Range)), ]) builder.serve("boring-ssl", at: v1, with: [ - "boring-ssl": ["swift-nio": (.versionSet(v1Range), .specific(["swift-nio"]))], + "swift-nio": (.versionSet(v1Range)), ]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "nio-postgres": (.revision("master"), .specific(["nio-postgres"])), - "http-client": (.versionSet(v1Range), .specific(["https-client"])), - "boring-ssl": (.versionSet(v1Range), .specific(["boring-ssl"])), + "nio-postgres": (.revision("master")), + "http-client": (.versionSet(v1Range)), + "boring-ssl": (.versionSet(v1Range)), ]) let result = resolver.solve(constraints: dependencies) @@ -947,12 +933,12 @@ final class PubgrubTests: XCTestCase { func testNonVersionDependencyInVersionDependency2() { builder.serve("foo", at: v1_1, with: [ - "foo": ["bar": (.revision("master"), .specific(["bar"]))] + "bar": (.revision("master")) ]) builder.serve("foo", at: v1) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.versionSet(v1Range), .specific(["foo"])), + "foo": (.versionSet(v1Range)), ]) let result = resolver.solve(constraints: dependencies) @@ -962,26 +948,26 @@ final class PubgrubTests: XCTestCase { } func testTrivialPinStore() throws { - builder.serve("a", at: v1, with: ["a": ["b": (.versionSet(v1Range), .specific(["b"]))]]) + builder.serve("a", at: v1, with: ["b": (.versionSet(v1Range))]) builder.serve("a", at: v1_1) builder.serve("b", at: v1) builder.serve("b", at: v1_1) builder.serve("b", at: v2) let dependencies = builder.create(dependencies: [ - "a": (.versionSet(v1Range), .specific(["a"])), + "a": (.versionSet(v1Range)), ]) let pinsStore = builder.create(pinsStore: [ - "a": (.version(v1), .specific(["a"])), - "b": (.version(v1), .specific(["b"])), + "a": (.version(v1)), + "b": (.version(v1)), ]) let resolver = builder.create(pinsMap: pinsStore.pinsMap) - let result = try resolver.solve(root: rootNode, constraints: dependencies) + let result = try resolver.solve(root: rootRef, constraints: dependencies) // Since a was pinned, we shouldn't have computed bounds for its incomaptibilities. - let aIncompat = result.state.positiveIncompatibilities(for: .product("a", package: builder.reference(for: "a")))![0] + let aIncompat = result.state.positiveIncompatibilities(for: builder.reference(for: "a"))![0] XCTAssertEqual(aIncompat.terms[0].requirement, .exact("1.0.0")) AssertResult(Result.success(result.bindings), [ @@ -993,22 +979,22 @@ final class PubgrubTests: XCTestCase { func testPartialPins() { // This checks that we can drop pins that are not valid anymore but still keep the ones // which fit the constraints. - builder.serve("a", at: v1, with: ["a": ["b": (.versionSet(v1Range), .specific(["b"]))]]) + builder.serve("a", at: v1, with: ["b": (.versionSet(v1Range))]) builder.serve("a", at: v1_1) builder.serve("b", at: v1) builder.serve("b", at: v1_1) - builder.serve("c", at: v1, with: ["c": ["b": (.versionSet(.range(v1_1..= 3.2.1 contains incompatible tools version (\(ToolsVersion.v4)) and root depends on 'a' 3.2.0..<4.0.0. 'a' < 3.2.1 cannot be used because 'a' < 3.2.1 depends on 'b' 1.0.0..<2.0.0. - 'b' >= 1.0.0 cannot be used because 'b' 1.0.0 contains incompatible tools version (\(ToolsVersion.v3)) and no versions of 'b' match the requirement 1.0.1..<2.0.0. + 'b' >= 1.0.0 cannot be used because no versions of 'b' match the requirement 1.0.1..<2.0.0 and 'b' 1.0.0 contains incompatible tools version (\(ToolsVersion.v3)). """) } func testConflict4() { builder.serve("foo", at: v1, with: [ - "foo": ["shared": (.versionSet(.range("2.0.0"..<"3.0.0")), .specific(["shared"]))], + "shared": (.versionSet(.range("2.0.0"..<"3.0.0"))), ]) builder.serve("bar", at: v1, with: [ - "bar": ["shared": (.versionSet(.range("2.9.0"..<"4.0.0")), .specific(["shared"]))], + "shared": (.versionSet(.range("2.9.0"..<"4.0.0"))), ]) builder.serve("shared", at: "2.5.0") builder.serve("shared", at: "3.5.0") let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "bar": (.versionSet(.exact(v1)), .specific(["bar"])), - "foo": (.versionSet(.exact(v1)), .specific(["foo"])), + "bar": (.versionSet(.exact(v1))), + "foo": (.versionSet(.exact(v1))), ]) let result = resolver.solve(constraints: dependencies) @@ -1629,22 +1608,22 @@ final class PubGrubDiagnosticsTests: XCTestCase { func testConflict5() { builder.serve("a", at: v1, with: [ - "a": ["b": (.versionSet(.exact("1.0.0")), .specific(["b"]))], + "b": (.versionSet(.exact("1.0.0"))), ]) builder.serve("a", at: "2.0.0", with: [ - "a": ["b": (.versionSet(.exact("2.0.0")), .specific(["b"]))], + "b": (.versionSet(.exact("2.0.0"))), ]) builder.serve("b", at: "1.0.0", with: [ - "b": ["a": (.versionSet(.exact("2.0.0")), .specific(["a"]))], + "a": (.versionSet(.exact("2.0.0"))), ]) builder.serve("b", at: "2.0.0", with: [ - "b": ["a": (.versionSet(.exact("1.0.0")), .specific(["a"]))], + "a": (.versionSet(.exact("1.0.0"))), ]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "b": (.versionSet(.range("0.0.0"..<"5.0.0")), .specific(["b"])), - "a": (.versionSet(.range("0.0.0"..<"5.0.0")), .specific(["a"])), + "b": (.versionSet(.range("0.0.0"..<"5.0.0"))), + "a": (.versionSet(.range("0.0.0"..<"5.0.0"))), ]) let result = resolver.solve(constraints: dependencies) @@ -1658,35 +1637,24 @@ final class PubGrubDiagnosticsTests: XCTestCase { """) } + /* func testProductsCannotResolveToDifferentVersions() { builder.serve("root", at: .unversioned, with: [ - "root": [ - "intermediate_a": (.versionSet(v1Range), .specific(["Intermediate A"])), - "intermediate_b": (.versionSet(v1Range), .specific(["Intermediate B"])) - ] + "intermediate_a": (.versionSet(v1Range)), + "intermediate_b": (.versionSet(v1Range)) ]) builder.serve("intermediate_a", at: v1, with: [ - "Intermediate A": [ - "transitive": (.versionSet(.exact(v1)), .specific(["Product A"])) - ] + "transitive": (.versionSet(.exact(v1))) ]) builder.serve("intermediate_b", at: v1, with: [ - "Intermediate B": [ - "transitive": (.versionSet(.exact(v1_1)), .specific(["Product B"])) - ] - ]) - builder.serve("transitive", at: v1, with: [ - "Product A": [:], - "Product B": [:] - ]) - builder.serve("transitive", at: v1_1, with: [ - "Product A": [:], - "Product B": [:] + "transitive": (.versionSet(.exact(v1_1))) ]) + builder.serve("transitive", at: v1, with: [:]) + builder.serve("transitive", at: v1_1, with: [:]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "root": (.unversioned, .everything) + "root": (.unversioned) ]) let result = resolver.solve(constraints: dependencies) @@ -1698,22 +1666,22 @@ final class PubGrubDiagnosticsTests: XCTestCase { 'intermediate_b' practically depends on 'transitive' 1.1.0 because 'intermediate_b' depends on 'transitive' 1.1.0 and 'transitive' >= 1.1.0 depends on 'transitive' 1.1.0. """ ) - } + }*/ } final class PubGrubBacktrackTests: XCTestCase { func testBacktrack1() { builder.serve("a", at: v1) builder.serve("a", at: "2.0.0", with: [ - "a": ["b": (.versionSet(.exact("1.0.0")), .specific(["b"]))], + "b": (.versionSet(.exact("1.0.0"))), ]) builder.serve("b", at: "1.0.0", with: [ - "b": ["a": (.versionSet(.exact("1.0.0")), .specific(["a"]))], + "a": (.versionSet(.exact("1.0.0"))), ]) let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "a": (.versionSet(.range("1.0.0"..<"3.0.0")), .specific(["a"])), + "a": (.versionSet(.range("1.0.0"..<"3.0.0"))), ]) let result = resolver.solve(constraints: dependencies) @@ -1726,14 +1694,14 @@ final class PubGrubBacktrackTests: XCTestCase { func testBacktrack2() { builder.serve("a", at: v1) builder.serve("a", at: "2.0.0", with: [ - "a": ["c": (.versionSet(.range("1.0.0"..<"2.0.0")), .specific(["c"]))], + "c": (.versionSet(.range("1.0.0"..<"2.0.0"))), ]) builder.serve("b", at: "1.0.0", with: [ - "b": ["c": (.versionSet(.range("2.0.0"..<"3.0.0")), .specific(["c"]))], + "c": (.versionSet(.range("2.0.0"..<"3.0.0"))), ]) builder.serve("b", at: "2.0.0", with: [ - "b": ["c": (.versionSet(.range("3.0.0"..<"4.0.0")), .specific(["c"]))], + "c": (.versionSet(.range("3.0.0"..<"4.0.0"))), ]) builder.serve("c", at: "1.0.0") @@ -1742,8 +1710,8 @@ final class PubGrubBacktrackTests: XCTestCase { let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "a": (.versionSet(.range("1.0.0"..<"3.0.0")), .specific(["a"])), - "b": (.versionSet(.range("1.0.0"..<"3.0.0")), .specific(["b"])), + "a": (.versionSet(.range("1.0.0"..<"3.0.0"))), + "b": (.versionSet(.range("1.0.0"..<"3.0.0"))), ]) let result = resolver.solve(constraints: dependencies) @@ -1757,24 +1725,22 @@ final class PubGrubBacktrackTests: XCTestCase { func testBacktrack3() { builder.serve("a", at: "1.0.0", with: [ - "a": ["x": (.versionSet(.range("1.0.0"..<"5.0.0")), .specific(["x"]))], + "x": (.versionSet(.range("1.0.0"..<"5.0.0"))), ]) builder.serve("b", at: "1.0.0", with: [ - "b": ["x": (.versionSet(.range("0.0.0"..<"2.0.0")), .specific(["x"]))], + "x": (.versionSet(.range("0.0.0"..<"2.0.0"))), ]) builder.serve("c", at: "1.0.0") builder.serve("c", at: "2.0.0", with: [ - "c": [ - "a": (.versionSet(.range("0.0.0"..<"5.0.0")), .specific(["a"])), - "b": (.versionSet(.range("0.0.0"..<"5.0.0")), .specific(["b"])), - ] + "a": (.versionSet(.range("0.0.0"..<"5.0.0"))), + "b": (.versionSet(.range("0.0.0"..<"5.0.0"))), ]) builder.serve("x", at: "0.0.0") builder.serve("x", at: "2.0.0") builder.serve("x", at: "1.0.0", with: [ - "x": ["y": (.versionSet(.exact(v1)), .specific(["y"]))], + "y": (.versionSet(.exact(v1))), ]) builder.serve("y", at: "1.0.0") @@ -1782,8 +1748,8 @@ final class PubGrubBacktrackTests: XCTestCase { let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "c": (.versionSet(.range("1.0.0"..<"3.0.0")), .specific(["c"])), - "y": (.versionSet(.range("2.0.0"..<"3.0.0")), .specific(["y"])), + "c": (.versionSet(.range("1.0.0"..<"3.0.0"))), + "y": (.versionSet(.range("2.0.0"..<"3.0.0"))), ]) let result = resolver.solve(constraints: dependencies) @@ -1796,24 +1762,22 @@ final class PubGrubBacktrackTests: XCTestCase { func testBacktrack4() { builder.serve("a", at: "1.0.0", with: [ - "a": ["x": (.versionSet(.range("1.0.0"..<"5.0.0")), .specific(["x"]))], + "x": (.versionSet(.range("1.0.0"..<"5.0.0"))), ]) builder.serve("b", at: "1.0.0", with: [ - "b": ["x": (.versionSet(.range("0.0.0"..<"2.0.0")), .specific(["x"]))], + "x": (.versionSet(.range("0.0.0"..<"2.0.0"))), ]) builder.serve("c", at: "1.0.0") builder.serve("c", at: "2.0.0", with: [ - "c": [ - "a": (.versionSet(.range("0.0.0"..<"5.0.0")), .specific(["a"])), - "b": (.versionSet(.range("0.0.0"..<"5.0.0")), .specific(["b"])), - ] + "a": (.versionSet(.range("0.0.0"..<"5.0.0"))), + "b": (.versionSet(.range("0.0.0"..<"5.0.0"))), ]) builder.serve("x", at: "0.0.0") builder.serve("x", at: "2.0.0") builder.serve("x", at: "1.0.0", with: [ - "x": ["y": (.versionSet(.exact(v1)), .specific(["y"]))], + "y": (.versionSet(.exact(v1))), ]) builder.serve("y", at: "1.0.0") @@ -1821,8 +1785,8 @@ final class PubGrubBacktrackTests: XCTestCase { let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "c": (.versionSet(.range("1.0.0"..<"3.0.0")), .specific(["c"])), - "y": (.versionSet(.range("2.0.0"..<"3.0.0")), .specific(["y"])), + "c": (.versionSet(.range("1.0.0"..<"3.0.0"))), + "y": (.versionSet(.range("2.0.0"..<"3.0.0"))), ]) let result = resolver.solve(constraints: dependencies) @@ -1835,30 +1799,30 @@ final class PubGrubBacktrackTests: XCTestCase { func testBacktrack5() { builder.serve("foo", at: "1.0.0", with: [ - "foo": ["bar": (.versionSet(.exact("1.0.0")), .specific(["bar"]))], + "bar": (.versionSet(.exact("1.0.0"))), ]) builder.serve("foo", at: "2.0.0", with: [ - "foo": ["bar": (.versionSet(.exact("2.0.0")), .specific(["bar"]))], + "bar": (.versionSet(.exact("2.0.0"))), ]) builder.serve("foo", at: "3.0.0", with: [ - "foo": ["bar": (.versionSet(.exact("3.0.0")), .specific(["bar"]))], + "bar": (.versionSet(.exact("3.0.0"))), ]) builder.serve("bar", at: "1.0.0", with: [ - "bar": ["baz": (.versionSet(.range("0.0.0"..<"3.0.0")), .specific(["baz"]))], + "baz": (.versionSet(.range("0.0.0"..<"3.0.0"))), ]) builder.serve("bar", at: "2.0.0", with: [ - "bar": ["baz": (.versionSet(.exact("3.0.0")), .specific(["baz"]))], + "baz": (.versionSet(.exact("3.0.0"))), ]) builder.serve("bar", at: "3.0.0", with: [ - "bar": ["baz": (.versionSet(.exact("3.0.0")), .specific(["baz"]))], + "baz": (.versionSet(.exact("3.0.0"))), ]) builder.serve("baz", at: "1.0.0") let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "foo": (.versionSet(.range("1.0.0"..<"4.0.0")), .specific(["foo"])), + "foo": (.versionSet(.range("1.0.0"..<"4.0.0"))), ]) let result = resolver.solve(constraints: dependencies) @@ -1874,19 +1838,19 @@ final class PubGrubBacktrackTests: XCTestCase { builder.serve("a", at: "1.0.0") builder.serve("a", at: "2.0.0") builder.serve("b", at: "1.0.0", with: [ - "b": ["a": (.versionSet(.exact("1.0.0")), .specific(["a"]))], + "a": (.versionSet(.exact("1.0.0"))), ]) builder.serve("c", at: "1.0.0", with: [ - "c": ["b": (.versionSet(.range("0.0.0"..<"3.0.0")), .specific(["b"]))], + "b": (.versionSet(.range("0.0.0"..<"3.0.0"))), ]) builder.serve("d", at: "1.0.0") builder.serve("d", at: "2.0.0") let resolver = builder.create() let dependencies = builder.create(dependencies: [ - "a": (.versionSet(.range("1.0.0"..<"4.0.0")), .specific(["a"])), - "c": (.versionSet(.range("1.0.0"..<"4.0.0")), .specific(["c"])), - "d": (.versionSet(.range("1.0.0"..<"4.0.0")), .specific(["d"])), + "a": (.versionSet(.range("1.0.0"..<"4.0.0"))), + "c": (.versionSet(.range("1.0.0"..<"4.0.0"))), + "d": (.versionSet(.range("1.0.0"..<"4.0.0"))), ]) let result = resolver.solve(constraints: dependencies) @@ -1975,12 +1939,12 @@ private func AssertError( // FIXME: this is not thread-safe public class MockContainer: PackageContainer { - public typealias Dependency = (container: PackageReference, requirement: PackageRequirement, productFilter: ProductFilter) + public typealias Dependency = (container: PackageReference, requirement: PackageRequirement) public var package: PackageReference var manifestName: PackageReference? - var dependencies: [String: [String: [Dependency]]] + var dependencies: [String: [Dependency]] public var unversionedDeps: [PackageContainerConstraint] = [] @@ -2027,30 +1991,26 @@ public class MockContainer: PackageContainer { return version } - public func getDependencies(at version: Version, productFilter: ProductFilter) throws -> [PackageContainerConstraint] { - return try getDependencies(at: version.description, productFilter: productFilter) + public func getDependencies(at version: Version) throws -> [PackageContainerConstraint] { + return try getDependencies(at: version.description) } - public func getDependencies(at revision: String, productFilter: ProductFilter) throws -> [PackageContainerConstraint] { + public func getDependencies(at revision: String) throws -> [PackageContainerConstraint] { guard let revisionDependencies = dependencies[revision] else { throw _MockLoadingError.unknownRevision } - var filteredDependencies: [MockContainer.Dependency] = [] - for (product, productDependencies) in revisionDependencies where productFilter.contains(product) { - filteredDependencies.append(contentsOf: productDependencies) + return revisionDependencies.map{ value in + let (package, requirement) = value + return PackageContainerConstraint(package: package, requirement: requirement) } - return filteredDependencies.map({ value in - let (package, requirement, filter) = value - return PackageContainerConstraint(package: package, requirement: requirement, products: filter) - }) } - public func getUnversionedDependencies(productFilter: ProductFilter) throws -> [PackageContainerConstraint] { + public func getUnversionedDependencies() throws -> [PackageContainerConstraint] { // FIXME: This is messy, remove unversionedDeps property. if !unversionedDeps.isEmpty { return unversionedDeps } - return try getDependencies(at: PackageRequirement.unversioned.description, productFilter: productFilter) + return try getDependencies(at: PackageRequirement.unversioned.description) } public func getUpdatedIdentifier(at boundVersion: BoundVersion) throws -> PackageReference { @@ -2073,29 +2033,21 @@ public class MockContainer: PackageContainer { public convenience init( package: PackageReference, - unversionedDependencies: [(package: PackageReference, requirement: PackageRequirement, productFilter: ProductFilter)] + unversionedDependencies: [(package: PackageReference, requirement: PackageRequirement)] ) { self.init(package: package) self.unversionedDeps = unversionedDependencies - .map { PackageContainerConstraint(package: $0.package, requirement: $0.requirement, products: $0.productFilter) } + .map { PackageContainerConstraint(package: $0.package, requirement: $0.requirement) } } public convenience init( package: PackageReference, - dependenciesByVersion: [Version: [String: [( - package: PackageReference, - requirement: VersionSetSpecifier, - productFilter: ProductFilter - )]]]) { - var dependencies: [String: [String: [Dependency]]] = [:] - for (version, productDependencies) in dependenciesByVersion { - if dependencies[version.description] == nil { - dependencies[version.description] = [:] - } - for (product, deps) in productDependencies { - dependencies[version.description, default: [:]][product] = deps.map({ - ($0.package, .versionSet($0.requirement), $0.productFilter) - }) + dependenciesByVersion: [Version: [(package: PackageReference, requirement: VersionSetSpecifier)]] + ) { + var dependencies: [String: [Dependency]] = [:] + for (version, deps) in dependenciesByVersion { + dependencies[version.description] = deps.map{ + ($0.package, .versionSet($0.requirement)) } } self.init(package: package, dependencies: dependencies) @@ -2103,7 +2055,7 @@ public class MockContainer: PackageContainer { public init( package: PackageReference, - dependencies: [String: [String: [Dependency]]] = [:] + dependencies: [String: [Dependency]] = [:] ) { self.package = package self.dependencies = dependencies @@ -2155,11 +2107,9 @@ class DependencyGraphBuilder { return newReference } - func create( - dependencies: OrderedDictionary - ) -> [PackageContainerConstraint] { + func create(dependencies: OrderedDictionary) -> [PackageContainerConstraint] { return dependencies.map { - PackageContainerConstraint(package: reference(for: $0), requirement: $1.0, products: $1.1) + PackageContainerConstraint(package: reference(for: $0), requirement: $1) } } @@ -2167,7 +2117,7 @@ class DependencyGraphBuilder { _ package: String, at version: Version, toolsVersion: ToolsVersion? = nil, - with dependencies: KeyValuePairs> = [:] + with dependencies: KeyValuePairs = [:] ) { serve(package, at: .version(version), toolsVersion: toolsVersion, with: dependencies) } @@ -2176,7 +2126,7 @@ class DependencyGraphBuilder { _ package: String, at version: BoundVersion, toolsVersion: ToolsVersion? = nil, - with dependencies: KeyValuePairs> = [:] + with dependencies: KeyValuePairs = [:] ) { let packageReference = reference(for: package) let container = self.containers[package] ?? MockContainer(package: packageReference) @@ -2187,25 +2137,20 @@ class DependencyGraphBuilder { container.appendVersion(version) - if container.dependencies[version.description] == nil { - container.dependencies[version.description] = [:] - } - for (product, filteredDependencies) in dependencies { - let packageDependencies: [MockContainer.Dependency] = filteredDependencies.map { - (container: reference(for: $0), requirement: $1.0, products: $1.1) - } - container.dependencies[version.description, default: [:]][product, default: []] += packageDependencies + let packageDependencies = dependencies.map { + (container: reference(for: $0), requirement: $1) } + container.dependencies[version.description] = packageDependencies self.containers[package] = container } /// Creates a pins store with the given pins. - func create(pinsStore pins: [String: (CheckoutState, ProductFilter)]) -> PinsStore { + func create(pinsStore pins: [String: CheckoutState]) -> PinsStore { let fs = InMemoryFileSystem() let store = try! PinsStore(pinsFile: AbsolutePath("/tmp/Package.resolved"), workingDirectory: .root, fileSystem: fs, mirrors: .init()) - for (package, pin) in pins { - store.pin(packageRef: reference(for: package), state: pin.0) + for (package, pinState) in pins { + store.pin(packageRef: reference(for: package), state: pinState) } try! store.saveState(toolsVersion: ToolsVersion.currentToolsVersion) @@ -2265,9 +2210,11 @@ extension Term: ExpressibleByStringLiteral { guard case let .versionSet(vs) = requirement! else { fatalError() } - self.init(node: .product(packageReference.name, package: packageReference), - requirement: vs, - isPositive: isPositive) + self.init( + package: packageReference, + requirement: vs, + isPositive: isPositive + ) } } diff --git a/Tests/PackageLoadingTests/PD_4_2_LoadingTests.swift b/Tests/PackageLoadingTests/PD_4_2_LoadingTests.swift index 78b763c78a2..bf87d26b2e5 100644 --- a/Tests/PackageLoadingTests/PD_4_2_LoadingTests.swift +++ b/Tests/PackageLoadingTests/PD_4_2_LoadingTests.swift @@ -815,7 +815,7 @@ class PackageDescription4_2LoadingTests: PackageDescriptionLoadingTests { packageKind: .fileSystem(manifestPath.parentDirectory), packageLocation: manifestPath.pathString, version: nil, - revision: nil, + //revision: nil, toolsVersion: .v4_2, identityResolver: identityResolver, fileSystem: localFileSystem, @@ -834,7 +834,7 @@ class PackageDescription4_2LoadingTests: PackageDescriptionLoadingTests { packageKind: .fileSystem(manifestPath.parentDirectory), packageLocation: manifestPath.pathString, version: nil, - revision: nil, + //revision: nil, toolsVersion: .v4_2, identityResolver: identityResolver, fileSystem: localFileSystem, @@ -899,7 +899,7 @@ class PackageDescription4_2LoadingTests: PackageDescriptionLoadingTests { packageKind: .fileSystem(manifestPath.parentDirectory), packageLocation: manifestPath.pathString, version: nil, - revision: nil, + //revision: nil, toolsVersion: .v4_2, identityResolver: identityResolver, fileSystem: localFileSystem, diff --git a/Tests/PackageLoadingTests/PackageBuilderTests.swift b/Tests/PackageLoadingTests/PackageBuilderTests.swift index d326b084331..aaa446ce037 100644 --- a/Tests/PackageLoadingTests/PackageBuilderTests.swift +++ b/Tests/PackageLoadingTests/PackageBuilderTests.swift @@ -2391,7 +2391,6 @@ final class PackageBuilderTester { let builder = PackageBuilder( identity: PackageIdentity(urlString: manifest.packageLocation), manifest: manifest, - productFilter: .everything, path: path, binaryArtifacts: binaryArtifacts, xcTestMinimumDeploymentTargets: Self.xcTestMinimumDeploymentTargets, diff --git a/Tests/PackageModelTests/ManifestTests.swift b/Tests/PackageModelTests/ManifestTests.swift index 2022370f101..55465a32a9d 100644 --- a/Tests/PackageModelTests/ManifestTests.swift +++ b/Tests/PackageModelTests/ManifestTests.swift @@ -36,7 +36,7 @@ class ManifestTests: XCTestCase { targets: targets ) - XCTAssertEqual(manifest.targetsRequired(for: .everything).map({ $0.name }).sorted(), [ + XCTAssertEqual(manifest.requiredTargets().map({ $0.name }).sorted(), [ "Bar", "Baz", "Foo", @@ -91,7 +91,7 @@ class ManifestTests: XCTestCase { targets: targets ) - XCTAssertEqual(manifest.dependenciesRequired(for: .everything).map({ $0.identity.description }).sorted(), [ + XCTAssertEqual(manifest.requiredDependencies().map({ $0.identity.description }).sorted(), [ "bar1", "bar2", "bar3", @@ -108,7 +108,8 @@ class ManifestTests: XCTestCase { targets: targets ) - XCTAssertEqual(manifest.dependenciesRequired(for: .specific(["Foo"])).map({ $0.identity.description }).sorted(), [ + // FIXME: tomer + XCTAssertEqual(manifest.requiredDependencies(/*for: .specific(["Foo"])*/).map({ $0.identity.description }).sorted(), [ "bar1", // Foo → Foo1 → Bar1 "bar2", // Foo → Foo1 → Foo2 → Bar2 "bar3", // Foo → Foo1 → Bar1 → could be from any package due to pre‐5.2 tools version. @@ -125,7 +126,7 @@ class ManifestTests: XCTestCase { targets: targets ) - XCTAssertEqual(manifest.dependenciesRequired(for: .everything).map({ $0.identity.description }).sorted(), [ + XCTAssertEqual(manifest.requiredDependencies().map({ $0.identity.description }).sorted(), [ "bar1", "bar2", "bar3", diff --git a/Tests/WorkspaceTests/ManifestSourceGenerationTests.swift b/Tests/WorkspaceTests/ManifestSourceGenerationTests.swift index 34030135cd1..a414509a24c 100644 --- a/Tests/WorkspaceTests/ManifestSourceGenerationTests.swift +++ b/Tests/WorkspaceTests/ManifestSourceGenerationTests.swift @@ -38,7 +38,7 @@ class ManifestSourceGenerationTests: XCTestCase { packageKind: .root(packageDir), packageLocation: packageDir.pathString, version: nil, - revision: nil, + //revision: nil, toolsVersion: toolsVersion, identityResolver: identityResolver, fileSystem: fs, @@ -63,7 +63,7 @@ class ManifestSourceGenerationTests: XCTestCase { packageKind: .root(packageDir), packageLocation: packageDir.pathString, version: nil, - revision: nil, + //revision: nil, toolsVersion: toolsVersion, identityResolver: identityResolver, fileSystem: fs, diff --git a/Tests/WorkspaceTests/PackageContainerProviderTests.swift b/Tests/WorkspaceTests/PackageContainerProviderTests.swift index 21a767e415b..a7e7309c279 100644 --- a/Tests/WorkspaceTests/PackageContainerProviderTests.swift +++ b/Tests/WorkspaceTests/PackageContainerProviderTests.swift @@ -289,7 +289,7 @@ class PackageContainerProviderTests: XCTestCase { let container = try provider.getContainer(for: ref, skipUpdate: false) as! SourceControlPackageContainer let revision = try container.getRevision(forTag: "1.0.0") do { - _ = try container.getDependencies(at: revision.identifier, productFilter: .nothing) + _ = try container.getDependencies(at: revision.identifier) } catch let error as SourceControlPackageContainer.GetDependenciesError { let error = error.underlyingError as! UnsupportedToolsVersion XCTAssertMatch(error.description, .and(.prefix("package '\(PackageIdentity(path: repoPath))' @"), .suffix("is using Swift tools version 3.1.0 which is no longer supported; consider using '// swift-tools-version:4.0' to specify the current tools version"))) @@ -389,6 +389,8 @@ class PackageContainerProviderTests: XCTestCase { XCTAssertEqual(v, ["2.0.1", "1.3.0", "1.2.0", "1.1.0", "1.0.4", "1.0.2", "1.0.1", "1.0.0"]) } + + /* // FIXME: tomer func testDependencyConstraints() throws { #if ENABLE_TARGET_BASED_DEPENDENCY_RESOLUTION #else @@ -522,7 +524,7 @@ class PackageContainerProviderTests: XCTestCase { ] ) } - } + }*/ func testMissingBranchDiagnostics() throws { try testWithTemporaryDirectory { tmpDir in @@ -568,7 +570,7 @@ class PackageContainerProviderTests: XCTestCase { let container = try containerProvider.getContainer(for: packageRef, skipUpdate: false) as! SourceControlPackageContainer // Simulate accessing a fictitious dependency on the `master` branch, and check that we get back the expected error. - do { _ = try container.getDependencies(at: "master", productFilter: .everything) } + do { _ = try container.getDependencies(at: "master") } catch let error as SourceControlPackageContainer.GetDependenciesError { // We expect to get an error message that mentions main. XCTAssertMatch(error.description, .and(.prefix("could not find a branch named ‘master’"), .suffix("(did you mean ‘main’?)"))) @@ -576,7 +578,7 @@ class PackageContainerProviderTests: XCTestCase { } // Simulate accessing a fictitious dependency on some random commit that doesn't exist, and check that we get back the expected error. - do { _ = try container.getDependencies(at: "535f4cb5b4a0872fa691473e82d7b27b9894df00", productFilter: .everything) } + do { _ = try container.getDependencies(at: "535f4cb5b4a0872fa691473e82d7b27b9894df00") } catch let error as SourceControlPackageContainer.GetDependenciesError { // We expect to get an error message about the specific commit. XCTAssertMatch(error.description, .prefix("could not find the commit 535f4cb5b4a0872fa691473e82d7b27b9894df00")) @@ -585,6 +587,7 @@ class PackageContainerProviderTests: XCTestCase { } } + /* // FIXME: tomer func testRepositoryPackageContainerCache() throws { // From rdar://problem/65284674 // RepositoryPackageContainer used to erroneously cache dependencies based only on version, @@ -651,7 +654,7 @@ class PackageContainerProviderTests: XCTestCase { XCTAssertNotEqual(forNothing, forProduct) #endif } - } + }*/ } extension PackageContainerProvider { diff --git a/Tests/WorkspaceTests/WorkspaceTests.swift b/Tests/WorkspaceTests/WorkspaceTests.swift index 2e8b415505a..ed369bb4282 100644 --- a/Tests/WorkspaceTests/WorkspaceTests.swift +++ b/Tests/WorkspaceTests/WorkspaceTests.swift @@ -69,8 +69,9 @@ final class WorkspaceTests: XCTestCase { ) let deps: [MockDependency] = [ - .sourceControl(path: "./Quix", requirement: .upToNextMajor(from: "1.0.0"), products: .specific(["Quix"])), - .sourceControl(path: "./Baz", requirement: .exact("1.0.0"), products: .specific(["Baz"])), + // FIXME: tomer + .sourceControl(path: "./Quix", requirement: .upToNextMajor(from: "1.0.0")/*, products: .specific(["Quix"])*/), + .sourceControl(path: "./Baz", requirement: .exact("1.0.0")/*, products: .specific(["Baz"])*/), ] try workspace.checkPackageGraph(roots: ["Foo"], deps: deps) { graph, diagnostics in PackageGraphTester(graph) { result in @@ -607,16 +608,17 @@ final class WorkspaceTests: XCTestCase { ] ) + // FIXME: tomer let dependencies: [PackageDependency] = [ .localSourceControl( path: workspace.packagesDir.appending(component: "Bar"), - requirement: .upToNextMajor(from: "1.0.0"), - productFilter: .specific(["Bar"]) + requirement: .upToNextMajor(from: "1.0.0")//, + //productFilter: .specific(["Bar"]) ), .localSourceControl( path: workspace.packagesDir.appending(component: "Foo"), - requirement: .upToNextMajor(from: "1.0.0"), - productFilter: .specific(["Foo"]) + requirement: .upToNextMajor(from: "1.0.0")//, + //productFilter: .specific(["Foo"]) ), ] @@ -685,7 +687,8 @@ final class WorkspaceTests: XCTestCase { // Resolve when A = 1.0.0. do { let deps: [MockDependency] = [ - .sourceControl(path: "./A", requirement: .exact("1.0.0"), products: .specific(["A"])), + // FIXME: tomer + .sourceControl(path: "./A", requirement: .exact("1.0.0")/*, products: .specific(["A"])*/), ] try workspace.checkPackageGraph(deps: deps) { graph, diagnostics in PackageGraphTester(graph) { result in @@ -708,7 +711,8 @@ final class WorkspaceTests: XCTestCase { // Resolve when A = 1.0.1. do { let deps: [MockDependency] = [ - .sourceControl(path: "./A", requirement: .exact("1.0.1"), products: .specific(["A"])), + // FIXME: tomer + .sourceControl(path: "./A", requirement: .exact("1.0.1")/*, products: .specific(["A"])*/), ] try workspace.checkPackageGraph(deps: deps) { graph, diagnostics in PackageGraphTester(graph) { result in @@ -779,8 +783,9 @@ final class WorkspaceTests: XCTestCase { ) let deps: [MockDependency] = [ - .sourceControl(path: "./A", requirement: .exact("1.0.0"), products: .specific(["A"])), - .sourceControl(path: "./B", requirement: .exact("1.0.0"), products: .specific(["B"])), + // FIXME: tomer + .sourceControl(path: "./A", requirement: .exact("1.0.0")/*, products: .specific(["A"])*/), + .sourceControl(path: "./B", requirement: .exact("1.0.0")/*, products: .specific(["B"])*/), ] try workspace.checkPackageGraph(deps: deps) { _, diagnostics in testDiagnostics(diagnostics) { result in @@ -1384,7 +1389,8 @@ final class WorkspaceTests: XCTestCase { // Do an intial run, capping at Foo at 1.0.0. let deps: [MockDependency] = [ - .sourceControl(path: "./Foo", requirement: .exact("1.0.0"), products: .specific(["Foo"])), + // FIXME: tomer + .sourceControl(path: "./Foo", requirement: .exact("1.0.0")/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { graph, diagnostics in PackageGraphTester(graph) { result in @@ -1469,7 +1475,8 @@ final class WorkspaceTests: XCTestCase { // Do an intial run, capping at Foo at 1.0.0. let deps: [MockDependency] = [ - .sourceControl(path: "./Foo", requirement: .exact("1.0.0"), products: .specific(["Foo"])), + // FIXME: tomer + .sourceControl(path: "./Foo", requirement: .exact("1.0.0")/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { graph, diagnostics in @@ -1486,10 +1493,11 @@ final class WorkspaceTests: XCTestCase { // Run update. try workspace.checkUpdateDryRun(roots: ["Root"]) { changes, diagnostics in XCTAssertNoDiagnostics(diagnostics) + // FIXME: tomer #if ENABLE_TARGET_BASED_DEPENDENCY_RESOLUTION - let stateChange = Workspace.PackageStateChange.updated(.init(requirement: .version(Version("1.5.0")), products: .specific(["Foo"]))) + let stateChange = Workspace.PackageStateChange.updated(.init(requirement: .version(Version("1.5.0"))/*, products: .specific(["Foo"])*/)) #else - let stateChange = Workspace.PackageStateChange.updated(.init(requirement: .version(Version("1.5.0")), products: .everything)) + let stateChange = Workspace.PackageStateChange.updated(.init(requirement: .version(Version("1.5.0"))/*, products: .everything*/)) #endif let path = AbsolutePath("/tmp/ws/pkgs/Foo") @@ -1576,9 +1584,10 @@ final class WorkspaceTests: XCTestCase { ] ) - // Do an intial run, capping at Foo at 1.0.0. + // Do an initial run, capping at Foo at 1.0.0. let deps: [MockDependency] = [ - .sourceControl(path: "./Foo", requirement: .exact("1.0.0"), products: .specific(["Foo"])), + // FIXME: tomer + .sourceControl(path: "./Foo", requirement: .exact("1.0.0")/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { _, diagnostics in XCTAssertNoDiagnostics(diagnostics) @@ -1883,7 +1892,8 @@ final class WorkspaceTests: XCTestCase { // We request Bar via revision. let deps: [MockDependency] = [ - .sourceControl(path: "./Bar", requirement: .revision(barRevision), products: .specific(["Bar"])), + // FIXME: tomer + .sourceControl(path: "./Bar", requirement: .revision(barRevision)/*, products: .specific(["Bar"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { graph, diagnostics in PackageGraphTester(graph) { result in @@ -1960,7 +1970,7 @@ final class WorkspaceTests: XCTestCase { // Check failure. workspace.checkResolve(pkg: "Foo", roots: ["Root"], version: "1.3.0") { diagnostics in testDiagnostics(diagnostics) { result in - result.check(diagnostic: .contains("'Foo' 1.3.0"), severity: .error) + result.check(diagnostic: .contains("'foo' 1.3.0"), severity: .error) } } workspace.checkManagedDependencies { result in @@ -2335,7 +2345,8 @@ final class WorkspaceTests: XCTestCase { ) let deps: [MockDependency] = [ - .sourceControl(path: "./Foo", requirement: .upToNextMajor(from: "1.0.0"), products: .specific(["Foo"])), + // FIXME: tomer + .sourceControl(path: "./Foo", requirement: .upToNextMajor(from: "1.0.0")/*, products: .specific(["Foo"])*/), ] let ws = try workspace.getOrCreateWorkspace() @@ -2428,7 +2439,8 @@ final class WorkspaceTests: XCTestCase { ) let deps: [MockDependency] = [ - .sourceControl(path: "./Foo", requirement: .exact("1.0.0"), products: .specific(["Foo"])), + // FIXME: tomer + .sourceControl(path: "./Foo", requirement: .exact("1.0.0")/*, products: .specific(["Foo"])*/), ] // Load the graph. try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { graph, diagnostics in @@ -2573,7 +2585,8 @@ final class WorkspaceTests: XCTestCase { } let deps: [MockDependency] = [ - .fileSystem(path: "./Foo", products: .specific(["Foo"])), + // FIXME: tomer + .fileSystem(path: "./Foo"/*), products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { graph, diagnostics in PackageGraphTester(graph) { result in @@ -2647,8 +2660,9 @@ final class WorkspaceTests: XCTestCase { identity: settings.identity, nameForTargetDependencyResolutionOnly: settings.nameForTargetDependencyResolutionOnly, location: settings.location, - requirement: .exact("1.5.0"), - productFilter: settings.productFilter + requirement: .exact("1.5.0")//, + // FIXME: tomer + //productFilter: settings.productFilter ) workspace.manifestLoader.manifests[fooKey] = Manifest( @@ -2745,11 +2759,12 @@ final class WorkspaceTests: XCTestCase { // Try resolving a bad graph. let deps: [MockDependency] = [ - .sourceControl(path: "./Bar", requirement: .exact("1.1.0"), products: .specific(["Bar"])), + // FIXME: tomer + .sourceControl(path: "./Bar", requirement: .exact("1.1.0")/*, products: .specific(["Bar"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { _, diagnostics in testDiagnostics(diagnostics) { result in - result.check(diagnostic: .contains("'Bar' 1.1.0"), severity: .error) + result.check(diagnostic: .contains("'bar' 1.1.0"), severity: .error) } } } @@ -2988,7 +3003,8 @@ final class WorkspaceTests: XCTestCase { // Override with local package and run update. let deps: [MockDependency] = [ - .fileSystem(path: "./Bar", products: .specific(["Bar"])), + // FIXME: tomer + .fileSystem(path: "./Bar"/*, products: .specific(["Bar"])*/), ] try workspace.checkUpdate(roots: ["Foo"], deps: deps) { diagnostics in XCTAssertNoDiagnostics(diagnostics) @@ -3076,7 +3092,8 @@ final class WorkspaceTests: XCTestCase { // without running swift package update. var deps: [MockDependency] = [ - .sourceControl(path: "./Foo", requirement: .branch("develop"), products: .specific(["Foo"])), + // FIXME: tomer + .sourceControl(path: "./Foo", requirement: .branch("develop")/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { graph, diagnostics in PackageGraphTester(graph) { result in @@ -3090,7 +3107,8 @@ final class WorkspaceTests: XCTestCase { } deps = [ - .sourceControl(path: "./Foo", requirement: .upToNextMajor(from: "1.0.0"), products: .specific(["Foo"])), + // FIXME: tomer + .sourceControl(path: "./Foo", requirement: .upToNextMajor(from: "1.0.0")/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { _, diagnostics in XCTAssertNoDiagnostics(diagnostics) @@ -3100,7 +3118,8 @@ final class WorkspaceTests: XCTestCase { } deps = [ - .sourceControl(path: "./Foo", requirement: .branch("develop"), products: .specific(["Foo"])), + // FIXME: tomer + .sourceControl(path: "./Foo", requirement: .branch("develop")/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { _, diagnostics in XCTAssertNoDiagnostics(diagnostics) @@ -3145,7 +3164,8 @@ final class WorkspaceTests: XCTestCase { // without running swift package update. var deps: [MockDependency] = [ - .fileSystem(path: "./Foo", products: .specific(["Foo"])), + // FIXME: tomer + .fileSystem(path: "./Foo"/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { graph, diagnostics in PackageGraphTester(graph) { result in @@ -3159,7 +3179,8 @@ final class WorkspaceTests: XCTestCase { } deps = [ - .sourceControl(path: "./Foo", requirement: .upToNextMajor(from: "1.0.0"), products: .specific(["Foo"])), + // FIXME: tomer + .sourceControl(path: "./Foo", requirement: .upToNextMajor(from: "1.0.0")/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { _, diagnostics in XCTAssertNoDiagnostics(diagnostics) @@ -3169,7 +3190,8 @@ final class WorkspaceTests: XCTestCase { } deps = [ - .fileSystem(path: "./Foo", products: .specific(["Foo"])), + // FIXME: tomer + .fileSystem(path: "./Foo"/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { _, diagnostics in XCTAssertNoDiagnostics(diagnostics) @@ -3225,7 +3247,8 @@ final class WorkspaceTests: XCTestCase { // different locations works correctly. var deps: [MockDependency] = [ - .fileSystem(path: "./Foo", products: .specific(["Foo"])), + // FIXME: tomer + .fileSystem(path: "./Foo"/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { graph, diagnostics in PackageGraphTester(graph) { result in @@ -3239,7 +3262,8 @@ final class WorkspaceTests: XCTestCase { } deps = [ - .fileSystem(path: "./Foo2", products: .specific(["Foo"])), + // FIXME: tomer + .fileSystem(path: "./Foo2"/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { _, diagnostics in XCTAssertNoDiagnostics(diagnostics) @@ -3295,7 +3319,8 @@ final class WorkspaceTests: XCTestCase { // different locations works correctly. var deps: [MockDependency] = [ - .fileSystem(path: "./Foo", products: .specific(["Foo"])), + // FIXME: tomer + .fileSystem(path: "./Foo"/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { graph, diagnostics in PackageGraphTester(graph) { result in @@ -3313,7 +3338,8 @@ final class WorkspaceTests: XCTestCase { } deps = [ - .fileSystem(path: "./Nested/Foo", products: .specific(["Foo"])), + // FIXME: tomer + .fileSystem(path: "./Nested/Foo"/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { _, diagnostics in XCTAssertNoDiagnostics(diagnostics) @@ -3359,7 +3385,8 @@ final class WorkspaceTests: XCTestCase { ) let deps: [MockDependency] = [ - .sourceControl(path: "./Foo", requirement: .upToNextMajor(from: "1.0.0"), products: .specific(["Foo"])), + // FIXME: tomer + .sourceControl(path: "./Foo", requirement: .upToNextMajor(from: "1.0.0")/*, products: .specific(["Foo"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { _, diagnostics in XCTAssertNoDiagnostics(diagnostics) @@ -3398,7 +3425,8 @@ final class WorkspaceTests: XCTestCase { ], products: [], dependencies: [ - .sourceControl(path: "./Foo", requirement: .upToNextMajor(from: "1.0.0"), products: .specific(["Foo"])), + // FIXME: tomer + .sourceControl(path: "./Foo", requirement: .upToNextMajor(from: "1.0.0")/*, products: .specific(["Foo"])*/), ], toolsVersion: pair.0 ), @@ -3518,7 +3546,8 @@ final class WorkspaceTests: XCTestCase { ) let deps: [MockDependency] = [ - .sourceControl(path: "./Bam", requirement: .upToNextMajor(from: "1.0.0"), products: .specific(["Bar"])), + // FIXME: tomer + .sourceControl(path: "./Bam", requirement: .upToNextMajor(from: "1.0.0")/*, products: .specific(["Bar"])*/), ] try workspace.checkPackageGraph(roots: ["Foo"], deps: deps) { graph, diagnostics in @@ -3622,7 +3651,8 @@ final class WorkspaceTests: XCTestCase { // dependencies. var deps: [MockDependency] = [ - .sourceControl(path: "./Bar", requirement: .exact("1.0.0"), products: .specific(["Bar"])), + // FIXME: tomer + .sourceControl(path: "./Bar", requirement: .exact("1.0.0")/*, products: .specific(["Bar"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { graph, diagnostics in PackageGraphTester(graph) { result in @@ -3646,7 +3676,8 @@ final class WorkspaceTests: XCTestCase { } deps = [ - .sourceControl(path: "./Bar", requirement: .exact("1.1.0"), products: .specific(["Bar"])), + // FIXME: tomer + .sourceControl(path: "./Bar", requirement: .exact("1.1.0")/*, products: .specific(["Bar"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { graph, diagnostics in PackageGraphTester(graph) { result in @@ -3712,7 +3743,8 @@ final class WorkspaceTests: XCTestCase { // Load the initial graph. let deps: [MockDependency] = [ - .sourceControl(path: "./Bar", requirement: .revision("develop"), products: .specific(["Bar"])), + // FIXME: tomer + .sourceControl(path: "./Bar", requirement: .revision("develop")/*, products: .specific(["Bar"])*/), ] try workspace.checkPackageGraph(roots: ["Root"], deps: deps) { _, diagnostics in XCTAssertNoDiagnostics(diagnostics) @@ -4008,7 +4040,8 @@ final class WorkspaceTests: XCTestCase { ) let deps: [MockDependency] = [ - .sourceControl(path: "./bazzz", requirement: .exact("1.0.0"), products: .specific(["Baz"])), + // FIXME: tomer + .sourceControl(path: "./bazzz", requirement: .exact("1.0.0")/*, products: .specific(["Baz"])*/), ] try workspace.checkPackageGraphFailure(roots: ["Overridden/bazzz-master"], deps: deps) { diagnostics in @@ -8276,7 +8309,7 @@ final class WorkspaceTests: XCTestCase { packageKind: PackageReference.Kind, packageLocation: String, version: Version?, - revision: String?, + //revision: String?, toolsVersion: ToolsVersion, identityResolver: IdentityResolver, fileSystem: FileSystem,