Skip to content

Commit 5aa4835

Browse files
committed
Augment ManagedDependency to handle provided libraries
1 parent b88cd88 commit 5aa4835

8 files changed

+88
-8
lines changed

Sources/SPMBuildCore/Plugins/PluginContextSerializer.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ 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(_):
243+
case .providedLibrary(_, _):
244244
throw InternalError("provided libraries are not supported in plugin context")
245245
}
246246
}

Sources/Workspace/ManagedDependency.swift

+20
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ extension Workspace {
3434
/// The dependency is downloaded from a registry.
3535
case registryDownload(version: Version)
3636

37+
/// The dependency is part of the toolchain in a binary form.
38+
case providedLibrary(at: AbsolutePath, version: Version)
39+
3740
/// The dependency is in edited state.
3841
///
3942
/// If the path is non-nil, the dependency is managed by a user and is
@@ -51,6 +54,8 @@ extension Workspace {
5154
return "sourceControlCheckout (\(checkoutState))"
5255
case .registryDownload(let version):
5356
return "registryDownload (\(version))"
57+
case .providedLibrary(let path, let version):
58+
return "library (\(path) @ \(version)"
5459
case .edited:
5560
return "edited"
5661
case .custom:
@@ -146,6 +151,21 @@ extension Workspace {
146151
)
147152
}
148153

154+
public static func providedLibrary(
155+
packageRef: PackageReference,
156+
version: Version
157+
) throws -> ManagedDependency {
158+
guard case .providedLibrary(_, let path) = packageRef.kind else {
159+
throw InternalError("invalid package type: \(packageRef.kind)")
160+
}
161+
162+
return ManagedDependency(
163+
packageRef: packageRef,
164+
state: .providedLibrary(at: path, version: version),
165+
subpath: try RelativePath(validating: packageRef.identity.description)
166+
)
167+
}
168+
149169
/// Create an edited dependency
150170
public static func edited(
151171
packageRef: PackageReference,

Sources/Workspace/Workspace+Dependencies.swift

+21-3
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ extension Workspace {
430430
return !pin.state.equals(checkoutState)
431431
case .registryDownload(let version):
432432
return !pin.state.equals(version)
433-
case .edited, .fileSystem, .custom:
433+
case .edited, .fileSystem, .providedLibrary, .custom:
434434
return true
435435
}
436436
}
@@ -781,6 +781,19 @@ extension Workspace {
781781
state: .custom(version: version, path: path),
782782
subpath: RelativePath(validating: "")
783783
)
784+
self.state.dependencies.add(dependency)
785+
try self.state.save()
786+
return path
787+
} else if let libraryContainer = container as? ProvidedLibraryPackageContainer {
788+
guard case .providedLibrary(_, let path) = libraryContainer.package.kind else {
789+
throw InternalError("invalid container for \(package.identity) of type \(package.kind)")
790+
}
791+
792+
let dependency: ManagedDependency = try .providedLibrary(
793+
packageRef: libraryContainer.package,
794+
version: version
795+
)
796+
784797
self.state.dependencies.add(dependency)
785798
try self.state.save()
786799
return path
@@ -1033,6 +1046,8 @@ extension Workspace {
10331046
packageStateChanges[binding.package.identity] = (binding.package, .updated(newState))
10341047
case .registryDownload:
10351048
throw InternalError("Unexpected unversioned binding for downloaded dependency")
1049+
case .providedLibrary:
1050+
throw InternalError("Unexpected unversioned binding for library dependency")
10361051
case .custom:
10371052
throw InternalError("Unexpected unversioned binding for custom dependency")
10381053
}
@@ -1103,9 +1118,12 @@ extension Workspace {
11031118
case .version(let version):
11041119
let stateChange: PackageStateChange
11051120
switch currentDependency?.state {
1106-
case .sourceControlCheckout(.version(version, _)), .registryDownload(version), .custom(version, _):
1121+
case .sourceControlCheckout(.version(version, _)),
1122+
.registryDownload(version),
1123+
.providedLibrary(_, version: version),
1124+
.custom(version, _):
11071125
stateChange = .unchanged
1108-
case .edited, .fileSystem, .sourceControlCheckout, .registryDownload, .custom:
1126+
case .edited, .fileSystem, .sourceControlCheckout, .registryDownload, .providedLibrary, .custom:
11091127
stateChange = .updated(.init(requirement: .version(version), products: binding.products))
11101128
case nil:
11111129
stateChange = .added(.init(requirement: .version(version), products: binding.products))

Sources/Workspace/Workspace+Editing.swift

+3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ extension Workspace {
5252
case .registryDownload:
5353
observabilityScope.emit(error: "registry dependency '\(dependency.packageRef.identity)' can't be edited")
5454
return
55+
case .providedLibrary:
56+
observabilityScope.emit(error: "library dependency '\(dependency.packageRef.identity)' can't be edited")
57+
return
5558
case .custom:
5659
observabilityScope.emit(error: "custom dependency '\(dependency.packageRef.identity)' can't be edited")
5760
return

Sources/Workspace/Workspace+Manifests.swift

+12-3
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ extension Workspace {
151151
result.insert(packageRef)
152152
}
153153

154-
case .registryDownload, .edited, .custom:
154+
case .registryDownload, .edited, .providedLibrary, .custom:
155155
continue
156156
case .fileSystem:
157157
result.insert(dependency.packageRef)
@@ -343,7 +343,7 @@ extension Workspace {
343343
products: productFilter
344344
)
345345
allConstraints.append(constraint)
346-
case .sourceControlCheckout, .registryDownload, .fileSystem, .custom:
346+
case .sourceControlCheckout, .registryDownload, .fileSystem, .providedLibrary, .custom:
347347
break
348348
}
349349
allConstraints += try externalManifest.dependencyConstraints(productFilter: productFilter)
@@ -358,7 +358,7 @@ extension Workspace {
358358

359359
for (_, managedDependency, productFilter, _) in dependencies {
360360
switch managedDependency.state {
361-
case .sourceControlCheckout, .registryDownload, .fileSystem, .custom: continue
361+
case .sourceControlCheckout, .registryDownload, .fileSystem, .providedLibrary, .custom: continue
362362
case .edited: break
363363
}
364364
// FIXME: We shouldn't need to construct a new package reference object here.
@@ -394,6 +394,8 @@ extension Workspace {
394394
return path ?? self.location.editSubdirectory(for: dependency)
395395
case .fileSystem(let path):
396396
return path
397+
case .providedLibrary(let path, _):
398+
return path
397399
case .custom(_, let path):
398400
return path
399401
}
@@ -684,6 +686,9 @@ extension Workspace {
684686
case .registryDownload(let downloadedVersion):
685687
packageKind = managedDependency.packageRef.kind
686688
packageVersion = downloadedVersion
689+
case .providedLibrary(_, let version):
690+
packageKind = managedDependency.packageRef.kind
691+
packageVersion = version
687692
case .custom(let availableVersion, _):
688693
packageKind = managedDependency.packageRef.kind
689694
packageVersion = availableVersion
@@ -897,6 +902,10 @@ extension Workspace {
897902
observabilityScope
898903
.emit(.editedDependencyMissing(packageName: dependency.packageRef.identity.description))
899904

905+
case .providedLibrary(_, version: _):
906+
// TODO: If the dependency is not available we can turn it into a source control dependency
907+
break
908+
900909
case .fileSystem:
901910
self.state.dependencies.remove(dependency.packageRef.identity)
902911
try self.state.save()

Sources/Workspace/Workspace+Pinning.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ extension PinsStore.Pin {
145145
packageRef: dependency.packageRef,
146146
state: .version(version, revision: .none)
147147
)
148-
case .edited, .fileSystem, .custom:
148+
case .edited, .fileSystem, .providedLibrary, .custom:
149149
// NOOP
150150
return nil
151151
}

Sources/Workspace/Workspace+State.swift

+26
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,15 @@ extension WorkspaceStateStorage {
256256
let version = try container.decode(String.self, forKey: .version)
257257
return try self
258258
.init(underlying: .registryDownload(version: TSCUtility.Version(versionString: version)))
259+
case "providedLibrary":
260+
let path = try container.decode(AbsolutePath.self, forKey: .path)
261+
let version = try container.decode(String.self, forKey: .version)
262+
return try self.init(
263+
underlying: .providedLibrary(
264+
at: path,
265+
version: TSCUtility.Version(versionString: version)
266+
)
267+
)
259268
case "edited":
260269
let path = try container.decode(AbsolutePath?.self, forKey: .path)
261270
return try self.init(underlying: .edited(
@@ -286,6 +295,10 @@ extension WorkspaceStateStorage {
286295
case .registryDownload(let version):
287296
try container.encode("registryDownload", forKey: .name)
288297
try container.encode(version, forKey: .version)
298+
case .providedLibrary(let path, let version):
299+
try container.encode("providedLibrary", forKey: .name)
300+
try container.encode(path, forKey: .path)
301+
try container.encode(version, forKey: .version)
289302
case .edited(_, let path):
290303
try container.encode("edited", forKey: .name)
291304
try container.encode(path, forKey: .path)
@@ -631,6 +644,15 @@ extension WorkspaceStateStorage {
631644
let version = try container.decode(String.self, forKey: .version)
632645
return try self
633646
.init(underlying: .registryDownload(version: TSCUtility.Version(versionString: version)))
647+
case "providedLibrary":
648+
let path = try container.decode(AbsolutePath.self, forKey: .path)
649+
let version = try container.decode(String.self, forKey: .version)
650+
return try self.init(
651+
underlying: .providedLibrary(
652+
at: path,
653+
version: TSCUtility.Version(versionString: version)
654+
)
655+
)
634656
case "edited":
635657
let path = try container.decode(AbsolutePath?.self, forKey: .path)
636658
return try self.init(underlying: .edited(
@@ -661,6 +683,10 @@ extension WorkspaceStateStorage {
661683
case .registryDownload(let version):
662684
try container.encode("registryDownload", forKey: .name)
663685
try container.encode(version, forKey: .version)
686+
case .providedLibrary(let path, let version):
687+
try container.encode("providedLibrary", forKey: .name)
688+
try container.encode(path, forKey: .path)
689+
try container.encode(version, forKey: .version)
664690
case .edited(_, let path):
665691
try container.encode("edited", forKey: .name)
666692
try container.encode(path, forKey: .path)

Sources/Workspace/Workspace.swift

+4
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,8 @@ extension Workspace {
708708
defaultRequirement = checkoutState.requirement
709709
case .registryDownload(let version), .custom(let version, _):
710710
defaultRequirement = .versionSet(.exact(version))
711+
case .providedLibrary(_, version: let version):
712+
defaultRequirement = .versionSet(.exact(version))
711713
case .fileSystem:
712714
throw StringError("local dependency '\(dependency.packageRef.identity)' can't be resolved")
713715
case .edited:
@@ -1351,6 +1353,8 @@ extension Workspace {
13511353
}
13521354
case .registryDownload(let version)?, .custom(let version, _):
13531355
result.append("resolved to '\(version)'")
1356+
case .providedLibrary(_, version: let version):
1357+
result.append("resolved to '\(version)'")
13541358
case .edited?:
13551359
result.append("edited")
13561360
case .fileSystem?:

0 commit comments

Comments
 (0)