Skip to content

Implement dependency resolution through package registry #3640

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 16 commits 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
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ let package = Package(
/** Primitive Package model objects */
name: "PackageModel",
dependencies: ["SwiftToolsSupport-auto", "Basics"]),

.target(
/** Package model conventions and loading support */
name: "PackageLoading",
Expand Down
26 changes: 5 additions & 21 deletions Sources/Commands/SwiftPackageRegistryTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import Foundation
import PackageRegistry

private enum RegistryConfigurationError: Swift.Error {
case missingScope(String? = nil)
case missingScope(PackageIdentity.Scope? = nil)
case invalidURL(String)
}

Expand Down Expand Up @@ -90,6 +90,8 @@ public struct SwiftPackageRegistryTool: ParsableCommand {
throw RegistryConfigurationError.invalidURL(self.url)
}

let scope = try scope.map(PackageIdentity.Scope.init(validating:))

// TODO: Require login if password is specified

let set: (inout RegistryConfiguration) throws -> Void = { configuration in
Expand Down Expand Up @@ -125,6 +127,8 @@ public struct SwiftPackageRegistryTool: ParsableCommand {
var scope: String?

func run(_ swiftTool: SwiftTool) throws {
let scope = try scope.map(PackageIdentity.Scope.init(validating:))

let unset: (inout RegistryConfiguration) throws -> Void = { configuration in
if let scope = scope {
guard let _ = configuration.scopedRegistries[scope] else {
Expand All @@ -148,23 +152,3 @@ public struct SwiftPackageRegistryTool: ParsableCommand {
}
}
}

// MARK: -


private extension SwiftTool {
func getRegistriesConfig() throws -> Workspace.Configuration.Registries {
let localRegistriesFile = try Workspace.DefaultLocations.registriesConfigurationFile(forRootPackage: self.getPackageRoot())

let workspace = try getActiveWorkspace()
let sharedRegistriesFile = workspace.location.sharedConfigurationDirectory.map {
Workspace.DefaultLocations.registriesConfigurationFile(at: $0)
}

return try .init(
localRegistriesFile: localRegistriesFile,
sharedRegistriesFile: sharedRegistriesFile,
fileSystem: localFileSystem
)
}
}
16 changes: 16 additions & 0 deletions Sources/Commands/SwiftTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,21 @@ public class SwiftTool {
return newPath
}

func getRegistriesConfig(sharedConfigurationDirectory: AbsolutePath? = nil) throws -> Workspace.Configuration.Registries {
let localRegistriesFile = try Workspace.DefaultLocations.registriesConfigurationFile(forRootPackage: self.getPackageRoot())

let sharedConfigurationDirectory = try sharedConfigurationDirectory ?? self.getSharedConfigurationDirectory()
let sharedRegistriesFile = sharedConfigurationDirectory.map {
Workspace.DefaultLocations.registriesConfigurationFile(at: $0)
}

return try .init(
localRegistriesFile: localRegistriesFile,
sharedRegistriesFile: sharedRegistriesFile,
fileSystem: localFileSystem
)
}

func getAuthorizationProvider() throws -> AuthorizationProvider? {
// currently only single provider: netrc
return try self.getNetrcConfig()?.get()
Expand Down Expand Up @@ -564,6 +579,7 @@ public class SwiftTool {
sharedConfigurationDirectory: sharedConfigurationDirectory
),
mirrors: self.getMirrorsConfig(sharedConfigurationDirectory: sharedConfigurationDirectory).mirrors,
registries: try? self.getRegistriesConfig(sharedConfigurationDirectory: sharedConfigurationDirectory).configuration,
authorizationProvider: self.getAuthorizationProvider(),
customManifestLoader: self.getManifestLoader(), // FIXME: doe we really need to customize it?
customRepositoryProvider: provider, // FIXME: doe we really need to customize it?
Expand Down
51 changes: 29 additions & 22 deletions Sources/PackageDescription/PackageDependency.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import Foundation

// MARK: - file system

extension Package {
Expand All @@ -27,7 +29,7 @@ extension Package {
public enum Kind {
case fileSystem(name: String?, path: String)
case sourceControl(name: String?, location: String, requirement: SourceControlRequirement)
case registry(identity: String, requirement: RegistryRequirement)
case registry(id: String, requirement: RegistryRequirement)
}

@available(_PackageDescription, introduced: 5.6)
Expand Down Expand Up @@ -81,7 +83,7 @@ extension Package {
case .revision(let revision):
return .revisionItem(revision)
}
case .registry(identity: _, requirement: let requirement):
case .registry(id: _, requirement: let requirement):
switch requirement {
case .exact(let version):
return .exactItem(version)
Expand Down Expand Up @@ -121,8 +123,8 @@ extension Package {
self.init(kind: .sourceControl(name: name, location: location, requirement: requirement))
}

convenience init(identity: String, requirement: RegistryRequirement) {
self.init(kind: .registry(identity: identity, requirement: requirement))
convenience init(id: String, requirement: RegistryRequirement) {
self.init(kind: .registry(id: id, requirement: requirement))
}
}
}
Expand Down Expand Up @@ -459,17 +461,17 @@ extension Package.Dependency {
/// The following example allows the Swift Package Manager to select a version
/// like a `1.2.3`, `1.2.4`, or `1.3.0`, but not `2.0.0`.
///
/// .package(identity: "scope.name", from: "1.2.3"),
/// .package(id: "scope.name", from: "1.2.3"),
///
/// - Parameters:
/// - identity: The identity of the package.
/// - id: The identity of the package.
/// - version: The minimum version requirement.
@available(_PackageDescription, introduced: 999)
public static func package(
identity: String,
id: String,
from version: Version
) -> Package.Dependency {
return .package(identity: identity, .upToNextMajor(from: version))
return .package(id: id, .upToNextMajor(from: version))
}

/// Adds a package dependency that uses the exact version requirement.
Expand All @@ -483,17 +485,17 @@ extension Package.Dependency {
///
/// The following example instruct the Swift Package Manager to use version `1.2.3`.
///
/// .package(identity: "scope.name", exact: "1.2.3"),
/// .package(id: "scope.name", exact: "1.2.3"),
///
/// - Parameters:
/// - identity: The identity of the package.
/// - id: The identity of the package.
/// - version: The minimum version requirement.
@available(_PackageDescription, introduced: 999)
public static func package(
identity: String,
id: String,
exact version: Version
) -> Package.Dependency {
return .package(identity: identity, requirement: .exact(version))
return .package(id: id, requirement: .exact(version))
}

/// Adds a package dependency starting with a specific minimum version, up to
Expand All @@ -502,17 +504,17 @@ extension Package.Dependency {
/// The following example allows the Swift Package Manager to pick
/// versions `1.2.3`, `1.2.4`, `1.2.5`, but not `1.2.6`.
///
/// .package(identity: "scope.name", "1.2.3"..<"1.2.6"),
/// .package(id: "scope.name", "1.2.3"..<"1.2.6"),
///
/// - Parameters:
/// - identity: The identity of the package.
/// - id: The identity of the package.
/// - range: The custom version range requirement.
@available(_PackageDescription, introduced: 999)
public static func package(
identity: String,
id: String,
_ range: Range<Version>
) -> Package.Dependency {
return .package(identity: identity, requirement: .range(range))
return .package(id: id, requirement: .range(range))
}

/// Adds a package dependency starting with a specific minimum version, going
Expand All @@ -521,14 +523,14 @@ extension Package.Dependency {
/// The following example allows the Swift Package Manager to pick
/// versions 1.2.3, 1.2.4, 1.2.5, as well as 1.2.6.
///
/// .package(identity: "scope.name", "1.2.3"..."1.2.6"),
/// .package(id: "scope.name", "1.2.3"..."1.2.6"),
///
/// - Parameters:
/// - identity: The identity of the package.
/// - id: The identity of the package.
/// - range: The closed version range requirement.
@available(_PackageDescription, introduced: 999)
public static func package(
identity: String,
id: String,
_ range: ClosedRange<Version>
) -> Package.Dependency {
// Increase upperbound's patch version by one.
Expand All @@ -537,16 +539,21 @@ extension Package.Dependency {
upper.major, upper.minor, upper.patch + 1,
prereleaseIdentifiers: upper.prereleaseIdentifiers,
buildMetadataIdentifiers: upper.buildMetadataIdentifiers)
return .package(identity: identity, range.lowerBound ..< upperBound)
return .package(id: id, range.lowerBound ..< upperBound)
}

// intentionally private to hide enum detail
@available(_PackageDescription, introduced: 999)
private static func package(
identity: String,
id: String,
requirement: Package.Dependency.RegistryRequirement
) -> Package.Dependency {
return .init(identity: identity, requirement: requirement)
let pattern = #"\A[a-zA-Z\d](?:[a-zA-Z\d]|-(?=[a-zA-Z\d])){0,38}\.[a-zA-Z0-9](?:[a-zA-Z0-9]|[-_](?=[a-zA-Z0-9])){0,99}\z"#
if id.range(of: pattern, options: .regularExpression) == nil {
errors.append("Invalid package identifier: \(id)")
}

return .init(id: id, requirement: requirement)
}
}

Expand Down
2 changes: 0 additions & 2 deletions Sources/PackageGraph/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ add_library(PackageGraph
DependencyResolver.swift
Diagnostics.swift
GraphLoadingNode.swift
LocalPackageContainer.swift
PackageContainer.swift
PackageGraph.swift
PackageGraph+Loading.swift
Expand All @@ -27,7 +26,6 @@ add_library(PackageGraph
Pubgrub/PartialSolution.swift
Pubgrub/PubgrubDependencyResolver.swift
Pubgrub/Term.swift
RepositoryPackageContainer.swift
ResolvedPackage.swift
ResolvedProduct.swift
ResolvedTarget.swift
Expand Down
5 changes: 2 additions & 3 deletions Sources/PackageGraph/CheckoutState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import TSCBasic
import SourceControl
import TSCUtility
import struct SourceControl.Revision // FIXME: remove this dependency
import struct TSCUtility.Version

/// A checkout state represents the current state of a repository.
///
Expand Down
2 changes: 0 additions & 2 deletions Sources/PackageGraph/DependencyMirrors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
*/

import Foundation

import TSCBasic
import TSCUtility

/// A collection of dependency mirrors.
public final class DependencyMirrors: Equatable {
Expand Down
3 changes: 1 addition & 2 deletions Sources/PackageGraph/GraphLoadingNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import TSCBasic
import PackageLoading
import PackageModel
import TSCUtility
import TSCBasic

/// A node used while loading the packages in a resolved graph.
///
Expand Down
6 changes: 2 additions & 4 deletions Sources/PackageGraph/PackageContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
*/

import Dispatch
import PackageLoading
import PackageModel
import SourceControl
import struct TSCUtility.Version

/// A container of packages.
Expand Down Expand Up @@ -104,7 +102,7 @@ extension PackageContainer {
}
}

// MARK: -
// MARK: - PackageContainerConstraint

/// An individual constraint onto a container.
public struct PackageContainerConstraint: Equatable, Hashable {
Expand Down Expand Up @@ -139,7 +137,7 @@ extension PackageContainerConstraint: CustomStringConvertible {
}
}

// MARK: -
// MARK: - PackageContainerProvider

/// An interface for resolving package containers.
public protocol PackageContainerProvider {
Expand Down
13 changes: 7 additions & 6 deletions Sources/PackageGraph/PackageGraph+Loading.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
import Basics
import PackageLoading
import PackageModel
import SourceControl
import TSCBasic
import TSCUtility

extension PackageGraph {

Expand Down Expand Up @@ -233,7 +231,7 @@ private func createResolvedPackages(
var dependenciesByNameForTargetDependencyResolution = [String: ResolvedPackageBuilder]()

// Establish the manifest-declared package dependencies.
package.manifest.dependenciesRequired(for: packageBuilder.productFilter).forEach { dependency in
try package.manifest.dependenciesRequired(for: packageBuilder.productFilter).forEach { dependency in
// FIXME: change this validation logic to use identity instead of location
let dependencyLocation: String
switch dependency {
Expand All @@ -246,9 +244,12 @@ private func createResolvedPackages(
case .remote(let url):
dependencyLocation = url.absoluteString
}
case .registry:
// FIXME
fatalError("registry based dependencies not implemented yet")
case .registry(let settings):
guard let _ = settings.identity.scopeAndName else {
throw InternalError("invalid package identifier \(settings.identity)")
}

dependencyLocation = "\(settings.identity)"
}

// Otherwise, look it up by its identity.
Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageGraph/PackageGraph.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import TSCBasic
import PackageModel
import TSCBasic

enum PackageGraphError: Swift.Error {
/// Indicates a non-root package with no targets.
Expand Down
3 changes: 1 addition & 2 deletions Sources/PackageGraph/PackageGraphRoot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@

import Basics
import PackageModel
import SourceControl
import TSCBasic
import TSCUtility
import enum TSCUtility.Git

/// Represents the input to the package graph root.
public struct PackageGraphRootInput {
Expand Down
7 changes: 3 additions & 4 deletions Sources/PackageGraph/PackageModel+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
*/

import PackageModel
import SourceControl

extension PackageDependency {
/// Create the package reference object for the dependency.
Expand All @@ -26,10 +25,10 @@ extension PackageDependency {
case .remote(let url):
packageKind = .remoteSourceControl(url)
}
case .registry:
// FIXME
fatalError("registry based dependencies not implemented yet")
case .registry(let settings):
packageKind = .registry(settings.identity)
}

return PackageReference(identity: self.identity, kind: packageKind)
}
}
Expand Down
Loading