Skip to content

Commit

Permalink
Propagate package manifest parsing errors (#86)
Browse files Browse the repository at this point in the history
Previously, initial manifest parsing error was ignored with `try?` and `ToolchainError.missingPackageManifest` was thrown instead. Now the `package` property is no longer optional, but is of `Result` type, where the package manifest parsing error is stored and re-thrown later.

Resolves #78.
  • Loading branch information
MaxDesiatov authored Aug 19, 2020
1 parent c51f617 commit a2e928a
Showing 1 changed file with 17 additions and 19 deletions.
36 changes: 17 additions & 19 deletions Sources/SwiftToolchain/Toolchain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ enum ToolchainError: Error, CustomStringConvertible {
case noExecutableProduct
case failedToBuild(product: String)
case failedToBuildTestBundle
case missingPackage
case missingPackageManifest
case invalidVersion(version: String)

var description: String {
Expand All @@ -44,7 +44,7 @@ enum ToolchainError: Error, CustomStringConvertible {
return "Failed to build executable product \(product)"
case .failedToBuildTestBundle:
return "Failed to build the test bundle"
case .missingPackage:
case .missingPackageManifest:
return """
The `Package.swift` manifest file could not be found. Please navigate to a directory that \
contains `Package.swift` and restart.
Expand All @@ -61,17 +61,19 @@ public final class Toolchain {

private let version: String
private let swiftPath: AbsolutePath
private let package: Package?
private let package: Result<Package, Error>

public init(
for versionSpec: String? = nil,
_ fileSystem: FileSystem,
_ terminal: TerminalController
) throws {
(swiftPath, version) = try fileSystem.inferSwiftPath(from: versionSpec, terminal)
let (swiftPath, version) = try fileSystem.inferSwiftPath(from: versionSpec, terminal)
self.swiftPath = swiftPath
self.version = version
self.fileSystem = fileSystem
self.terminal = terminal
package = try? Package(with: swiftPath, terminal)
package = Result { try Package(with: swiftPath, terminal) }
}

private func inferBinPath() throws -> AbsolutePath {
Expand All @@ -86,9 +88,8 @@ public final class Toolchain {
}

private func inferDevProduct(hint: String?) throws -> String? {
guard let package = package else {
throw ToolchainError.missingPackage
}
let package = try self.package.get()

var candidateProducts = package.products
.filter { $0.type.library == nil }
.map(\.name)
Expand Down Expand Up @@ -125,8 +126,8 @@ public final class Toolchain {
}

private func inferManifestDirectory() throws -> AbsolutePath {
guard package != nil, var cwd = fileSystem.currentWorkingDirectory else {
throw ToolchainError.missingPackage
guard (try? package.get()) != nil, var cwd = fileSystem.currentWorkingDirectory else {
throw ToolchainError.missingPackageManifest
}

repeat {
Expand All @@ -138,13 +139,11 @@ public final class Toolchain {
cwd = cwd.parentDirectory
} while !cwd.isRoot

throw ToolchainError.missingPackage
throw ToolchainError.missingPackageManifest
}

public func inferSourcesPaths() throws -> [AbsolutePath] {
guard let package = package else {
throw ToolchainError.missingPackage
}
let package = try self.package.get()

let targetPaths = package.targets.compactMap { target -> String? in
guard let path = target.path else {
Expand Down Expand Up @@ -177,8 +176,9 @@ public final class Toolchain {
guard let product = try inferDevProduct(hint: product)
else { throw ToolchainError.noExecutableProduct }

if let package = package,
let jsKit = package.dependencies?.first(where: { $0.name == "JavaScriptKit" }),
let package = try self.package.get()

if let jsKit = package.dependencies?.first(where: { $0.name == "JavaScriptKit" }),
jsKit.requirement.revision != ["c90e82f"] {
let version = jsKit.requirement.revision.flatMap { " (\($0[0]))" } ?? ""

Expand Down Expand Up @@ -221,9 +221,7 @@ public final class Toolchain {

/// Returns an absolute path to the resulting test bundle
public func buildTestBundle(isRelease: Bool) throws -> AbsolutePath {
guard let package = package else {
throw ToolchainError.missingPackage
}
let package = try self.package.get()
let binPath = try inferBinPath()
let testBundlePath = binPath.appending(component: "\(package.name)PackageTests.xctest")
terminal.logLookup("- test bundle to run: ", testBundlePath.pathString)
Expand Down

0 comments on commit a2e928a

Please sign in to comment.