Skip to content

Do not validate unused SCM dependencies #7036

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

Closed
wants to merge 1 commit into from
Closed
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
4 changes: 2 additions & 2 deletions Examples/package-info/Sources/package-info/example.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ struct Example {

let workspace = try Workspace(forRootPackage: packagePath)

let manifest = try await workspace.loadRootManifest(at: packagePath, observabilityScope: observability.topScope)
let manifest = try await workspace.loadRootManifest(at: packagePath, rootPackageIdentities: [], observabilityScope: observability.topScope)

let package = try await workspace.loadRootPackage(at: packagePath, observabilityScope: observability.topScope)
let package = try await workspace.loadRootPackage(at: packagePath, rootPackageIdentities: [], observabilityScope: observability.topScope)

let graph = try workspace.loadPackageGraph(rootPath: packagePath, observabilityScope: observability.topScope)

Expand Down
1 change: 1 addition & 0 deletions Sources/Commands/PackageTools/Describe.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ extension SwiftPackageTool {
let package = try temp_await {
workspace.loadRootPackage(
at: packagePath,
rootPackageIdentities: [PackageIdentity(path: packagePath)],
observabilityScope: swiftTool.observabilityScope,
completion: $0
)
Expand Down
1 change: 1 addition & 0 deletions Sources/Commands/PackageTools/DumpCommands.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ struct DumpPackage: SwiftCommand {
let rootManifests = try temp_await {
workspace.loadRootManifests(
packages: root.packages,
rootPackageIdentities: root.packages.map { PackageIdentity(path: $0) },
observabilityScope: swiftTool.observabilityScope,
completion: $0
)
Expand Down
1 change: 1 addition & 0 deletions Sources/Commands/PackageTools/EditCommands.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ extension SwiftPackageTool {
path: path,
revision: revision,
checkoutBranch: checkoutBranch,
rootPackageIdentities: [],
observabilityScope: swiftTool.observabilityScope
)
}
Expand Down
1 change: 1 addition & 0 deletions Sources/Commands/PackageTools/Format.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ extension SwiftPackageTool {
let package = try temp_await {
workspace.loadRootPackage(
at: packagePath,
rootPackageIdentities: [PackageIdentity(path: packagePath)],
observabilityScope: swiftTool.observabilityScope,
completion: $0
)
Expand Down
2 changes: 2 additions & 0 deletions Sources/Commands/SwiftTestTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ public struct SwiftTestTool: SwiftCommand {
let rootManifests = try temp_await {
workspace.loadRootManifests(
packages: root.packages,
rootPackageIdentities: root.packages.map { PackageIdentity(path: $0) },
observabilityScope: swiftTool.observabilityScope,
completion: $0
)
Expand Down Expand Up @@ -517,6 +518,7 @@ extension SwiftTestTool {
let rootManifests = try temp_await {
workspace.loadRootManifests(
packages: root.packages,
rootPackageIdentities: root.packages.map { PackageIdentity(path: $0) },
observabilityScope: swiftTool.observabilityScope,
completion: $0
)
Expand Down
13 changes: 11 additions & 2 deletions Sources/PackageLoading/ManifestLoader+Validation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ public struct ManifestValidator {
private let manifest: Manifest
private let sourceControlValidator: ManifestSourceControlValidator
private let fileSystem: FileSystem
private let dependencyMapper: DependencyMapper
private let rootPackageIdentities: [PackageIdentity]

public init(manifest: Manifest, sourceControlValidator: ManifestSourceControlValidator, fileSystem: FileSystem) {
public init(manifest: Manifest, sourceControlValidator: ManifestSourceControlValidator, dependencyMapper: DependencyMapper, rootPackageIdentities: [PackageIdentity], fileSystem: FileSystem) {
self.manifest = manifest
self.sourceControlValidator = sourceControlValidator
self.dependencyMapper = dependencyMapper
self.rootPackageIdentities = rootPackageIdentities
self.fileSystem = fileSystem
}

Expand Down Expand Up @@ -96,7 +100,12 @@ public struct ManifestValidator {

// validate dependency requirements
for dependency in self.manifest.dependencies {
switch dependency {
guard !rootPackageIdentities.contains(dependency.identity) else {
// avoid validating dependencies which are overidden by a root
continue
}
let mappedDependency = try? dependencyMapper.mappedDependency(for: dependency, fileSystem: self.fileSystem)
switch mappedDependency {
case .sourceControl(let sourceControl):
diagnostics += validateSourceControlDependency(sourceControl)
default:
Expand Down
5 changes: 3 additions & 2 deletions Sources/SPMTestSupport/MockWorkspace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ public final class MockWorkspace {
path: path,
revision: revision,
checkoutBranch: checkoutBranch,
rootPackageIdentities: [],
observabilityScope: observability.topScope
)
}
Expand Down Expand Up @@ -516,7 +517,7 @@ public final class MockWorkspace {
let pinsStore = try workspace.pinsStore.load()

let rootInput = PackageGraphRootInput(packages: try rootPaths(for: roots.map { $0.name }), dependencies: [])
let rootManifests = try temp_await { workspace.loadRootManifests(packages: rootInput.packages, observabilityScope: observability.topScope, completion: $0) }
let rootManifests = try temp_await { workspace.loadRootManifests(packages: rootInput.packages, rootPackageIdentities: [], observabilityScope: observability.topScope, completion: $0) }
let root = PackageGraphRoot(input: rootInput, manifests: rootManifests, observabilityScope: observability.topScope)

let dependencyManifests = try workspace.loadDependencyManifests(root: root, observabilityScope: observability.topScope)
Expand Down Expand Up @@ -732,7 +733,7 @@ public final class MockWorkspace {
let rootInput = PackageGraphRootInput(
packages: try rootPaths(for: roots), dependencies: dependencies
)
let rootManifests = try temp_await { workspace.loadRootManifests(packages: rootInput.packages, observabilityScope: observability.topScope, completion: $0) }
let rootManifests = try temp_await { workspace.loadRootManifests(packages: rootInput.packages, rootPackageIdentities: [], observabilityScope: observability.topScope, completion: $0) }
let graphRoot = PackageGraphRoot(input: rootInput, manifests: rootManifests, observabilityScope: observability.topScope)
let manifests = try workspace.loadDependencyManifests(root: graphRoot, observabilityScope: observability.topScope)
result(manifests, observability.diagnostics)
Expand Down
3 changes: 3 additions & 0 deletions Sources/Workspace/Workspace+Dependencies.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ extension Workspace {
// Load the root manifests and currently checked out manifests.
let rootManifests = try temp_await { self.loadRootManifests(
packages: root.packages,
rootPackageIdentities: root.packages.map { PackageIdentity(path: $0) },
observabilityScope: observabilityScope,
completion: $0
) }
Expand Down Expand Up @@ -333,6 +334,7 @@ extension Workspace {
// FIXME: this should not block
let rootManifests = try temp_await { self.loadRootManifests(
packages: root.packages,
rootPackageIdentities: root.packages.map { PackageIdentity(path: $0) },
observabilityScope: observabilityScope,
completion: $0
) }
Expand Down Expand Up @@ -481,6 +483,7 @@ extension Workspace {
// Load the root manifests and currently checked out manifests.
let rootManifests = try temp_await { self.loadRootManifests(
packages: root.packages,
rootPackageIdentities: root.packages.map { PackageIdentity(path: $0) },
observabilityScope: observabilityScope,
completion: $0
) }
Expand Down
4 changes: 4 additions & 0 deletions Sources/Workspace/Workspace+Editing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ import struct PackageGraph.PackageGraphRootInput
import struct SourceControl.Revision
import class TSCBasic.InMemoryFileSystem

import PackageModel

extension Workspace {
/// Edit implementation.
func _edit(
packageName: String,
path: AbsolutePath? = nil,
revision: Revision? = nil,
checkoutBranch: String? = nil,
rootPackageIdentities: [PackageIdentity],
observabilityScope: ObservabilityScope
) throws {
// Look up the dependency and check if we can edit it.
Expand Down Expand Up @@ -70,6 +73,7 @@ extension Workspace {
packageKind: .fileSystem(destination),
packagePath: destination,
packageLocation: dependency.packageRef.locationString,
rootPackageIdentities: rootPackageIdentities,
observabilityScope: observabilityScope,
completion: $0
)
Expand Down
12 changes: 11 additions & 1 deletion Sources/Workspace/Workspace+Manifests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,10 @@ extension Workspace {

// Load root dependencies manifests (in parallel)
let rootDependencies = root.dependencies.map(\.packageRef)
let rootPackageIdentities = Array(root.packages.keys)
let rootDependenciesManifests = try temp_await { self.loadManagedManifests(
for: rootDependencies,
rootPackageIdentities: rootPackageIdentities,
observabilityScope: observabilityScope,
completion: $0
) }
Expand All @@ -458,6 +460,7 @@ extension Workspace {
let firstLevelDependencies = topLevelManifests.values.map { $0.dependencies.map(\.packageRef) }.flatMap { $0 }
let firstLevelManifests = try temp_await { self.loadManagedManifests(
for: firstLevelDependencies,
rootPackageIdentities: rootPackageIdentities,
observabilityScope: observabilityScope,
completion: $0
) } // FIXME: this should not block
Expand Down Expand Up @@ -492,6 +495,7 @@ extension Workspace {
}
let dependenciesManifests = try temp_await { self.loadManagedManifests(
for: dependenciesToLoad,
rootPackageIdentities: rootPackageIdentities,
observabilityScope: observabilityScope,
completion: $0
) }
Expand Down Expand Up @@ -591,14 +595,15 @@ extension Workspace {
/// Loads the given manifests, if it is present in the managed dependencies.
private func loadManagedManifests(
for packages: [PackageReference],
rootPackageIdentities: [PackageIdentity],
observabilityScope: ObservabilityScope,
completion: @escaping (Result<[PackageIdentity: Manifest], Error>) -> Void
) {
let sync = DispatchGroup()
let manifests = ThreadSafeKeyValueStore<PackageIdentity, Manifest>()
Set(packages).forEach { package in
sync.enter()
self.loadManagedManifest(for: package, observabilityScope: observabilityScope) { manifest in
self.loadManagedManifest(for: package, rootPackageIdentities: rootPackageIdentities, observabilityScope: observabilityScope) { manifest in
defer { sync.leave() }
if let manifest {
manifests[package.identity] = manifest
Expand All @@ -614,6 +619,7 @@ extension Workspace {
/// Loads the given manifest, if it is present in the managed dependencies.
private func loadManagedManifest(
for package: PackageReference,
rootPackageIdentities: [PackageIdentity],
observabilityScope: ObservabilityScope,
completion: @escaping (Manifest?) -> Void
) {
Expand Down Expand Up @@ -675,6 +681,7 @@ extension Workspace {
packagePath: packagePath,
packageLocation: managedDependency.packageRef.locationString,
packageVersion: packageVersion,
rootPackageIdentities: rootPackageIdentities,
fileSystem: fileSystem,
observabilityScope: observabilityScope
) { result in
Expand All @@ -692,6 +699,7 @@ extension Workspace {
packagePath: AbsolutePath,
packageLocation: String,
packageVersion: Version? = nil,
rootPackageIdentities: [PackageIdentity],
fileSystem: FileSystem? = nil,
observabilityScope: ObservabilityScope,
completion: @escaping (Result<Manifest, Error>) -> Void
Expand Down Expand Up @@ -747,6 +755,8 @@ extension Workspace {
let validator = ManifestValidator(
manifest: manifest,
sourceControlValidator: self.repositoryManager,
dependencyMapper: self.dependencyMapper,
rootPackageIdentities: rootPackageIdentities,
fileSystem: self.fileSystem
)
let validationIssues = validator.validate()
Expand Down
23 changes: 17 additions & 6 deletions Sources/Workspace/Workspace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -585,12 +585,15 @@ extension Workspace {
/// should be checked out to otherwise current revision.
/// - checkoutBranch: If provided, a new branch with this name will be
/// created from the revision provided.
/// - rootPackageIdentities: Identities of any root packages being used
/// in the given package graph.
/// - observabilityScope: The observability scope that reports errors, warnings, etc
public func edit(
packageName: String,
path: AbsolutePath? = nil,
revision: Revision? = nil,
checkoutBranch: String? = nil,
rootPackageIdentities: [PackageIdentity],
observabilityScope: ObservabilityScope
) {
do {
Expand All @@ -599,6 +602,7 @@ extension Workspace {
path: path,
revision: revision,
checkoutBranch: checkoutBranch,
rootPackageIdentities: rootPackageIdentities,
observabilityScope: observabilityScope
)
} catch {
Expand Down Expand Up @@ -939,10 +943,11 @@ extension Workspace {
/// Loads and returns manifests at the given paths.
public func loadRootManifests(
packages: [AbsolutePath],
rootPackageIdentities: [PackageIdentity],
observabilityScope: ObservabilityScope
) async throws -> [AbsolutePath: Manifest] {
try await withCheckedThrowingContinuation { continuation in
self.loadRootManifests(packages: packages, observabilityScope: observabilityScope) { result in
self.loadRootManifests(packages: packages, rootPackageIdentities: rootPackageIdentities, observabilityScope: observabilityScope) { result in
continuation.resume(with: result)
}
}
Expand All @@ -951,6 +956,7 @@ extension Workspace {
/// Loads and returns manifests at the given paths.
public func loadRootManifests(
packages: [AbsolutePath],
rootPackageIdentities: [PackageIdentity],
observabilityScope: ObservabilityScope,
completion: @escaping (Result<[AbsolutePath: Manifest], Error>) -> Void
) {
Expand All @@ -965,6 +971,7 @@ extension Workspace {
packageKind: .root(package),
packagePath: package,
packageLocation: package.pathString,
rootPackageIdentities: rootPackageIdentities,
observabilityScope: observabilityScope
) { result in
defer { sync.leave() }
Expand Down Expand Up @@ -992,10 +999,11 @@ extension Workspace {
/// Loads and returns manifest at the given path.
public func loadRootManifest(
at path: AbsolutePath,
rootPackageIdentities: [PackageIdentity],
observabilityScope: ObservabilityScope
) async throws -> Manifest {
try await withCheckedThrowingContinuation { continuation in
self.loadRootManifest(at: path, observabilityScope: observabilityScope) { result in
self.loadRootManifest(at: path, rootPackageIdentities: rootPackageIdentities, observabilityScope: observabilityScope) { result in
continuation.resume(with: result)
}
}
Expand All @@ -1004,10 +1012,11 @@ extension Workspace {
/// Loads and returns manifest at the given path.
public func loadRootManifest(
at path: AbsolutePath,
rootPackageIdentities: [PackageIdentity],
observabilityScope: ObservabilityScope,
completion: @escaping (Result<Manifest, Error>) -> Void
) {
self.loadRootManifests(packages: [path], observabilityScope: observabilityScope) { result in
self.loadRootManifests(packages: [path], rootPackageIdentities: rootPackageIdentities, observabilityScope: observabilityScope) { result in
completion(result.tryMap {
// normally, we call loadRootManifests which attempts to load any manifest it can and report errors via
// diagnostics
Expand All @@ -1025,9 +1034,9 @@ extension Workspace {
}

/// Loads root package
public func loadRootPackage(at path: AbsolutePath, observabilityScope: ObservabilityScope) async throws -> Package {
public func loadRootPackage(at path: AbsolutePath, rootPackageIdentities: [PackageIdentity], observabilityScope: ObservabilityScope) async throws -> Package {
try await withCheckedThrowingContinuation { continuation in
self.loadRootPackage(at: path, observabilityScope: observabilityScope) { result in
self.loadRootPackage(at: path, rootPackageIdentities: rootPackageIdentities, observabilityScope: observabilityScope) { result in
continuation.resume(with: result)
}
}
Expand All @@ -1036,10 +1045,11 @@ extension Workspace {
/// Loads root package
public func loadRootPackage(
at path: AbsolutePath,
rootPackageIdentities: [PackageIdentity],
observabilityScope: ObservabilityScope,
completion: @escaping (Result<Package, Error>) -> Void
) {
self.loadRootManifest(at: path, observabilityScope: observabilityScope) { result in
self.loadRootManifest(at: path, rootPackageIdentities: rootPackageIdentities, observabilityScope: observabilityScope) { result in
let result = result.tryMap { manifest -> Package in
let identity = try self.identityResolver.resolveIdentity(for: manifest.packageKind)

Expand Down Expand Up @@ -1140,6 +1150,7 @@ extension Workspace {
packageKind: previousPackage.underlyingPackage.manifest.packageKind,
packagePath: previousPackage.path,
packageLocation: previousPackage.underlyingPackage.manifest.packageLocation,
rootPackageIdentities: packageGraph.rootPackages.map { $0.identity },
observabilityScope: observabilityScope
) { result in
let result = result.tryMap { manifest -> Package in
Expand Down
1 change: 1 addition & 0 deletions Tests/CommandsTests/PackageToolTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2956,6 +2956,7 @@ final class PackageToolTests: CommandsTestCase {
let rootManifests = try temp_await {
workspace.loadRootManifests(
packages: rootInput.packages,
rootPackageIdentities: rootInput.packages.map { PackageIdentity(path: $0) },
observabilityScope: observability.topScope,
completion: $0
)
Expand Down
Loading