Skip to content

Commit 6f8717c

Browse files
committed
moar
1 parent f878137 commit 6f8717c

File tree

11 files changed

+222
-116
lines changed

11 files changed

+222
-116
lines changed

Examples/package-info/Sources/package-info/main.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ let packagePath = localFileSystem.currentWorkingDirectory!
3232
// Each takes longer to load than the level above it, but provides more detail.
3333
let diagnostics = DiagnosticsEngine()
3434
let identityResolver = DefaultIdentityResolver()
35-
let manifest = try tsc_await { ManifestLoader.loadManifest(at: packagePath, kind: .local, swiftCompiler: swiftCompiler, swiftCompilerFlags: [], identityResolver: identityResolver, on: .global(), completion: $0) }
36-
let loadedPackage = try tsc_await { PackageBuilder.loadPackage(at: packagePath, swiftCompiler: swiftCompiler, swiftCompilerFlags: [], identityResolver: identityResolver, diagnostics: diagnostics, on: .global(), completion: $0) }
37-
let graph = try Workspace.loadGraph(packagePath: packagePath, swiftCompiler: swiftCompiler, swiftCompilerFlags: [], identityResolver: identityResolver, diagnostics: diagnostics)
35+
let manifest = try tsc_await { ManifestLoader.loadRootManifest(at: packagePath, swiftCompiler: swiftCompiler, swiftCompilerFlags: [], identityResolver: identityResolver, on: .global(), completion: $0) }
36+
let loadedPackage = try tsc_await { PackageBuilder.loadRootPackage(at: packagePath, swiftCompiler: swiftCompiler, swiftCompilerFlags: [], identityResolver: identityResolver, diagnostics: diagnostics, on: .global(), completion: $0) }
37+
let graph = try Workspace.loadRootGraph(at: packagePath, swiftCompiler: swiftCompiler, swiftCompilerFlags: [], identityResolver: identityResolver, diagnostics: diagnostics)
3838

3939
// EXAMPLES
4040
// ========

Sources/PackageGraph/PackageGraph+Loading.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,16 @@ extension PackageGraph {
4141
// Ensure that identity and package name are the same once we have an
4242
// API to specify identity in the manifest file
4343
// FIXME: use PackageIdentity.root?
44-
let manifestMapSequence = (root.manifests + externalManifests).map({ (identityResolver.resolveIdentity(for: $0.packageLocation), $0) })
45-
let manifestMap = Dictionary(uniqueKeysWithValues: manifestMapSequence)
44+
45+
46+
//let manifestMapSequence = (root.manifests + externalManifests).map({ (identityResolver.resolveIdentity(for: $0.packageLocation), $0) })
47+
//let manifestMap = Dictionary(uniqueKeysWithValues: manifestMapSequence)
48+
let rootManifestsMap = root.packages.mapValues { $0.manifest }
49+
let externalManifestsMap = externalManifests.map{ (identityResolver.resolveIdentity(for: $0.packageLocation), $0) }
50+
let manifestMap = rootManifestsMap.merging(externalManifestsMap, uniquingKeysWith: { lhs, rhs in
51+
return rhs // 👀 this was not possible before (the dictionary creation would crash), is preferring external correct?
52+
})
53+
4654
let successors: (GraphLoadingNode) -> [GraphLoadingNode] = { node in
4755
node.requiredDependencies().compactMap{ dependency in
4856
return manifestMap[dependency.identity].map { manifest in
@@ -52,14 +60,14 @@ extension PackageGraph {
5260
}
5361

5462
// Construct the root manifest and root dependencies set.
55-
let rootManifestSet = Set(root.manifests)
63+
let rootManifestSet = Set(root.manifests.values)
5664
let rootDependencies = Set(root.dependencies.compactMap{
5765
manifestMap[$0.identity]
5866
})
59-
let rootManifestNodes = root.manifests.map {
67+
let rootManifestNodes = root.packages.map { identity, package in
6068
// FIXME: use PackageIdentity.root?
61-
GraphLoadingNode(identity: identityResolver.resolveIdentity(for: $0.packageLocation),
62-
manifest: $0,
69+
GraphLoadingNode(identity: identity,
70+
manifest: package.manifest,
6371
productFilter: .everything)
6472
}
6573
let rootDependencyNodes = root.dependencies.lazy.compactMap { (dependency: PackageDependencyDescription) -> GraphLoadingNode? in

Sources/PackageGraph/PackageGraphRoot.swift

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11-
import TSCBasic
12-
import TSCUtility
13-
11+
import Basics
1412
import PackageModel
1513
import SourceControl
14+
import TSCBasic
15+
import TSCUtility
1616

1717
/// Represents the input to the package graph root.
1818
public struct PackageGraphRootInput {
@@ -33,23 +33,33 @@ public struct PackageGraphRootInput {
3333
/// Represents the inputs to the package graph.
3434
public struct PackageGraphRoot {
3535

36-
/// The list of root manifests.
37-
public let manifests: [Manifest]
36+
/// The root packages.
37+
public let packages: [PackageIdentity: (manifest: Manifest, packageReference: PackageReference)]
38+
39+
/// The root manifests.
40+
public var manifests: [PackageIdentity: Manifest] {
41+
return self.packages.mapValues { $0.manifest }
42+
}
3843

3944
/// The root package references.
40-
public let packageRefs: [PackageReference]
45+
public var packageReferences: [PackageReference] {
46+
return self.packages.values.map { $0.packageReference }
47+
}
4148

4249
/// The top level dependencies.
4350
public let dependencies: [PackageDependencyDescription]
4451

4552
/// Create a package graph root.
46-
public init(input: PackageGraphRootInput, manifests: [Manifest], explicitProduct: String? = nil) {
47-
// TODO: this does not use the identity resolver which is probably fine since its the root packages
48-
self.packageRefs = zip(input.packages, manifests).map { (path, manifest) in
49-
let identity = PackageIdentity(url: manifest.packageLocation)
50-
return .root(identity: identity, path: path)
51-
}
52-
self.manifests = manifests
53+
public init(input: PackageGraphRootInput, manifests: [Manifest], explicitProduct: String? = nil) throws {
54+
self.packages = try input.packages.reduce(into: .init(), { partial, inputPath in
55+
let manifestPath = inputPath.basename == Manifest.filename ? inputPath : inputPath.appending(component: Manifest.filename)
56+
let packagePath = manifestPath.parentDirectory
57+
guard let manifest = (manifests.first{ $0.path == manifestPath}) else {
58+
throw InternalError("manifest for \(inputPath) not found")
59+
}
60+
let identity = PackageIdentity(path: packagePath) // this does not use the identity resolver which is fine since these are the root packages
61+
partial[identity] = (manifest, .root(identity: identity, path: packagePath))
62+
})
5363

5464
// FIXME: Deprecate special casing once the manifest supports declaring used executable products.
5565
// Special casing explicit products like this is necessary to pass the test suite and satisfy backwards compatibility.
@@ -70,7 +80,7 @@ public struct PackageGraphRoot {
7080

7181
/// Returns the constraints imposed by root manifests + dependencies.
7282
public func constraints() -> [PackageContainerConstraint] {
73-
let constraints = packageRefs.map{
83+
let constraints = self.packageReferences.map {
7484
PackageContainerConstraint(package: $0, requirement: .unversioned, products: .everything)
7585
}
7686
return constraints + dependencies.map{

Sources/PackageLoading/ManifestLoader.swift

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,8 @@ public final class ManifestLoader: ManifestLoaderProtocol {
157157
self.operationQueue.maxConcurrentOperationCount = Concurrency.maxOperations
158158
}
159159

160-
/// Loads a manifest from a package repository using the resources associated with a particular `swiftc` executable.
161-
///
162-
/// - Parameters:
163-
/// - at: The absolute path of the package root.
164-
/// - kind: The kind of package the manifest is from.
165-
/// - swiftCompiler: The absolute path of a `swiftc` executable.
166-
/// Its associated resources will be used by the loader.
167-
// FIXME: take identity?
160+
// deprecated 3/21, remove once clients migrated over
161+
@available(*, deprecated, message: "use loadRootManifest instead")
168162
public static func loadManifest(
169163
at path: AbsolutePath,
170164
kind: PackageReference.Kind,
@@ -200,6 +194,51 @@ public final class ManifestLoader: ManifestLoaderProtocol {
200194
}
201195
}
202196

197+
/// Loads a root manifest from a path using the resources associated with a particular `swiftc` executable.
198+
///
199+
/// - Parameters:
200+
/// - at: The absolute path of the package root.
201+
/// - swiftCompiler: The absolute path of a `swiftc` executable. Its associated resources will be used by the loader.
202+
/// - identityResolver: A helper to resolve identities based on configuration
203+
/// - diagnostics: Optional. The diagnostics engine.
204+
/// - on: The dispatch queue to perform asynchronous operations on.
205+
/// - completion: The completion handler .
206+
public static func loadRootManifest(
207+
at path: AbsolutePath,
208+
swiftCompiler: AbsolutePath,
209+
swiftCompilerFlags: [String],
210+
identityResolver: IdentityResolver,
211+
diagnostics: DiagnosticsEngine? = nil,
212+
on queue: DispatchQueue,
213+
completion: @escaping (Result<Manifest, Error>) -> Void
214+
) {
215+
do {
216+
let fileSystem = localFileSystem
217+
let resources = try UserManifestResources(swiftCompiler: swiftCompiler, swiftCompilerFlags: swiftCompilerFlags)
218+
let loader = ManifestLoader(manifestResources: resources)
219+
let toolsVersion = try ToolsVersionLoader().load(at: path, fileSystem: fileSystem)
220+
let packageLocation = path.pathString
221+
let packageIdentity = identityResolver.resolveIdentity(for: packageLocation)
222+
loader.load(
223+
at: path,
224+
packageIdentity: packageIdentity,
225+
packageKind: .root,
226+
packageLocation: packageLocation,
227+
version: nil,
228+
revision: nil,
229+
toolsVersion: toolsVersion,
230+
identityResolver: identityResolver,
231+
fileSystem: fileSystem,
232+
diagnostics: diagnostics,
233+
on: queue,
234+
completion: completion
235+
)
236+
} catch {
237+
return completion(.failure(error))
238+
}
239+
}
240+
241+
// deprecated 3/21, remove once clients migrated over
203242
@available(*, deprecated, message: "use load(at: packageIdentity:, ...) variant instead")
204243
public func load(
205244
at path: AbsolutePath,
@@ -262,16 +301,6 @@ public final class ManifestLoader: ManifestLoaderProtocol {
262301
}
263302
}
264303

265-
/// Create a manifest by loading a specific manifest file from the given `path`.
266-
///
267-
/// - Parameters:
268-
/// - at: The path to the manifest file (or a package root).
269-
/// - packageIdentity: The identity of package the manifest is from.
270-
/// - packageKind: The kind of package the manifest is from.
271-
/// - packageLocation: The location the manifest was loaded from.
272-
/// - version: The version the manifest is from, if known.
273-
/// - revision: The revision the manifest is from, if known.
274-
/// - fileSystem: If given, the file system to load from (otherwise load from the local file system).
275304
private func loadFile(
276305
at path: AbsolutePath,
277306
packageIdentity: PackageIdentity,

Sources/PackageLoading/PackageBuilder.swift

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -298,14 +298,8 @@ public final class PackageBuilder {
298298
self.warnAboutImplicitExecutableTargets = warnAboutImplicitExecutableTargets
299299
}
300300

301-
/// Loads a package from a package repository using the resources associated with a particular `swiftc` executable.
302-
///
303-
/// - Parameters:
304-
/// - path: The absolute path of the package root.
305-
/// - swiftCompiler: The absolute path of a `swiftc` executable.
306-
/// Its associated resources will be used by the loader.
307-
/// - kind: The kind of package.
308-
// FIXME: use PackageIdentity.root? tae identity?
301+
// deprecated 3/21, remove once clients migrated over
302+
@available(*, deprecated, message: "use loadRootPackage instead")
309303
public static func loadPackage(
310304
at path: AbsolutePath,
311305
kind: PackageReference.Kind = .root,
@@ -339,6 +333,46 @@ public final class PackageBuilder {
339333
}
340334
}
341335

336+
/// Loads a root package from a path using the resources associated with a particular `swiftc` executable.
337+
///
338+
/// - Parameters:
339+
/// - at: The absolute path of the package root.
340+
/// - swiftCompiler: The absolute path of a `swiftc` executable. Its associated resources will be used by the loader.
341+
/// - identityResolver: A helper to resolve identities based on configuration
342+
/// - diagnostics: Optional. The diagnostics engine.
343+
/// - on: The dispatch queue to perform asynchronous operations on.
344+
/// - completion: The completion handler .
345+
public static func loadRootPackage(
346+
at path: AbsolutePath,
347+
swiftCompiler: AbsolutePath,
348+
swiftCompilerFlags: [String],
349+
xcTestMinimumDeploymentTargets: [PackageModel.Platform:PlatformVersion] = MinimumDeploymentTarget.default.xcTestMinimumDeploymentTargets,
350+
identityResolver: IdentityResolver,
351+
diagnostics: DiagnosticsEngine,
352+
on queue: DispatchQueue,
353+
completion: @escaping (Result<Package, Error>) -> Void
354+
) {
355+
ManifestLoader.loadRootManifest(at: path,
356+
swiftCompiler: swiftCompiler,
357+
swiftCompilerFlags: swiftCompilerFlags,
358+
identityResolver: identityResolver,
359+
diagnostics: diagnostics,
360+
on: queue) { result in
361+
let result = result.tryMap { manifest -> Package in
362+
let identity = identityResolver.resolveIdentity(for: manifest.packageLocation)
363+
let builder = PackageBuilder(
364+
identity: identity,
365+
manifest: manifest,
366+
productFilter: .everything,
367+
path: path,
368+
xcTestMinimumDeploymentTargets: xcTestMinimumDeploymentTargets,
369+
diagnostics: diagnostics)
370+
return try builder.construct()
371+
}
372+
completion(result)
373+
}
374+
}
375+
342376
/// Build a new package following the conventions.
343377
public func construct() throws -> Package {
344378
let targets = try self.constructTargets()

Sources/SPMTestSupport/MockWorkspace.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ public final class MockWorkspace {
355355

356356
let rootInput = PackageGraphRootInput(packages: rootPaths(for: roots.map { $0.name }), dependencies: [])
357357
let rootManifests = try temp_await { workspace.loadRootManifests(packages: rootInput.packages, diagnostics: diagnostics, completion: $0) }
358-
let root = PackageGraphRoot(input: rootInput, manifests: rootManifests)
358+
let root = try PackageGraphRoot(input: rootInput, manifests: rootManifests)
359359

360360
let dependencyManifests = try workspace.loadDependencyManifests(root: root, diagnostics: diagnostics)
361361

@@ -508,7 +508,7 @@ public final class MockWorkspace {
508508
packages: rootPaths(for: roots), dependencies: dependencies
509509
)
510510
let rootManifests = try tsc_await { workspace.loadRootManifests(packages: rootInput.packages, diagnostics: diagnostics, completion: $0) }
511-
let graphRoot = PackageGraphRoot(input: rootInput, manifests: rootManifests)
511+
let graphRoot = try PackageGraphRoot(input: rootInput, manifests: rootManifests)
512512
let manifests = try workspace.loadDependencyManifests(root: graphRoot, diagnostics: diagnostics)
513513
result(manifests, diagnostics)
514514
}

Sources/SPMTestSupport/misc.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ public func loadPackageGraph(
233233
let externalManifests = manifests.filter { $0.packageKind != .root }
234234
let packages = rootManifests.map { $0.path }
235235
let input = PackageGraphRootInput(packages: packages)
236-
let graphRoot = PackageGraphRoot(input: input, manifests: rootManifests, explicitProduct: explicitProduct)
236+
let graphRoot = try PackageGraphRoot(input: input, manifests: rootManifests, explicitProduct: explicitProduct)
237237

238238
return try PackageGraph.load(
239239
root: graphRoot,

Sources/Workspace/ResolverPrecomputationProvider.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,10 @@ struct ResolverPrecomputationProvider: PackageContainerProvider {
7676
}
7777

7878
// Continue searching from the Workspace's root manifests.
79-
// FIXME: We might want to use a dictionary for faster lookups.
80-
if let index = self.dependencyManifests.root.packageRefs.firstIndex(of: package) {
79+
if let rootPackage = self.dependencyManifests.root.packages[package.identity] {
8180
let container = LocalPackageContainer(
8281
package: package,
83-
manifest: self.dependencyManifests.root.manifests[index],
82+
manifest: rootPackage.manifest,
8483
dependency: nil,
8584
identityResolver: self.identityResolver,
8685
currentToolsVersion: self.currentToolsVersion

0 commit comments

Comments
 (0)