Skip to content

Commit 6d0f18e

Browse files
committed
Add new providedLibrary package reference kind
This kind of reference is going to be returned by package resolution if it detects that a provided library version matches all of the constraints. This makes it easier to handle provided libraries post-resolution instead of eliding them completely.
1 parent 6f12e54 commit 6d0f18e

File tree

16 files changed

+134
-6
lines changed

16 files changed

+134
-6
lines changed

Sources/Build/BuildPlan/BuildPlan.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ extension ResolvedPackage {
740740
switch self.underlying.manifest.packageKind {
741741
case .registry, .remoteSourceControl, .localSourceControl:
742742
return true
743-
case .root, .fileSystem:
743+
case .root, .fileSystem, .providedLibrary:
744744
return false
745745
}
746746
}

Sources/PackageGraph/ModulesGraph.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ extension PackageGraphError: CustomStringConvertible {
358358
switch $0.manifest.packageKind {
359359
case .root(let path),
360360
.fileSystem(let path),
361-
.localSourceControl(let path):
361+
.localSourceControl(let path),
362+
.providedLibrary(let path):
362363
description += " (at '\(path)')"
363364
case .remoteSourceControl(let url):
364365
description += " (from '\(url)')"

Sources/PackageGraph/Resolution/PubGrub/PubGrubDependencyResolver.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,7 @@ extension PackageRequirement {
897897
extension PackageReference {
898898
public func matchingPrebuiltLibrary(in availableLibraries: [LibraryMetadata]) -> LibraryMetadata? {
899899
switch self.kind {
900-
case .fileSystem, .localSourceControl, .root:
900+
case .fileSystem, .localSourceControl, .root, .providedLibrary:
901901
return nil // can never match a prebuilt library
902902
case .registry(let identity):
903903
if let registryIdentity = identity.registry {

Sources/PackageLoading/ManifestJSONParser.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ enum ManifestJSONParser {
8383
case .localSourceControl(let _packagePath):
8484
// we have a more accurate path than the virtual one
8585
packagePath = _packagePath
86-
case .root(let _packagePath), .fileSystem(let _packagePath):
86+
case .root(let _packagePath), .fileSystem(let _packagePath), .providedLibrary(let _packagePath):
8787
// we dont have a more accurate path, and they should be the same
8888
// asserting (debug only) to make sure refactoring is correct 11/2023
8989
assert(packagePath == _packagePath, "expecting package path '\(packagePath)' to be the same as '\(_packagePath)'")

Sources/PackageModel/IdentityResolver.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ public struct DefaultIdentityResolver: IdentityResolver {
4646
return try self.resolveIdentity(for: url)
4747
case .registry(let identity):
4848
return identity
49+
case .providedLibrary(let path):
50+
return try self.resolveIdentity(for: path)
4951
}
5052
}
5153

Sources/PackageModel/PackageReference.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ public struct PackageReference {
3434
/// A package from a registry.
3535
case registry(PackageIdentity)
3636

37+
/// A prebuilt library provided by a toolchain
38+
case providedLibrary(AbsolutePath)
39+
3740
// FIXME: we should not need this once we migrate off URLs
3841
//@available(*, deprecated)
3942
public var locationString: String {
@@ -49,6 +52,8 @@ public struct PackageReference {
4952
case .registry(let identity):
5053
// FIXME: this is a placeholder
5154
return identity.description
55+
case .providedLibrary(let path):
56+
return path.pathString
5257
}
5358
}
5459

@@ -70,6 +75,8 @@ public struct PackageReference {
7075
return "remoteSourceControl \(url)"
7176
case .registry(let identity):
7277
return "registry \(identity)"
78+
case .providedLibrary(let path):
79+
return "library \(path)"
7380
}
7481
}
7582

@@ -124,6 +131,8 @@ public struct PackageReference {
124131
case .registry(let identity):
125132
// FIXME: this is a placeholder
126133
self.deprecatedName = name ?? identity.description
134+
case .providedLibrary(let path):
135+
self.deprecatedName = name ?? PackageIdentityParser.computeDefaultName(fromPath: path)
127136
}
128137
}
129138

@@ -151,6 +160,10 @@ public struct PackageReference {
151160
public static func registry(identity: PackageIdentity) -> PackageReference {
152161
PackageReference(identity: identity, kind: .registry(identity))
153162
}
163+
164+
public static func library(identity: PackageIdentity, path: AbsolutePath) -> PackageReference {
165+
PackageReference(identity: identity, kind: .providedLibrary(path))
166+
}
154167
}
155168

156169
extension PackageReference: Equatable {
@@ -203,7 +216,7 @@ extension PackageReference: CustomStringConvertible {
203216

204217
extension PackageReference.Kind: Encodable {
205218
private enum CodingKeys: String, CodingKey {
206-
case root, fileSystem, localSourceControl, remoteSourceControl, registry
219+
case root, fileSystem, localSourceControl, remoteSourceControl, registry, providedLibrary
207220
}
208221

209222
public func encode(to encoder: Encoder) throws {
@@ -224,6 +237,9 @@ extension PackageReference.Kind: Encodable {
224237
case .registry:
225238
var unkeyedContainer = container.nestedUnkeyedContainer(forKey: .registry)
226239
try unkeyedContainer.encode(self.isRoot)
240+
case .providedLibrary(let path):
241+
var unkeyedContainer = container.nestedUnkeyedContainer(forKey: .providedLibrary)
242+
try unkeyedContainer.encode(path)
227243
}
228244
}
229245
}

Sources/SPMBuildCore/Plugins/PluginContextSerializer.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ internal struct PluginContextSerializer {
240240
return .repository(url: url.absoluteString, displayVersion: String(describing: package.manifest.version), scmRevision: String(describing: package.manifest.revision))
241241
case .registry(let identity):
242242
return .registry(identity: identity.description, displayVersion: String(describing: package.manifest.version))
243+
case .providedLibrary(_):
244+
throw InternalError("provided libraries are not supported in plugin context")
243245
}
244246
}
245247

Sources/SPMTestSupport/MockManifestLoader.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ extension ManifestLoader {
109109
packageIdentity = identity
110110
// FIXME: placeholder
111111
packageLocation = identity.description
112+
case .providedLibrary(let path):
113+
packageIdentity = try identityResolver.resolveIdentity(for: path)
114+
packageLocation = path.pathString
112115
}
113116
return try await self.load(
114117
manifestPath: manifestPath,
@@ -156,6 +159,9 @@ extension ManifestLoader {
156159
packageIdentity = identity
157160
// FIXME: placeholder
158161
packageLocation = identity.description
162+
case .providedLibrary(let path):
163+
packageIdentity = try identityResolver.resolveIdentity(for: path)
164+
packageLocation = path.pathString
159165
}
160166
return try await self.load(
161167
packagePath: packagePath,

Sources/SPMTestSupport/MockWorkspace.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,8 @@ extension PackageReference.Kind {
10411041
return "remoteSourceControl"
10421042
case .registry:
10431043
return "registry"
1044+
case .providedLibrary:
1045+
return "library"
10441046
}
10451047
}
10461048
}

Sources/Workspace/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ add_library(Workspace
1515
ManagedArtifact.swift
1616
ManagedDependency.swift
1717
PackageContainer/FileSystemPackageContainer.swift
18+
PackageContainer/ProvidedLibraryPackageContainer.swift
1819
PackageContainer/RegistryPackageContainer.swift
1920
PackageContainer/SourceControlPackageContainer.swift
2021
ResolvedFileWatcher.swift

Sources/Workspace/Diagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ extension Basics.Diagnostic {
185185
return "'\(identity.description)'"
186186
case .remoteSourceControl(let url):
187187
return "'\($0.identity)' from \(url)"
188-
case .localSourceControl(let path), .fileSystem(let path), .root(let path):
188+
case .localSourceControl(let path), .fileSystem(let path), .root(let path), .providedLibrary(let path):
189189
return "'\($0.identity)' at \(path)"
190190
}
191191
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2014-2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import Basics
14+
import Dispatch
15+
import PackageGraph
16+
import PackageLoading
17+
import PackageModel
18+
19+
import struct TSCUtility.Version
20+
21+
public struct ProvidedLibraryPackageContainer: PackageContainer {
22+
public let package: PackageReference
23+
24+
/// Observability scope to emit diagnostics
25+
private let observabilityScope: ObservabilityScope
26+
27+
public init(
28+
package: PackageReference,
29+
observabilityScope: ObservabilityScope
30+
) throws {
31+
switch package.kind {
32+
case .providedLibrary:
33+
break
34+
default:
35+
throw InternalError("invalid package type \(package.kind)")
36+
}
37+
self.package = package
38+
self.observabilityScope = observabilityScope.makeChildScope(
39+
description: "ProvidedLibraryPackageContainer",
40+
metadata: package.diagnosticsMetadata)
41+
}
42+
43+
public func isToolsVersionCompatible(at version: Version) -> Bool {
44+
true
45+
}
46+
47+
public func toolsVersion(for version: Version) throws -> ToolsVersion {
48+
.v6_0
49+
}
50+
51+
public func toolsVersionsAppropriateVersionsDescending() throws -> [Version] {
52+
return try versionsDescending()
53+
}
54+
55+
public func versionsAscending() throws -> [Version] {
56+
[] // TODO
57+
}
58+
59+
public func getDependencies(at version: Version, productFilter: ProductFilter) throws -> [PackageContainerConstraint] {
60+
[]
61+
}
62+
63+
public func getDependencies(at revision: String, productFilter: ProductFilter) throws -> [PackageContainerConstraint] {
64+
[]
65+
}
66+
67+
public func getUnversionedDependencies(productFilter: ProductFilter) throws -> [PackageContainerConstraint] {
68+
[]
69+
}
70+
71+
public func loadPackageReference(at boundVersion: BoundVersion) throws -> PackageReference {
72+
package
73+
}
74+
}

Sources/Workspace/Workspace+PackageContainer.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ extension Workspace: PackageContainerProvider {
9393
queue.async {
9494
completion(.success(container))
9595
}
96+
97+
case .providedLibrary:
98+
let container = try ProvidedLibraryPackageContainer(
99+
package: package,
100+
observabilityScope: observabilityScope)
101+
queue.async {
102+
completion(.success(container))
103+
}
96104
}
97105
} catch {
98106
queue.async {

Sources/Workspace/Workspace+State.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,9 @@ extension WorkspaceStateStorage {
440440
self.kind = .registry
441441
// FIXME: placeholder
442442
self.location = self.identity.description
443+
case .providedLibrary(let path):
444+
self.kind = .providedLibrary
445+
self.location = path.pathString
443446
}
444447
self.name = reference.deprecatedName
445448
}
@@ -450,6 +453,7 @@ extension WorkspaceStateStorage {
450453
case localSourceControl
451454
case remoteSourceControl
452455
case registry
456+
case providedLibrary
453457
}
454458
}
455459
}
@@ -492,6 +496,8 @@ extension PackageModel.PackageReference {
492496
kind = .remoteSourceControl(SourceControlURL(reference.location))
493497
case .registry:
494498
kind = .registry(identity)
499+
case .providedLibrary:
500+
kind = try .providedLibrary(.init(validating: reference.location))
495501
}
496502

497503
self.init(
@@ -766,6 +772,9 @@ extension WorkspaceStateStorage {
766772
self.kind = .registry
767773
// FIXME: placeholder
768774
self.location = self.identity.description
775+
case .providedLibrary(let path):
776+
self.kind = .providedLibrary
777+
self.location = path.pathString
769778
}
770779
self.name = reference.deprecatedName
771780
}
@@ -776,6 +785,7 @@ extension WorkspaceStateStorage {
776785
case localSourceControl
777786
case remoteSourceControl
778787
case registry
788+
case providedLibrary
779789
}
780790
}
781791
}
@@ -819,6 +829,8 @@ extension PackageModel.PackageReference {
819829
kind = .remoteSourceControl(SourceControlURL(reference.location))
820830
case .registry:
821831
kind = .registry(identity)
832+
case .providedLibrary:
833+
kind = try .providedLibrary(.init(validating: reference.location))
822834
}
823835

824836
self.init(

Sources/Workspace/Workspace.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,8 @@ extension Workspace {
12691269
try self.removeRepository(dependency: dependencyToRemove)
12701270
case .registry:
12711271
try self.removeRegistryArchive(for: dependencyToRemove)
1272+
case .providedLibrary:
1273+
break // NOOP
12721274
}
12731275

12741276
// Save the state.

Tests/PackageLoadingTests/PDLoadingTests.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ class PackageDescriptionLoadingTests: XCTestCase, ManifestLoaderDelegate {
9797
packagePath = path
9898
case .remoteSourceControl, .registry:
9999
packagePath = .root
100+
case .providedLibrary(let path):
101+
packagePath = path
100102
}
101103

102104
let toolsVersion = toolsVersion

0 commit comments

Comments
 (0)