Skip to content

Reduce use of AbsolutePath with precondition failure #5797

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 1 commit into from
Oct 19, 2022
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
2 changes: 1 addition & 1 deletion Examples/package-info/Sources/package-info/example.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct Example {

// We need a package to work with.
// This computes the path of this package root based on the file location
let packagePath = AbsolutePath(#file).parentDirectory.parentDirectory.parentDirectory
let packagePath = try AbsolutePath(validating: #file).parentDirectory.parentDirectory.parentDirectory

// LOADING
// =======
Expand Down
78 changes: 47 additions & 31 deletions Sources/Basics/FileSystem+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ import TSCBasic
extension FileSystem {
/// SwiftPM directory under user's home directory (~/.swiftpm)
public var dotSwiftPM: AbsolutePath {
self.homeDirectory.appending(component: ".swiftpm")
get throws {
return try self.homeDirectory.appending(component: ".swiftpm")
}
}

fileprivate var idiomaticSwiftPMDirectory: AbsolutePath? {
return FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first.flatMap { AbsolutePath($0.path) }?.appending(component: "org.swift.swiftpm")
get throws {
return try FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first.flatMap { try AbsolutePath(validating: $0.path) }?.appending(component: "org.swift.swiftpm")
}
}
}

Expand All @@ -39,33 +43,37 @@ extension FileSystem {

/// SwiftPM cache directory under user's caches directory (if exists)
public var swiftPMCacheDirectory: AbsolutePath {
if let path = self.idiomaticUserCacheDirectory {
return path.appending(component: "org.swift.swiftpm")
} else {
return self.dotSwiftPMCachesDirectory
get throws {
if let path = self.idiomaticUserCacheDirectory {
return path.appending(component: "org.swift.swiftpm")
} else {
return try self.dotSwiftPMCachesDirectory
}
}
}

fileprivate var dotSwiftPMCachesDirectory: AbsolutePath {
return self.dotSwiftPM.appending(component: "cache")
get throws {
return try self.dotSwiftPM.appending(component: "cache")
}
}
}

extension FileSystem {
public func getOrCreateSwiftPMCacheDirectory() throws -> AbsolutePath {
let idiomaticCacheDirectory = self.swiftPMCacheDirectory
let idiomaticCacheDirectory = try self.swiftPMCacheDirectory
// Create idiomatic if necessary
if !self.exists(idiomaticCacheDirectory) {
try self.createDirectory(idiomaticCacheDirectory, recursive: true)
}
// Create ~/.swiftpm if necessary
if !self.exists(self.dotSwiftPM) {
if !self.exists(try self.dotSwiftPM) {
try self.createDirectory(self.dotSwiftPM, recursive: true)
}
// Create ~/.swiftpm/cache symlink if necessary
// locking ~/.swiftpm to protect from concurrent access
try self.withLock(on: self.dotSwiftPM, type: .exclusive) {
if !self.exists(self.dotSwiftPMCachesDirectory, followSymlink: false) {
if !self.exists(try self.dotSwiftPMCachesDirectory, followSymlink: false) {
try self.createSymbolicLink(dotSwiftPMCachesDirectory, pointingAt: idiomaticCacheDirectory, relative: false)
}
}
Expand All @@ -78,21 +86,25 @@ extension FileSystem {
extension FileSystem {
/// SwiftPM config directory under user's config directory (if exists)
public var swiftPMConfigurationDirectory: AbsolutePath {
if let path = self.idiomaticSwiftPMDirectory {
return path.appending(component: "configuration")
} else {
return self.dotSwiftPMConfigurationDirectory
get throws {
if let path = try self.idiomaticSwiftPMDirectory {
return path.appending(component: "configuration")
} else {
return try self.dotSwiftPMConfigurationDirectory
}
}
}

fileprivate var dotSwiftPMConfigurationDirectory: AbsolutePath {
return self.dotSwiftPM.appending(component: "configuration")
get throws {
return try self.dotSwiftPM.appending(component: "configuration")
}
}
}

extension FileSystem {
public func getOrCreateSwiftPMConfigurationDirectory(warningHandler: @escaping (String) -> Void) throws -> AbsolutePath {
let idiomaticConfigurationDirectory = self.swiftPMConfigurationDirectory
let idiomaticConfigurationDirectory = try self.swiftPMConfigurationDirectory

// temporary 5.6, remove on next version: transition from previous configuration location
if !self.exists(idiomaticConfigurationDirectory) {
Expand All @@ -116,7 +128,7 @@ extension FileSystem {
}

// in the case where ~/.swiftpm/configuration is not the idiomatic location (eg on macOS where its /Users/<user>/Library/org.swift.swiftpm/configuration)
if idiomaticConfigurationDirectory != self.dotSwiftPMConfigurationDirectory {
if try idiomaticConfigurationDirectory != self.dotSwiftPMConfigurationDirectory {
// copy the configuration files from old location (eg /Users/<user>/Library/org.swift.swiftpm) to new one (eg /Users/<user>/Library/org.swift.swiftpm/configuration)
// but leave them there for backwards compatibility (eg older xcode)
let oldConfigDirectory = idiomaticConfigurationDirectory.parentDirectory
Expand All @@ -130,7 +142,7 @@ extension FileSystem {
} else {
// copy the configuration files from old location (~/.swiftpm/config) to new one (~/.swiftpm/configuration)
// but leave them there for backwards compatibility (eg older toolchain)
let oldConfigDirectory = self.dotSwiftPM.appending(component: "config")
let oldConfigDirectory = try self.dotSwiftPM.appending(component: "config")
if self.exists(oldConfigDirectory, followSymlink: false) && self.isDirectory(oldConfigDirectory) {
let configurationFiles = try self.getDirectoryContents(oldConfigDirectory)
.map{ oldConfigDirectory.appending(component: $0) }
Expand All @@ -145,13 +157,13 @@ extension FileSystem {
try self.createDirectory(idiomaticConfigurationDirectory, recursive: true)
}
// Create ~/.swiftpm if necessary
if !self.exists(self.dotSwiftPM) {
if !self.exists(try self.dotSwiftPM) {
try self.createDirectory(self.dotSwiftPM, recursive: true)
}
// Create ~/.swiftpm/configuration symlink if necessary
// locking ~/.swiftpm to protect from concurrent access
try self.withLock(on: self.dotSwiftPM, type: .exclusive) {
if !self.exists(self.dotSwiftPMConfigurationDirectory, followSymlink: false) {
if !self.exists(try self.dotSwiftPMConfigurationDirectory, followSymlink: false) {
try self.createSymbolicLink(dotSwiftPMConfigurationDirectory, pointingAt: idiomaticConfigurationDirectory, relative: false)
}
}
Expand All @@ -165,26 +177,30 @@ extension FileSystem {
extension FileSystem {
/// SwiftPM security directory under user's security directory (if exists)
public var swiftPMSecurityDirectory: AbsolutePath {
if let path = self.idiomaticSwiftPMDirectory {
return path.appending(component: "security")
} else {
return self.dotSwiftPMSecurityDirectory
get throws {
if let path = try self.idiomaticSwiftPMDirectory {
return path.appending(component: "security")
} else {
return try self.dotSwiftPMSecurityDirectory
}
}
}

fileprivate var dotSwiftPMSecurityDirectory: AbsolutePath {
return self.dotSwiftPM.appending(component: "security")
get throws {
return try self.dotSwiftPM.appending(component: "security")
}
}
}

extension FileSystem {
public func getOrCreateSwiftPMSecurityDirectory() throws -> AbsolutePath {
let idiomaticSecurityDirectory = self.swiftPMSecurityDirectory
let idiomaticSecurityDirectory = try self.swiftPMSecurityDirectory

// temporary 5.6, remove on next version: transition from ~/.swiftpm/security to idiomatic location + symbolic link
if idiomaticSecurityDirectory != self.dotSwiftPMSecurityDirectory &&
self.exists(self.dotSwiftPMSecurityDirectory) &&
self.isDirectory(self.dotSwiftPMSecurityDirectory) {
if try idiomaticSecurityDirectory != self.dotSwiftPMSecurityDirectory &&
self.exists(try self.dotSwiftPMSecurityDirectory) &&
self.isDirectory(try self.dotSwiftPMSecurityDirectory) {
try self.removeFileTree(self.dotSwiftPMSecurityDirectory)
}
// ~temporary 5.6 migration
Expand All @@ -194,13 +210,13 @@ extension FileSystem {
try self.createDirectory(idiomaticSecurityDirectory, recursive: true)
}
// Create ~/.swiftpm if necessary
if !self.exists(self.dotSwiftPM) {
if !self.exists(try self.dotSwiftPM) {
try self.createDirectory(self.dotSwiftPM, recursive: true)
}
// Create ~/.swiftpm/security symlink if necessary
// locking ~/.swiftpm to protect from concurrent access
try self.withLock(on: self.dotSwiftPM, type: .exclusive) {
if !self.exists(self.dotSwiftPMSecurityDirectory, followSymlink: false) {
if !self.exists(try self.dotSwiftPMSecurityDirectory, followSymlink: false) {
try self.createSymbolicLink(dotSwiftPMSecurityDirectory, pointingAt: idiomaticSecurityDirectory, relative: false)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Basics/HTPClient+URLSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ private class DownloadTaskManager: NSObject, URLSessionDownloadDelegate {
}

do {
try task.fileSystem.move(from: AbsolutePath(location.path), to: task.destination)
try task.fileSystem.move(from: AbsolutePath(validating: location.path), to: task.destination)
} catch {
task.moveFileError = error
}
Expand Down
14 changes: 7 additions & 7 deletions Sources/Basics/Sandbox.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ public enum Sandbox {
strictness: Strictness = .default,
writableDirectories: [AbsolutePath] = [],
readOnlyDirectories: [AbsolutePath] = []
) -> [String] {
) throws -> [String] {
#if os(macOS)
let profile = macOSSandboxProfile(strictness: strictness, writableDirectories: writableDirectories, readOnlyDirectories: readOnlyDirectories)
let profile = try macOSSandboxProfile(strictness: strictness, writableDirectories: writableDirectories, readOnlyDirectories: readOnlyDirectories)
return ["/usr/bin/sandbox-exec", "-p", profile] + command
#else
// rdar://40235432, rdar://75636874 tracks implementing sandboxes for other platforms.
Expand All @@ -59,7 +59,7 @@ fileprivate func macOSSandboxProfile(
strictness: Sandbox.Strictness,
writableDirectories: [AbsolutePath],
readOnlyDirectories: [AbsolutePath]
) -> String {
) throws -> String {
var contents = "(version 1)\n"

// Deny everything by default.
Expand Down Expand Up @@ -94,7 +94,7 @@ fileprivate func macOSSandboxProfile(
else if strictness == .writableTemporaryDirectory {
// Add `subpath` expressions for the regular and the Foundation temporary directories.
for tmpDir in ["/tmp", NSTemporaryDirectory()] {
writableDirectoriesExpression += ["(subpath \(resolveSymlinks(AbsolutePath(tmpDir)).quotedAsSubpathForSandboxProfile))"]
writableDirectoriesExpression += try ["(subpath \(resolveSymlinks(AbsolutePath(validating: tmpDir)).quotedAsSubpathForSandboxProfile))"]
}
}

Expand All @@ -111,7 +111,7 @@ fileprivate func macOSSandboxProfile(
if readOnlyDirectories.count > 0 {
contents += "(deny file-write*\n"
for path in readOnlyDirectories {
contents += " (subpath \(resolveSymlinks(path).quotedAsSubpathForSandboxProfile))\n"
contents += " (subpath \(try resolveSymlinks(path).quotedAsSubpathForSandboxProfile))\n"
}
contents += ")\n"
}
Expand All @@ -120,7 +120,7 @@ fileprivate func macOSSandboxProfile(
if writableDirectories.count > 0 {
contents += "(allow file-write*\n"
for path in writableDirectories {
contents += " (subpath \(resolveSymlinks(path).quotedAsSubpathForSandboxProfile))\n"
contents += " (subpath \(try resolveSymlinks(path).quotedAsSubpathForSandboxProfile))\n"
}
contents += ")\n"
}
Expand All @@ -139,6 +139,6 @@ fileprivate extension AbsolutePath {
}

extension TSCUtility.Platform {
fileprivate static let threadSafeDarwinCacheDirectories = ThreadSafeArrayStore<AbsolutePath>(Self.darwinCacheDirectories())
fileprivate static let threadSafeDarwinCacheDirectories = ThreadSafeArrayStore<AbsolutePath>((try? Self.darwinCacheDirectories()) ?? [])
}
#endif
4 changes: 2 additions & 2 deletions Sources/Basics/TemporaryFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,13 @@ private func createTemporaryDirectory(fileSystem: FileSystem, dir: AbsolutePath?

let randomSuffix = String((0..<6).map { _ in letters.randomElement()! })

let tempDirectory = dir ?? fileSystem.tempDirectory
let tempDirectory = try dir ?? fileSystem.tempDirectory
guard fileSystem.isDirectory(tempDirectory) else {
throw TempFileError.couldNotFindTmpDir(tempDirectory.pathString)
}

// Construct path to the temporary directory.
let templatePath = AbsolutePath(prefix + ".\(randomSuffix)", relativeTo: tempDirectory)
let templatePath = try AbsolutePath(validating: prefix + ".\(randomSuffix)", relativeTo: tempDirectory)

try fileSystem.createDirectory(templatePath, recursive: true)
return templatePath
Expand Down
2 changes: 1 addition & 1 deletion Sources/Build/BuildOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
// TODO: We need to also use any working directory, but that support isn't yet available on all platforms at a lower level.
var commandLine = [command.configuration.executable.pathString] + command.configuration.arguments
if !self.disableSandboxForPluginCommands {
commandLine = Sandbox.apply(command: commandLine, strictness: .writableTemporaryDirectory, writableDirectories: [pluginResult.pluginOutputDirectory])
commandLine = try Sandbox.apply(command: commandLine, strictness: .writableTemporaryDirectory, writableDirectories: [pluginResult.pluginOutputDirectory])
}
let processResult = try TSCBasic.Process.popen(arguments: commandLine, environment: command.configuration.environment)
let output = try processResult.utf8Output() + processResult.utf8stderrOutput()
Expand Down
11 changes: 6 additions & 5 deletions Sources/Build/BuildOperationBuildSystemDelegateHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ final class TestDiscoveryCommand: CustomLLBuildCommand, TestBuildCommand {
let store = try IndexStore.open(store: index, api: api)

// FIXME: We can speed this up by having one llbuild command per object file.
let tests = try store.listTests(in: tool.inputs.map{ AbsolutePath($0.name) })
let tests = try store.listTests(in: tool.inputs.map{ try AbsolutePath(validating: $0.name) })

let outputs = tool.outputs.compactMap{ try? AbsolutePath(validating: $0.name) }
let testsByModule = Dictionary(grouping: tests, by: { $0.module.spm_mangledToC99ExtendedIdentifier() })
Expand Down Expand Up @@ -445,7 +445,7 @@ public final class BuildExecutionContext {
.appending(component: "libIndexStore.dll")
#else
let ext = buildParameters.hostTriple.dynamicLibraryExtension
let indexStoreLib = buildParameters.toolchain.toolchainLibDir.appending(component: "libIndexStore" + ext)
let indexStoreLib = try buildParameters.toolchain.toolchainLibDir.appending(component: "libIndexStore" + ext)
#endif
return try IndexStoreAPI(dylib: indexStoreLib)
}
Expand Down Expand Up @@ -489,8 +489,8 @@ final class CopyCommand: CustomLLBuildCommand {
throw StringError("command \(command.name) not registered")
}

let input = AbsolutePath(tool.inputs[0].name)
let output = AbsolutePath(tool.outputs[0].name)
let input = try AbsolutePath(validating: tool.inputs[0].name)
let output = try AbsolutePath(validating: tool.outputs[0].name)
try self.context.fileSystem.createDirectory(output.parentDirectory, recursive: true)
try self.context.fileSystem.removeFileTree(output)
try self.context.fileSystem.copy(from: input, to: output)
Expand Down Expand Up @@ -903,7 +903,8 @@ fileprivate struct CommandTaskTracker {
switch message.name {
case "compile":
if let sourceFile = info.inputs.first {
return "Compiling \(targetName) \(AbsolutePath(sourceFile).components.last!)"
let sourceFilePath = try! AbsolutePath(validating: sourceFile)
return "Compiling \(targetName) \(sourceFilePath.components.last!)"
}
case "link":
return "Linking \(targetName)"
Expand Down
Loading