Skip to content

Commit c7eef31

Browse files
committed
moar
1 parent ce91eea commit c7eef31

File tree

17 files changed

+282
-184
lines changed

17 files changed

+282
-184
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/Commands/SwiftPackageTool.swift

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,16 @@ extension SwiftPackageTool {
170170
let workspace = try swiftTool.getActiveWorkspace()
171171
let root = try swiftTool.getWorkspaceRoot()
172172

173-
let manifests = try temp_await {
173+
let rootManifests = try temp_await {
174174
workspace.loadRootManifests(packages: root.packages, diagnostics: swiftTool.diagnostics, completion: $0)
175175
}
176-
guard let manifest = manifests.first else { return }
177-
// FIXME: use PackageIdentity.root?
178-
let packageIdentity = workspace.identityResolver.resolveIdentity(for: manifest.packageLocation)
176+
guard let rootManifest = rootManifests.first else {
177+
throw StringError("invalid manifests at \(root.packages)")
178+
}
179179

180180
let builder = PackageBuilder(
181-
identity: packageIdentity,
182-
manifest: manifest,
181+
identity: .root(name: rootManifest.name),
182+
manifest: rootManifest,
183183
productFilter: .everything,
184184
path: try swiftTool.getPackageRoot(),
185185
xcTestMinimumDeploymentTargets: MinimumDeploymentTarget.default.xcTestMinimumDeploymentTargets,
@@ -240,15 +240,16 @@ extension SwiftPackageTool {
240240
// Get the root package.
241241
let workspace = try swiftTool.getActiveWorkspace()
242242
let root = try swiftTool.getWorkspaceRoot()
243-
let manifest = try temp_await {
243+
let rootManifests = try temp_await {
244244
workspace.loadRootManifests(packages: root.packages, diagnostics: swiftTool.diagnostics, completion: $0)
245-
}[0]
246-
// FIXME: use PackageIdentity.root?
247-
let packageIdentity = workspace.identityResolver.resolveIdentity(for: manifest.packageLocation)
245+
}
246+
guard let rootManifest = rootManifests.first else {
247+
throw StringError("invalid manifests at \(root.packages)")
248+
}
248249

249250
let builder = PackageBuilder(
250-
identity: packageIdentity,
251-
manifest: manifest,
251+
identity: .root(name: rootManifest.name),
252+
manifest: rootManifest,
252253
productFilter: .everything,
253254
path: try swiftTool.getPackageRoot(),
254255
xcTestMinimumDeploymentTargets: [:], // Minimum deployment target does not matter for this operation.
@@ -372,15 +373,17 @@ extension SwiftPackageTool {
372373
let workspace = try swiftTool.getActiveWorkspace()
373374
let root = try swiftTool.getWorkspaceRoot()
374375

375-
let manifests = try temp_await {
376+
let rootManifests = try temp_await {
376377
workspace.loadRootManifests(packages: root.packages, diagnostics: swiftTool.diagnostics, completion: $0)
377378
}
378-
guard let manifest = manifests.first else { return }
379+
guard let rootManifest = rootManifests.first else {
380+
throw StringError("invalid manifests at \(root.packages)")
381+
}
379382

380383
let encoder = JSONEncoder.makeWithDefaults()
381384
encoder.userInfo[Manifest.dumpPackageKey] = true
382385

383-
let jsonData = try encoder.encode(manifest)
386+
let jsonData = try encoder.encode(rootManifest)
384387
let jsonString = String(data: jsonData, encoding: .utf8)!
385388
print(jsonString)
386389
}

Sources/Commands/SwiftTestTool.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,12 @@ public struct SwiftTestTool: SwiftCommand {
224224
case .codeCovPath:
225225
let workspace = try swiftTool.getActiveWorkspace()
226226
let root = try swiftTool.getWorkspaceRoot()
227-
let rootManifest = try temp_await {
227+
let rootManifests = try temp_await {
228228
workspace.loadRootManifests(packages: root.packages, diagnostics: swiftTool.diagnostics, completion: $0)
229-
}[0]
229+
}
230+
guard let rootManifest = rootManifests.first else {
231+
throw StringError("invalid manifests at \(root.packages)")
232+
}
230233
let buildParameters = try swiftTool.buildParametersForTest()
231234
print(codeCovAsJSONPath(buildParameters: buildParameters, packageName: rootManifest.name))
232235

@@ -354,9 +357,12 @@ public struct SwiftTestTool: SwiftCommand {
354357
private func processCodeCoverage(_ testProducts: [BuiltTestProduct], swiftTool: SwiftTool) throws {
355358
let workspace = try swiftTool.getActiveWorkspace()
356359
let root = try swiftTool.getWorkspaceRoot()
357-
let rootManifest = try temp_await {
360+
let rootManifests = try temp_await {
358361
workspace.loadRootManifests(packages: root.packages, diagnostics: swiftTool.diagnostics, completion: $0)
359-
}[0]
362+
}
363+
guard let rootManifest = rootManifests.first else {
364+
throw StringError("invalid manifests at \(root.packages)")
365+
}
360366

361367
// Merge all the profraw files to produce a single profdata file.
362368
try mergeCodeCovRawDataFiles(swiftTool: swiftTool)

Sources/PackageGraph/PackageGraph+Loading.swift

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,12 @@ extension PackageGraph {
3535
) throws -> PackageGraph {
3636

3737
// Create a map of the manifests, keyed by their identity.
38-
//
39-
// FIXME: For now, we have to compute the identity of dependencies from
40-
// the URL but that shouldn't be needed after <rdar://problem/33693433>
41-
// Ensure that identity and package name are the same once we have an
42-
// API to specify identity in the manifest file
43-
// FIXME: use PackageIdentity.root?
44-
let manifestMapSequence = (root.manifests + externalManifests).map({ (identityResolver.resolveIdentity(for: $0.packageLocation), $0) })
45-
let manifestMap = Dictionary(uniqueKeysWithValues: manifestMapSequence)
38+
let rootManifestsMap = root.packages.mapValues { $0.manifest }
39+
let externalManifestsMap = externalManifests.map{ (identityResolver.resolveIdentity(for: $0.packageLocation), $0) }
40+
let manifestMap = rootManifestsMap.merging(externalManifestsMap, uniquingKeysWith: { lhs, rhs in
41+
return rhs // 👀 this was not possible before (the dictionary creation would crash), is preferring external correct?
42+
})
43+
4644
let successors: (GraphLoadingNode) -> [GraphLoadingNode] = { node in
4745
node.requiredDependencies().compactMap{ dependency in
4846
return manifestMap[dependency.identity].map { manifest in
@@ -52,14 +50,14 @@ extension PackageGraph {
5250
}
5351

5452
// Construct the root manifest and root dependencies set.
55-
let rootManifestSet = Set(root.manifests)
53+
let rootManifestSet = Set(root.manifests.values)
5654
let rootDependencies = Set(root.dependencies.compactMap{
5755
manifestMap[$0.identity]
5856
})
59-
let rootManifestNodes = root.manifests.map {
57+
let rootManifestNodes = root.packages.map { identity, package in
6058
// FIXME: use PackageIdentity.root?
61-
GraphLoadingNode(identity: identityResolver.resolveIdentity(for: $0.packageLocation),
62-
manifest: $0,
59+
GraphLoadingNode(identity: identity,
60+
manifest: package.manifest,
6361
productFilter: .everything)
6462
}
6563
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/PackageGraph/ResolvedPackage.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public final class ResolvedPackage: ObjectIdentifierProtocol {
3434
}
3535

3636
/// The name of the package as entered in the manifest.
37-
@available(*, deprecated, message: "use identity instead")
37+
/// This should rarely be used beyond presentation purposes
3838
public var manifestName: String {
3939
return self.underlyingPackage.manifestName
4040
}

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.basename == Manifest.filename ? path.parentDirectory : path
221+
let packageIdentity = identityResolver.resolveIdentity(for: packageLocation)
222+
loader.load(
223+
at: path,
224+
packageIdentity: packageIdentity,
225+
packageKind: .root,
226+
packageLocation: packageLocation.pathString,
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/PackageModel/Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public final class Package: ObjectIdentifierProtocol, Encodable {
5959
}
6060

6161
/// The name of the package as entered in the manifest.
62-
@available(*, deprecated, message: "use identity instead")
62+
/// This should rarely be used beyond presentation purposes
6363
public var manifestName: String {
6464
return manifest.name
6565
}

0 commit comments

Comments
 (0)