Skip to content

Commit 139c6fa

Browse files
committed
[Resolution/Loading] Handle packages backed by a provided library
Instead of eliding provided library packages, start returning them from resolution as a special `.providedLibrary` reference and augment manifest loader to build manifests for such libraries based on contents of the library's directory (each `.swiftmodule` becomes a `.providedLibrary` target).
1 parent fd7995e commit 139c6fa

File tree

3 files changed

+75
-8
lines changed

3 files changed

+75
-8
lines changed

Sources/PackageGraph/Resolution/PubGrub/PubGrubDependencyResolver.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public struct PubGrubDependencyResolver {
231231
continue
232232
}
233233

234-
let package = assignment.term.node.package
234+
var package = assignment.term.node.package
235235

236236
let boundVersion: BoundVersion
237237
switch assignment.term.requirement {
@@ -241,16 +241,18 @@ public struct PubGrubDependencyResolver {
241241
throw InternalError("unexpected requirement value for assignment \(assignment.term)")
242242
}
243243

244-
// Strip packages that have prebuilt libraries only if they match library version.
245-
//
246-
// FIXME: This is built on assumption that libraries are part of the SDK and are
247-
// always available in include/library paths, but what happens if they are
248-
// part of a toolchain instead? Builder needs an indicator that certain path
249-
// has to be included when building packages that depend on prebuilt libraries.
250244
if let library = package.matchingPrebuiltLibrary(in: availableLibraries),
251245
boundVersion == .version(.init(stringLiteral: library.version))
252246
{
253-
continue
247+
guard case .remoteSourceControl(let url) = package.kind else {
248+
throw InternalError("Matched provided library against invalid package: \(package)")
249+
}
250+
251+
package = .providedLibrary(
252+
identity: package.identity,
253+
origin: url,
254+
path: library.location
255+
)
254256
}
255257

256258
let products = assignment.term.node.productFilter

Sources/PackageLoading/ManifestLoader+Validation.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ public struct ManifestValidator {
3434

3535
/// Validate the provided manifest.
3636
public func validate() -> [Basics.Diagnostic] {
37+
// Provided library manifest is synthesized by the package manager.
38+
if case .providedLibrary = self.manifest.packageKind {
39+
return []
40+
}
41+
3742
var diagnostics = [Basics.Diagnostic]()
3843

3944
diagnostics += self.validateTargets()

Sources/PackageLoading/ManifestLoader.swift

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,19 @@ extension ManifestLoaderProtocol {
206206
completion: @escaping (Result<Manifest, Error>) -> Void
207207
) {
208208
do {
209+
if case .providedLibrary = packageKind {
210+
let manifest = try self.loadLibrary(
211+
fileSystem: fileSystem,
212+
packagePath: packagePath,
213+
packageKind: packageKind,
214+
packageIdentity: packageIdentity,
215+
packageLocation: packageLocation,
216+
packageVersion: packageVersion?.version
217+
)
218+
completion(.success(manifest))
219+
return
220+
}
221+
209222
// find the manifest path and parse it's tools-version
210223
let manifestPath = try ManifestLoader.findManifest(packagePath: packagePath, fileSystem: fileSystem, currentToolsVersion: currentToolsVersion)
211224
let manifestToolsVersion = try ToolsVersionParser.parse(manifestPath: manifestPath, fileSystem: fileSystem)
@@ -266,6 +279,53 @@ extension ManifestLoaderProtocol {
266279
)
267280
}
268281
}
282+
283+
private func loadLibrary(
284+
fileSystem: FileSystem,
285+
packagePath: AbsolutePath,
286+
packageKind: PackageReference.Kind,
287+
packageIdentity: PackageIdentity,
288+
packageLocation: String,
289+
packageVersion: Version?
290+
) throws -> Manifest {
291+
let names = try fileSystem.getDirectoryContents(packagePath).filter {
292+
$0.hasSuffix("swiftmodule")
293+
}.map {
294+
let components = $0.split(separator: ".")
295+
return String(components[0])
296+
}
297+
298+
let products: [ProductDescription] = try names.map {
299+
try .init(name: $0, type: .library(.automatic), targets: [$0])
300+
}
301+
302+
let targets: [TargetDescription] = try names.map {
303+
try .init(
304+
name: $0,
305+
path: packagePath.pathString,
306+
type: .providedLibrary
307+
)
308+
}
309+
310+
return .init(
311+
displayName: packageIdentity.description,
312+
path: packagePath.appending(component: "provided-libraries.json"),
313+
packageKind: packageKind,
314+
packageLocation: packageLocation,
315+
defaultLocalization: nil,
316+
platforms: [],
317+
version: packageVersion,
318+
revision: nil,
319+
toolsVersion: .v6_0,
320+
pkgConfig: nil,
321+
providers: nil,
322+
cLanguageStandard: nil,
323+
cxxLanguageStandard: nil,
324+
swiftLanguageVersions: nil,
325+
products: products,
326+
targets: targets
327+
)
328+
}
269329
}
270330

271331
// MARK: - ManifestLoader

0 commit comments

Comments
 (0)