Skip to content

Clean up warnings, fix handling of dep version changes #8232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions Sources/PackageGraph/ModulesGraph+Loading.swift
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,12 @@ extension ModulesGraph {
)

let rootPackages = resolvedPackages.filter { root.manifests.values.contains($0.manifest) }
checkAllDependenciesAreUsed(packages: resolvedPackages, rootPackages, observabilityScope: observabilityScope)
checkAllDependenciesAreUsed(
packages: resolvedPackages,
rootPackages,
prebuilts: prebuilts,
observabilityScope: observabilityScope
)

return try ModulesGraph(
rootPackages: rootPackages,
Expand All @@ -275,6 +280,7 @@ extension ModulesGraph {
private func checkAllDependenciesAreUsed(
packages: IdentifiableSet<ResolvedPackage>,
_ rootPackages: [ResolvedPackage],
prebuilts: [PackageIdentity: [String: PrebuiltLibrary]],
observabilityScope: ObservabilityScope
) {
for package in rootPackages {
Expand Down Expand Up @@ -352,9 +358,10 @@ private func checkAllDependenciesAreUsed(
let usedByPackage = productDependencies.contains { $0.name == product.name }
// We check if any of the products of this dependency is guarded by a trait.
let traitGuarded = traitGuardedProductDependencies.contains(product.name)
// Consider prebuilts as used
let prebuilt = prebuilts[dependency.identity]?.keys.contains(product.name) ?? false

// If the product is either used directly or guarded by a trait we consider it as used
return usedByPackage || traitGuarded
return usedByPackage || traitGuarded || prebuilt
}

if !dependencyIsUsed && !observabilityScope.errorsReportedInAnyScope {
Expand Down
41 changes: 23 additions & 18 deletions Sources/Workspace/ManagedPrebuilt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
//
//===----------------------------------------------------------------------===//

import struct TSCUtility.Version

import Basics
import PackageModel

Expand All @@ -19,6 +21,9 @@ extension Workspace {
/// The package identity
public let identity: PackageIdentity

/// The package version
public let version: Version

/// The name of the binary target the artifact corresponds to.
public let libraryName: String

Expand All @@ -45,60 +50,60 @@ extension Workspace {
/// A collection of managed artifacts which have been downloaded.
public final class ManagedPrebuilts {
/// A mapping from package identity, to target name, to ManagedArtifact.
private var artifactMap: [PackageIdentity: [String: ManagedPrebuilt]]
private var prebuiltMap: [PackageIdentity: [String: ManagedPrebuilt]]

internal var artifacts: AnyCollection<ManagedPrebuilt> {
AnyCollection(self.artifactMap.values.lazy.flatMap{ $0.values })
internal var prebuilts: AnyCollection<ManagedPrebuilt> {
AnyCollection(self.prebuiltMap.values.lazy.flatMap{ $0.values })
}

init() {
self.artifactMap = [:]
self.prebuiltMap = [:]
}

init(_ artifacts: [ManagedPrebuilt]) throws {
let artifactsByPackagePath = Dictionary(grouping: artifacts, by: { $0.identity })
self.artifactMap = try artifactsByPackagePath.mapValues{ artifacts in
try Dictionary(artifacts.map { ($0.libraryName, $0) }, uniquingKeysWith: { _, _ in
init(_ prebuilts: [ManagedPrebuilt]) throws {
let prebuiltsByPackagePath = Dictionary(grouping: prebuilts, by: { $0.identity })
self.prebuiltMap = try prebuiltsByPackagePath.mapValues{ prebuilt in
try Dictionary(prebuilt.map { ($0.libraryName, $0) }, uniquingKeysWith: { _, _ in
// should be unique
throw StringError("binary artifact already exists in managed artifacts")
throw StringError("prebuilt already exists in managed prebuilts")
})
}
}

public subscript(packageIdentity packageIdentity: PackageIdentity, targetName targetName: String) -> ManagedPrebuilt? {
self.artifactMap[packageIdentity]?[targetName]
self.prebuiltMap[packageIdentity]?[targetName]
}

public func add(_ artifact: ManagedPrebuilt) {
self.artifactMap[artifact.identity, default: [:]][artifact.libraryName] = artifact
public func add(_ prebuilt: ManagedPrebuilt) {
self.prebuiltMap[prebuilt.identity, default: [:]][prebuilt.libraryName] = prebuilt
}

public func remove(packageIdentity: PackageIdentity, targetName: String) {
self.artifactMap[packageIdentity]?[targetName] = nil
self.prebuiltMap[packageIdentity]?[targetName] = nil
}
}
}

extension Workspace.ManagedPrebuilts: Collection {
public var startIndex: AnyIndex {
self.artifacts.startIndex
self.prebuilts.startIndex
}

public var endIndex: AnyIndex {
self.artifacts.endIndex
self.prebuilts.endIndex
}

public subscript(index: AnyIndex) -> Workspace.ManagedPrebuilt {
self.artifacts[index]
self.prebuilts[index]
}

public func index(after index: AnyIndex) -> AnyIndex {
self.artifacts.index(after: index)
self.prebuilts.index(after: index)
}
}

extension Workspace.ManagedPrebuilts: CustomStringConvertible {
public var description: String {
"<ManagedArtifacts: \(Array(self.artifacts))>"
"<ManagedArtifacts: \(Array(self.prebuilts))>"
}
}
34 changes: 21 additions & 13 deletions Sources/Workspace/Workspace+Prebuilts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,9 @@ extension Workspace {
if fileSystem.exists(destination) {
do {
return try JSONDecoder().decode(
PrebuiltsManifest.self,
from: try Data(contentsOf: destination.asURL)
path: destination,
fileSystem: fileSystem,
as: PrebuiltsManifest.self
)
} catch {
// redownload it
Expand Down Expand Up @@ -325,10 +326,10 @@ extension Workspace {
}

do {
let data = try fileSystem.readFileContents(destination)
return try JSONDecoder().decode(
PrebuiltsManifest.self,
from: Data(data.contents)
path: destination,
fileSystem: fileSystem,
as: PrebuiltsManifest.self
)
} catch {
observabilityScope.emit(
Expand Down Expand Up @@ -489,13 +490,11 @@ extension Workspace {
return
}

for prebuilt in prebuiltsManager.findPrebuilts(
packages: try manifests.requiredPackages
) {
let addedPrebuilts = ManagedPrebuilts()

for prebuilt in prebuiltsManager.findPrebuilts(packages: try manifests.requiredPackages) {
guard
let manifest = manifests.allDependencyManifests[
prebuilt.identity
],
let manifest = manifests.allDependencyManifests[prebuilt.identity],
let packageVersion = manifest.manifest.version,
let prebuiltManifest = try await prebuiltsManager
.downloadManifest(
Expand Down Expand Up @@ -523,21 +522,30 @@ extension Workspace {
artifact: artifact,
observabilityScope: observabilityScope
)
{
{
// Add to workspace state
let managedPrebuilt = ManagedPrebuilt(
identity: prebuilt.identity,
version: packageVersion,
libraryName: library.name,
path: path,
products: library.products,
cModules: library.cModules
)
addedPrebuilts.add(managedPrebuilt)
self.state.prebuilts.add(managedPrebuilt)
try self.state.save()
}
}
}
}

for prebuilt in self.state.prebuilts.prebuilts {
if !addedPrebuilts.contains(where: { $0.identity == prebuilt.identity && $0.version == prebuilt.version }) {
self.state.prebuilts.remove(packageIdentity: prebuilt.identity, targetName: prebuilt.libraryName)
}
}

try self.state.save()
}

var hostPrebuiltsPlatform: PrebuiltsManifest.Platform? {
Expand Down
5 changes: 5 additions & 0 deletions Sources/Workspace/Workspace+State.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
//
//===----------------------------------------------------------------------===//

import struct TSCUtility.Version

import Basics
import Foundation
import PackageGraph
Expand Down Expand Up @@ -447,13 +449,15 @@ extension WorkspaceStateStorage {

struct Prebuilt: Codable {
let identity: PackageIdentity
let version: TSCUtility.Version
let libraryName: String
let path: AbsolutePath
let products: [String]
let cModules: [String]

init(_ managedPrebuilt: Workspace.ManagedPrebuilt) {
self.identity = managedPrebuilt.identity
self.version = managedPrebuilt.version
self.libraryName = managedPrebuilt.libraryName
self.path = managedPrebuilt.path
self.products = managedPrebuilt.products
Expand Down Expand Up @@ -527,6 +531,7 @@ extension Workspace.ManagedPrebuilt {
fileprivate init(_ prebuilt: WorkspaceStateStorage.V7.Prebuilt) throws {
self.init(
identity: prebuilt.identity,
version: prebuilt.version,
libraryName: prebuilt.libraryName,
path: prebuilt.path,
products: prebuilt.products,
Expand Down
23 changes: 23 additions & 0 deletions Sources/_InternalTestSupport/ManifestExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -266,4 +266,27 @@ extension Manifest {
traits: self.traits
)
}

public func with(dependencies: [PackageDependency]) -> Manifest {
Manifest(
displayName: self.displayName,
path: self.path,
packageKind: self.packageKind,
packageLocation: self.packageLocation,
defaultLocalization: self.defaultLocalization,
platforms: self.platforms,
version: self.version,
revision: self.revision,
toolsVersion: self.toolsVersion,
pkgConfig: self.pkgConfig,
providers: self.providers,
cLanguageStandard: self.cLanguageStandard,
cxxLanguageStandard: self.cxxLanguageStandard,
swiftLanguageVersions: self.swiftLanguageVersions,
dependencies: dependencies,
products: self.products,
targets: self.targets,
traits: self.traits
)
}
}
2 changes: 1 addition & 1 deletion Sources/_InternalTestSupport/MockWorkspace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ public final class MockWorkspace {
public func checkPackageGraph(
roots: [String] = [],
deps: [MockDependency],
_ result: (ModulesGraph, [Basics.Diagnostic]) -> Void
_ result: (ModulesGraph, [Basics.Diagnostic]) throws -> Void
) async throws {
let dependencies = try deps.map { try $0.convert(baseURL: packagesDir, identityResolver: self.identityResolver) }
try await self.checkPackageGraph(roots: roots, dependencies: dependencies, result)
Expand Down
Loading