Skip to content

RFC: configuration utilities #3652

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
Empty file added .swiftpm.lock
Empty file.
10 changes: 7 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ let package = Package(
name: "Basics",
dependencies: ["SwiftToolsSupport-auto"]),

.target(
name: "Configurations",
dependencies: ["SwiftToolsSupport-auto", "Basics"]),

.target(
/** The llbuild manifest model */
name: "LLBuildManifest",
Expand All @@ -151,7 +155,7 @@ let package = Package(
.target(
/** Package model conventions and loading support */
name: "PackageLoading",
dependencies: ["SwiftToolsSupport-auto", "Basics", "PackageModel", "SourceControl"]),
dependencies: ["SwiftToolsSupport-auto", "Basics", "Configurations", "PackageModel", "SourceControl"]),

// MARK: Package Dependency Resolution

Expand Down Expand Up @@ -182,7 +186,7 @@ let package = Package(
.target(
/** Data structures and support for package collections */
name: "PackageCollections",
dependencies: ["SwiftToolsSupport-auto", "Basics", "PackageModel", "SourceControl", "PackageCollectionsModel", "PackageCollectionsSigning"]),
dependencies: ["SwiftToolsSupport-auto", "Basics", "Configurations", "PackageModel", "SourceControl", "PackageCollectionsModel", "PackageCollectionsSigning"]),

// MARK: Package Manager Functionality

Expand All @@ -206,7 +210,7 @@ let package = Package(
.target(
/** High level functionality */
name: "Workspace",
dependencies: ["SwiftToolsSupport-auto", "Basics", "SPMBuildCore", "PackageGraph", "PackageModel", "SourceControl", "Xcodeproj"]),
dependencies: ["SwiftToolsSupport-auto", "Basics", "Configurations", "SPMBuildCore", "PackageGraph", "PackageModel", "SourceControl", "Xcodeproj"]),

// MARK: Commands

Expand Down
1 change: 1 addition & 0 deletions Sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
add_subdirectory(Basics)
add_subdirectory(Build)
add_subdirectory(Commands)
add_subdirectory(Configurations)
add_subdirectory(LLBuildManifest)
add_subdirectory(PackageCollections)
add_subdirectory(PackageCollectionsModel)
Expand Down
5 changes: 4 additions & 1 deletion Sources/Commands/SwiftPackageCollectionsTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import ArgumentParser
import Basics
import Configurations
import Foundation
import PackageCollections
import PackageModel
Expand Down Expand Up @@ -359,7 +360,9 @@ private extension JSONEncoder {

private extension ParsableCommand {
func with<T>(handler: (_ collections: PackageCollectionsProtocol) throws -> T) throws -> T {
let collections = PackageCollections()
let configuration = Configuration.Collections(fileSystem: localFileSystem) // FIXME: share across calls
let diagnosticsEngine = DiagnosticsEngine() // // FIXME: share across calls
let collections = PackageCollections(configuration: configuration, diagnosticsEngine: diagnosticsEngine)
defer {
do {
try collections.shutdown()
Expand Down
19 changes: 9 additions & 10 deletions Sources/Commands/SwiftPackageTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -886,8 +886,6 @@ extension SwiftPackageTool.Config {
var mirrorURL: String

func run(_ swiftTool: SwiftTool) throws {
let config = try swiftTool.getSwiftPMConfig()

if packageURL != nil {
swiftTool.diagnostics.emit(
warning: "'--package-url' option is deprecated; use '--original-url' instead")
Expand All @@ -898,8 +896,10 @@ extension SwiftPackageTool.Config {
throw ExitCode.failure
}

config.mirrors.set(mirrorURL: mirrorURL, forURL: originalURL)
try config.saveState()
let config = try swiftTool.getSwiftPMConfiguration()
try config.mirrors.withMapping { mapping in
mapping.set(mirrorURL: mirrorURL, forURL: originalURL)
}
}
}

Expand All @@ -920,8 +920,6 @@ extension SwiftPackageTool.Config {
var mirrorURL: String?

func run(_ swiftTool: SwiftTool) throws {
let config = try swiftTool.getSwiftPMConfig()

if packageURL != nil {
swiftTool.diagnostics.emit(
warning: "'--package-url' option is deprecated; use '--original-url' instead")
Expand All @@ -932,8 +930,10 @@ extension SwiftPackageTool.Config {
throw ExitCode.failure
}

try config.mirrors.unset(originalOrMirrorURL: originalOrMirrorURL)
try config.saveState()
let config = try swiftTool.getSwiftPMConfiguration()
try config.mirrors.withMapping { mapping in
try mapping.unset(originalOrMirrorURL: originalOrMirrorURL)
}
}
}

Expand All @@ -951,8 +951,6 @@ extension SwiftPackageTool.Config {
var originalURL: String?

func run(_ swiftTool: SwiftTool) throws {
let config = try swiftTool.getSwiftPMConfig()

if packageURL != nil {
swiftTool.diagnostics.emit(
warning: "'--package-url' option is deprecated; use '--original-url' instead")
Expand All @@ -963,6 +961,7 @@ extension SwiftPackageTool.Config {
throw ExitCode.failure
}

let config = try swiftTool.getSwiftPMConfiguration()
if let mirror = config.mirrors.mirrorURL(for: originalURL) {
print(mirror)
} else {
Expand Down
154 changes: 107 additions & 47 deletions Sources/Commands/SwiftTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,23 @@
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import ArgumentParser
import Basics
import Build
import Configurations
import Dispatch
import func Foundation.NSUserName
import class Foundation.ProcessInfo
import func Foundation.NSHomeDirectory
import Dispatch

import ArgumentParser
import TSCLibc
import TSCBasic
import TSCUtility

import PackageModel
import PackageGraph
import PackageModel
import SourceControl
import SPMBuildCore
import Build
import XCBuildSupport
import TSCBasic
import TSCLibc
import TSCUtility
import Workspace
import Basics
import XCBuildSupport

typealias Diagnostic = TSCBasic.Diagnostic

Expand Down Expand Up @@ -459,14 +458,81 @@ public class SwiftTool {
return try getPackageRoot().appending(component: "Packages")
}

// FIXME: move out of here
func resolvedFilePath() throws -> AbsolutePath {
if let multiRootPackageDataFile = options.multirootPackageDataFile {
return multiRootPackageDataFile.appending(components: "xcshareddata", "swiftpm", "Package.resolved")
}
return try getPackageRoot().appending(component: "Package.resolved")
}

func configFilePath() throws -> AbsolutePath {
// FIXME: global vs local, default locations
func getSwiftPMConfiguration() throws -> Configuration {
let fileSystem = localFileSystem
return .init(resolution: try self.getResolutionConfiguration(fileSystem: fileSystem),
manifestsLoading: try self.getManifestLoadingConfiguration(fileSystem: fileSystem),
mirrors: try self.getMirrorsConfiguration(fileSystem: fileSystem),
netrc: try self.getNetrcConfiguration(fileSystem: fileSystem),
collections: try self.getCollectionsConfiguration(fileSystem: fileSystem)
)
}

func getManifestLoadingConfiguration(fileSystem: FileSystem) throws -> Configuration.ManifestsLoading {
return .init(
cachePath: try self.resolveManifestCachePath(fileSystem: fileSystem),
isManifestSandboxEnabled: !self.options.shouldDisableSandbox
)
}

// FIXME: move out of here
func resolveManifestCachePath(fileSystem: FileSystem) throws -> AbsolutePath? {
switch (self.options.shouldDisableManifestCaching, self.options.manifestCachingMode) {
case (true, _):
// backwards compatibility
return .none
case (false, .none):
return .none
case (false, .local):
return self.buildPath
case (false, .shared):
return try self.resolveCachePath(fileSystem: fileSystem).map { Configuration.ManifestsLoading.cachePath(rootCachePath: $0) }
}
}

func getResolutionConfiguration(fileSystem: FileSystem) throws -> Configuration.Resolution {
return .init(
repositories: try getRepositoriesResolutionConfiguration(fileSystem: fileSystem),
prefetchingEnabled: options.shouldEnableResolverPrefetching,
tracingEnabled: options.enableResolverTrace,
skipUpdate: options.skipDependencyUpdate
)
}

func getRepositoriesResolutionConfiguration(fileSystem: FileSystem) throws -> Configuration.Resolution.Repositories {
return .init(
cachePath: try self.resolveRepositoriesResolutionCachePath(fileSystem: fileSystem)
)
}

// FIXME: move out of here
func resolveRepositoriesResolutionCachePath(fileSystem: FileSystem) throws -> AbsolutePath? {
guard self.options.useRepositoriesCache else {
return .none
}
// FIXME
return try self.resolveCachePath(fileSystem: fileSystem).map { Configuration.Resolution.Repositories.cachePath(rootCachePath: $0) }
}

func getMirrorsConfiguration(fileSystem: FileSystem) throws -> Configuration.Mirrors {
return .init(
fileSystem: fileSystem,
path: try self.resolveMirrorsConfigFilePath(fileSystem: fileSystem)
)
}

// FIXME: move out of here
// FIXME: global vs local, default locations
func resolveMirrorsConfigFilePath(fileSystem: FileSystem) throws -> AbsolutePath {
// Look for the override in the environment.
if let envPath = ProcessEnv.vars["SWIFTPM_MIRROR_CONFIG"] {
return try AbsolutePath(validating: envPath)
Expand All @@ -479,21 +545,21 @@ public class SwiftTool {
return try getPackageRoot().appending(components: ".swiftpm", "config")
}

func getSwiftPMConfig() throws -> Workspace.Configuration {
return try _swiftpmConfig.get()
func getNetrcConfiguration(fileSystem: FileSystem) throws -> Configuration.Netrc {
return .init(
fileSystem: fileSystem,
path: try self.resolveNetrcConfigFilePath(fileSystem: fileSystem)
)
}

private lazy var _swiftpmConfig: Result<Workspace.Configuration, Swift.Error> = {
return Result(catching: { try Workspace.Configuration(path: try configFilePath()) })
}()

func resolvedNetrcFilePath() throws -> AbsolutePath? {
// FIXME: move out of here
func resolveNetrcConfigFilePath(fileSystem: FileSystem) throws -> AbsolutePath? {
guard options.netrc ||
options.netrcFilePath != nil ||
options.netrcOptional else { return nil }

let resolvedPath: AbsolutePath = options.netrcFilePath ?? AbsolutePath("\(NSHomeDirectory())/.netrc")
guard localFileSystem.exists(resolvedPath) else {
guard fileSystem.exists(resolvedPath) else {
if !options.netrcOptional {
diagnostics.emit(error: "Cannot find mandatory .netrc file at \(resolvedPath.pathString). To make .netrc file optional, use --netrc-optional flag.")
throw ExitCode.failure
Expand All @@ -505,7 +571,20 @@ public class SwiftTool {
return resolvedPath
}

private func getCachePath(fileSystem: FileSystem = localFileSystem) throws -> AbsolutePath? {
func getCollectionsConfiguration(fileSystem: FileSystem) throws -> Configuration.Collections {
return .init(
fileSystem: fileSystem,
path: try self.resolveCollectionsFilePath(fileSystem: fileSystem)
)
}

// FIXME: move out of here
func resolveCollectionsFilePath(fileSystem: FileSystem) throws -> AbsolutePath? {
return try self.resolveConfigPath(fileSystem: fileSystem).flatMap{ $0.appending(component: "collections.json") }
}

// FIXME: move out of here
private func resolveCachePath(fileSystem: FileSystem) throws -> AbsolutePath? {
if let explicitCachePath = options.cachePath {
// Create the explicit cache path if necessary
if !fileSystem.exists(explicitCachePath) {
Expand All @@ -522,7 +601,8 @@ public class SwiftTool {
}
}

private func getConfigPath(fileSystem: FileSystem = localFileSystem) throws -> AbsolutePath? {
// FIXME: move out of here
private func resolveConfigPath(fileSystem: FileSystem) throws -> AbsolutePath? {
if let explicitConfigPath = options.configPath {
// Create the explicit config path if necessary
if !fileSystem.exists(explicitConfigPath) {
Expand All @@ -548,24 +628,17 @@ public class SwiftTool {
let isVerbose = options.verbosity != 0
let delegate = ToolWorkspaceDelegate(self.stdoutStream, isVerbose: isVerbose, diagnostics: diagnostics)
let provider = GitRepositoryProvider(processSet: processSet)
let cachePath = self.options.useRepositoriesCache ? try self.getCachePath() : .none
_ = try self.getConfigPath() // TODO: actually use this in the workspace
let isXcodeBuildSystemEnabled = self.options.buildSystem == .xcode
let workspace = Workspace(
configuration: try getSwiftPMConfiguration(),
dataPath: buildPath,
editablesPath: try editablesPath(),
pinsFile: try resolvedFilePath(),
manifestLoader: try getManifestLoader(),
toolsVersionLoader: ToolsVersionLoader(),
delegate: delegate,
config: try getSwiftPMConfig(),
repositoryProvider: provider,
netrcFilePath: try resolvedNetrcFilePath(),
additionalFileRules: isXcodeBuildSystemEnabled ? FileRuleDescription.xcbuildFileTypes : FileRuleDescription.swiftpmFileTypes,
isResolverPrefetchingEnabled: options.shouldEnableResolverPrefetching,
skipUpdate: options.skipDependencyUpdate,
enableResolverTrace: options.enableResolverTrace,
cachePath: cachePath
additionalFileRules: isXcodeBuildSystemEnabled ? FileRuleDescription.xcbuildFileTypes : FileRuleDescription.swiftpmFileTypes
)
_workspace = workspace
_workspaceDelegate = delegate
Expand Down Expand Up @@ -852,30 +925,17 @@ public class SwiftTool {

private lazy var _manifestLoader: Result<ManifestLoader, Swift.Error> = {
return Result(catching: {
let cachePath: AbsolutePath?
switch (self.options.shouldDisableManifestCaching, self.options.manifestCachingMode) {
case (true, _):
// backwards compatibility
cachePath = nil
case (false, .none):
cachePath = nil
case (false, .local):
cachePath = self.buildPath
case (false, .shared):
cachePath = try self.getCachePath().map{ $0.appending(component: "manifests") }
}

var extraManifestFlags = self.options.manifestFlags
// Disable the implicit concurrency import if the compiler in use supports it to avoid warnings if we are building against an older SDK that does not contain a Concurrency module.
if SwiftTargetBuildDescription.checkSupportedFrontendFlags(flags: ["disable-implicit-concurrency-module-import"], fs: localFileSystem) {
extraManifestFlags += ["-Xfrontend", "-disable-implicit-concurrency-module-import"]
}

let configuration = try self.getSwiftPMConfiguration()
return try ManifestLoader(
// Always use the host toolchain's resources for parsing manifest.
configuration: configuration.manifestsLoading,
// Always use the host toolchain's for parsing manifest.
toolchain: self._hostToolchain.get().configuration,
isManifestSandboxEnabled: !self.options.shouldDisableSandbox,
cacheDir: cachePath,
extraManifestFlags: extraManifestFlags
)
})
Expand Down
Loading