From 2c26d33c07ffa2c527be1d13ea12107e8010aebb Mon Sep 17 00:00:00 2001 From: Sam Deane Date: Wed, 4 Sep 2024 22:21:17 +0100 Subject: [PATCH] Cleaned up errors --- .../Commands/AppcastCommand.swift | 26 +++++++------- .../Commands/ArchiveCommand.swift | 36 +++++++++---------- .../Commands/CompressCommand.swift | 6 ++-- .../ReleaseTools/Commands/ExportCommand.swift | 8 ++--- .../Commands/NotarizeCommand.swift | 16 ++++----- .../Commands/PublishCommand.swift | 16 ++++----- .../Commands/UpdateBuildCommand.swift | 21 ++++++----- .../ReleaseTools/Commands/UploadCommand.swift | 12 +++---- .../Commands/WaitForNotarizationCommand.swift | 26 +++++++------- 9 files changed, 82 insertions(+), 85 deletions(-) diff --git a/Sources/ReleaseTools/Commands/AppcastCommand.swift b/Sources/ReleaseTools/Commands/AppcastCommand.swift index ed8bc2c..635ef1b 100644 --- a/Sources/ReleaseTools/Commands/AppcastCommand.swift +++ b/Sources/ReleaseTools/Commands/AppcastCommand.swift @@ -8,19 +8,19 @@ import Foundation import Runner enum AppcastError: Error, CustomStringConvertible { - case buildAppcastGeneratorFailed(_ output: String) - case appcastGeneratorFailed(_ result: Runner.RunningProcess) - case keyGenerationFailed(_ result: Runner.RunningProcess) - case keyImportFailed(_ result: Runner.RunningProcess) + case buildAppcastGeneratorFailed + case appcastGeneratorFailed + case keyGenerationFailed + case keyImportFailed case generatedKeys(_ name: String) public var description: String { switch self { - case .buildAppcastGeneratorFailed(let output): - return "Failed to build the generate_appcast tool.\n\(output)" - case .appcastGeneratorFailed(let result): return "Failed to generate the appcast.\n\(result)" - case .keyGenerationFailed(let result): return "Failed to generate appcast keys.\n\(result)" - case .keyImportFailed(let result): return "Failed to import appcast keys.\n\(result)" + case .buildAppcastGeneratorFailed: + return "Failed to build the generate_appcast tool." + case .appcastGeneratorFailed: return "Failed to generate the appcast." + case .keyGenerationFailed: return "Failed to generate appcast keys." + case .keyImportFailed: return "Failed to import appcast keys." case .generatedKeys(let name): return """ The appcast private key was missing, so we've generated one. @@ -68,7 +68,7 @@ struct AppcastCommand: AsyncParsableCommand { "build", "-workspace", parsed.workspace, "-scheme", "generate_appcast", "BUILD_DIR=\(buildURL.path)", ]) - try await result.throwIfFailed(AppcastError.buildAppcastGeneratorFailed(await String(result.stderr))) + try await result.throwIfFailed(AppcastError.buildAppcastGeneratorFailed) let workspaceName = URL(fileURLWithPath: parsed.workspace).deletingPathExtension() .lastPathComponent @@ -80,7 +80,7 @@ struct AppcastCommand: AsyncParsableCommand { if state != .succeeded { let output = await String(genResult.stdout) if !output.contains("Unable to load DSA private key") { - throw AppcastError.appcastGeneratorFailed(genResult) + throw AppcastError.appcastGeneratorFailed } } @@ -88,7 +88,7 @@ struct AppcastCommand: AsyncParsableCommand { let keygen = Runner(for: URL(fileURLWithPath: "Dependencies/Sparkle/bin/generate_keys")) let keygenResult = try keygen.run([]) - try await keygenResult.throwIfFailed(AppcastError.keyGenerationFailed(keygenResult)) + try await keygenResult.throwIfFailed(AppcastError.keyGenerationFailed) parsed.log("Importing Key.") @@ -96,7 +96,7 @@ struct AppcastCommand: AsyncParsableCommand { let importResult = try security.run([ "import", "dsa_priv.pem", "-a", "labl", "\(parsed.scheme) Sparkle Key", ]) - try await importResult.throwIfFailed(AppcastError.keyImportFailed(importResult)) + try await importResult.throwIfFailed(AppcastError.keyImportFailed) parsed.log("Moving Public Key.") diff --git a/Sources/ReleaseTools/Commands/ArchiveCommand.swift b/Sources/ReleaseTools/Commands/ArchiveCommand.swift index 319889e..3320129 100644 --- a/Sources/ReleaseTools/Commands/ArchiveCommand.swift +++ b/Sources/ReleaseTools/Commands/ArchiveCommand.swift @@ -16,12 +16,14 @@ struct SchemesSpec: Decodable { let workspace: WorkspaceSpec } -enum ArchiveError: Error { - case archiveFailed(_ output: String) +enum ArchiveError: RunnerError { + case archiveFailed - public var description: String { + func description(for session: Runner.Session) async -> String { + async let stdout = String(session.stdout) + async let stderr = String(session.stderr) switch self { - case .archiveFailed(let output): return "Archiving failed.\n\(output)" + case .archiveFailed: return "Archiving failed.\n\n\(await stderr)" } } } @@ -51,8 +53,6 @@ struct ArchiveCommand: AsyncParsableCommand { } static func archive(parsed: OptionParser, xcconfig: String? = nil) async throws { - parsed.showOutput = true // TEMPORARY OVERRIDE THE OPTION BECAUSE WE HANG WITHOUT IT - parsed.log("Updating Version Info") let infoHeaderPath = "\(parsed.buildURL.path)/VersionInfo.h" let build = try await UpdateBuildCommand.generateHeader( @@ -71,20 +71,20 @@ struct ArchiveCommand: AsyncParsableCommand { } switch parsed.platform { - case "iOS": - args.append(contentsOf: ["-destination", "generic/platform=iOS"]) - case "tvOS": - args.append(contentsOf: ["-destination", "generic/platform=tvOS"]) - case "watchOS": - args.append(contentsOf: ["-destination", "generic/platform=watchOS"]) - default: - break + case "iOS": + args.append(contentsOf: ["-destination", "generic/platform=iOS"]) + case "tvOS": + args.append(contentsOf: ["-destination", "generic/platform=tvOS"]) + case "watchOS": + args.append(contentsOf: ["-destination", "generic/platform=watchOS"]) + default: + break } - let outMode: Runner.Mode = parsed.verbose ? .forward : .capture - let errMode: Runner.Mode = parsed.verbose ? .both : .capture - let result = try xcode.run(args, stdoutMode: .capture, stderrMode: errMode) - try await result.throwIfFailed(ArchiveError.archiveFailed(await String(result.stderr))) + let outMode: Runner.Mode = parsed.showOutput ? .both : .capture + let errMode: Runner.Mode = parsed.showOutput ? .both : .capture + let result = try xcode.run(args, stdoutMode: outMode, stderrMode: errMode) + try await result.throwIfFailed(ArchiveError.archiveFailed) parsed.log("Archived scheme \(parsed.scheme).") } } diff --git a/Sources/ReleaseTools/Commands/CompressCommand.swift b/Sources/ReleaseTools/Commands/CompressCommand.swift index c80bf49..02abfee 100644 --- a/Sources/ReleaseTools/Commands/CompressCommand.swift +++ b/Sources/ReleaseTools/Commands/CompressCommand.swift @@ -8,11 +8,11 @@ import Foundation import Runner enum CompressError: Error { - case compressFailed(_ output: String) + case compressFailed public var description: String { switch self { - case .compressFailed(let output): return "Compressing failed.\n\(output)" + case .compressFailed: return "Compressing failed." } } } @@ -45,7 +45,7 @@ struct CompressCommand: AsyncParsableCommand { let destination = updates.url.appendingPathComponent(parsed.archive.versionedZipName) let result = try ditto.zip(stapledAppURL, as: destination) - try await result.throwIfFailed(CompressError.compressFailed(await String(result.stderr))) + try await result.throwIfFailed(CompressError.compressFailed) parsed.log( "Saving copy of archive to \(website.websiteURL.path) as \(parsed.archive.unversionedZipName)." diff --git a/Sources/ReleaseTools/Commands/ExportCommand.swift b/Sources/ReleaseTools/Commands/ExportCommand.swift index ce06ce6..e3d7281 100644 --- a/Sources/ReleaseTools/Commands/ExportCommand.swift +++ b/Sources/ReleaseTools/Commands/ExportCommand.swift @@ -7,12 +7,12 @@ import ArgumentParser import Foundation enum ExportError: Error { - case exportFailed(_ output: String) - case writingOptionsFailed(_ output: Error) + case exportFailed + case writingOptionsFailed(Error) public var description: String { switch self { - case .exportFailed(let output): return "Exporting failed.\n\(output)" + case .exportFailed: return "Exporting failed." case .writingOptionsFailed(let error): return "Writing export options file failed.\n\(error)" } } @@ -67,6 +67,6 @@ struct ExportCommand: AsyncParsableCommand { "-allowProvisioningUpdates", ]) - try await result.throwIfFailed(ExportError.exportFailed(await String(result.stderr))) + try await result.throwIfFailed(ExportError.exportFailed) } } diff --git a/Sources/ReleaseTools/Commands/NotarizeCommand.swift b/Sources/ReleaseTools/Commands/NotarizeCommand.swift index adb30a5..46345bb 100644 --- a/Sources/ReleaseTools/Commands/NotarizeCommand.swift +++ b/Sources/ReleaseTools/Commands/NotarizeCommand.swift @@ -8,16 +8,14 @@ import Foundation import Runner enum NotarizeError: Error, Sendable { - case compressingFailed(_ result: Runner.RunningProcess) - case notarizingFailed( - _ result: Runner.RunningProcess - ) - case savingNotarizationReceiptFailed(_ error: Error) + case compressingFailed + case notarizingFailed + case savingNotarizationReceiptFailed(Error) public var description: String { switch self { - case .compressingFailed(let result): return "Compressing failed.\n\(result)" - case .notarizingFailed(let result): return "Notarizing failed.\n\(result)" + case .compressingFailed: return "Compressing failed." + case .notarizingFailed: return "Notarizing failed." case .savingNotarizationReceiptFailed(let error): return "Saving notarization receipt failed.\n\(error)" } @@ -55,7 +53,7 @@ struct NotarizeCommand: AsyncParsableCommand { let ditto = DittoRunner(parsed: parsed) let zipResult = try ditto.zip(parsed.exportedAppURL, as: parsed.exportedZipURL) - try await zipResult.throwIfFailed(NotarizeError.compressingFailed(zipResult)) + try await zipResult.throwIfFailed(NotarizeError.compressingFailed) parsed.log("Uploading \(parsed.versionTag) to notarization service.") let xcrun = XCRunRunner(parsed: parsed) @@ -64,7 +62,7 @@ struct NotarizeCommand: AsyncParsableCommand { parsed.user, "--password", "@keychain:AC_PASSWORD", "--team-id", parsed.archive.team, "--file", parsed.exportedZipURL.path, "--output-format", "xml", ]) - try await result.throwIfFailed(NotarizeError.notarizingFailed(result)) + try await result.throwIfFailed(NotarizeError.notarizingFailed) parsed.log("Requested notarization.") do { diff --git a/Sources/ReleaseTools/Commands/PublishCommand.swift b/Sources/ReleaseTools/Commands/PublishCommand.swift index ff0fe20..c079b31 100644 --- a/Sources/ReleaseTools/Commands/PublishCommand.swift +++ b/Sources/ReleaseTools/Commands/PublishCommand.swift @@ -8,14 +8,14 @@ import Foundation import Runner enum PublishError: Error { - case commitFailed(_ result: Runner.RunningProcess) - case pushFailed(_ result: Runner.RunningProcess) + case commitFailed + case pushFailed public var description: String { switch self { - case .commitFailed(let result): - return "Failed to commit the appcast feed and updates.\n\(result)" - case .pushFailed(let result): return "Failed to push the appcast feed and updates.\n\(result)" + case .commitFailed: + return "Failed to commit the appcast feed and updates." + case .pushFailed: return "Failed to push the appcast feed and updates." } } } @@ -46,14 +46,14 @@ struct PublishCommand: AsyncParsableCommand { parsed.log("Committing updates.") var result = try git.run(["add", updates.path]) - try await result.throwIfFailed(PublishError.commitFailed(result)) + try await result.throwIfFailed(PublishError.commitFailed) let message = "v\(parsed.archive.version), build \(parsed.archive.build)" result = try git.run(["commit", "-a", "-m", message]) - try await result.throwIfFailed(PublishError.commitFailed(result)) + try await result.throwIfFailed(PublishError.commitFailed) parsed.log("Pushing updates.") let pushResult = try git.run(["push"]) - try await pushResult.throwIfFailed(PublishError.pushFailed(pushResult)) + try await pushResult.throwIfFailed(PublishError.pushFailed) } } diff --git a/Sources/ReleaseTools/Commands/UpdateBuildCommand.swift b/Sources/ReleaseTools/Commands/UpdateBuildCommand.swift index a1a7614..968aae2 100644 --- a/Sources/ReleaseTools/Commands/UpdateBuildCommand.swift +++ b/Sources/ReleaseTools/Commands/UpdateBuildCommand.swift @@ -11,19 +11,18 @@ import Resources import Runner enum UpdateBuildError: Error { - case gettingBuildFailed(_ result: Runner.RunningProcess) - case gettingCommitFailed(_ result: Runner.RunningProcess) + case gettingBuildFailed + case gettingCommitFailed case writingConfigFailed - case updatingIndexFailed(_ result: Runner.RunningProcess) + case updatingIndexFailed public var description: String { switch self { - case .gettingBuildFailed(let result): - return "Failed to get the build number from git.\n\(result)" - case .gettingCommitFailed(let result): return "Failed to get the commit from git.\n\(result)" + case .gettingBuildFailed: + return "Failed to get the build number from git." + case .gettingCommitFailed: return "Failed to get the commit from git." case .writingConfigFailed: return "Failed to write the config file." - case .updatingIndexFailed(let result): - return "Failed to tell git to ignore the config file.\n\(result)" + case .updatingIndexFailed: return "Failed to tell git to ignore the config file." } } } @@ -64,12 +63,12 @@ struct UpdateBuildCommand: AsyncParsableCommand { chdir(url.path) var result = try git.run(["rev-list", "--count", "HEAD"]) - try await result.throwIfFailed(UpdateBuildError.gettingBuildFailed(result)) + try await result.throwIfFailed(UpdateBuildError.gettingBuildFailed) let build = await String(result.stdout).trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) result = try git.run(["rev-list", "--max-count", "1", "HEAD"]) - try await result.throwIfFailed(UpdateBuildError.gettingCommitFailed(result)) + try await result.throwIfFailed(UpdateBuildError.gettingCommitFailed) let commit = await String(result.stdout).trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) return (build, commit) @@ -146,7 +145,7 @@ struct UpdateBuildCommand: AsyncParsableCommand { } let result = try git.run(["update-index", "--assume-unchanged", configURL.path]) - try await result.throwIfFailed(UpdateBuildError.updatingIndexFailed(result)) + try await result.throwIfFailed(UpdateBuildError.updatingIndexFailed) } } } diff --git a/Sources/ReleaseTools/Commands/UploadCommand.swift b/Sources/ReleaseTools/Commands/UploadCommand.swift index 1218d4a..de1a1f7 100644 --- a/Sources/ReleaseTools/Commands/UploadCommand.swift +++ b/Sources/ReleaseTools/Commands/UploadCommand.swift @@ -8,12 +8,12 @@ import Foundation import Runner enum UploadError: Error { - case uploadingFailed(_ result: Runner.RunningProcess) - case savingUploadReceiptFailed(_ error: Error) + case uploadingFailed + case savingUploadReceiptFailed(Error) public var description: String { switch self { - case .uploadingFailed(let result): return "Uploading failed.\n\(result)" + case .uploadingFailed: return "Uploading failed." case .savingUploadReceiptFailed(let error): return "Saving upload receipt failed.\n\(error)" } } @@ -52,7 +52,7 @@ struct UploadCommand: AsyncParsableCommand { static func upload(parsed: OptionParser) async throws { parsed.log("Uploading \(parsed.versionTag) to Apple Connect.") let xcrun = XCRunRunner(parsed: parsed) - let uploadResult: Runner.RunningProcess + let uploadResult: Runner.Session if parsed.apiKey.isEmpty { // use username & password uploadResult = try xcrun.run([ @@ -67,7 +67,7 @@ struct UploadCommand: AsyncParsableCommand { ]) } - try await uploadResult.throwIfFailed(UploadError.uploadingFailed(uploadResult)) + try await uploadResult.throwIfFailed(UploadError.uploadingFailed) parsed.log("Finished uploading.") do { @@ -83,6 +83,6 @@ struct UploadCommand: AsyncParsableCommand { let tagResult = try git.run([ "tag", parsed.versionTag, "-m", "Uploaded with \(CommandLine.name)", ]) - try await tagResult.throwIfFailed(GeneralError.taggingFailed(tagResult)) + try await tagResult.throwIfFailed(GeneralError.taggingFailed) } } diff --git a/Sources/ReleaseTools/Commands/WaitForNotarizationCommand.swift b/Sources/ReleaseTools/Commands/WaitForNotarizationCommand.swift index d601696..07ca932 100644 --- a/Sources/ReleaseTools/Commands/WaitForNotarizationCommand.swift +++ b/Sources/ReleaseTools/Commands/WaitForNotarizationCommand.swift @@ -9,24 +9,24 @@ import Foundation import Runner enum WaitForNotarizationError: Error { - case fetchingNotarizationStatusFailed(_ result: Runner.RunningProcess) - case fetchingNotarizationStatusThrew(_ error: Error) + case fetchingNotarizationStatusFailed + case fetchingNotarizationStatusThrew(Error) case loadingNotarizationReceiptFailed - case notarizationFailed(_ output: String) - case exportingNotarizedAppFailed(_ result: Runner.RunningProcess) - case exportingNotarizedAppThrew(_ error: Error) + case notarizationFailed(String) + case exportingNotarizedAppFailed + case exportingNotarizedAppThrew(Error) case missingArchive public var description: String { switch self { - case .fetchingNotarizationStatusFailed(let result): - return "Fetching notarization status failed.\n\(result)" + case .fetchingNotarizationStatusFailed: + return "Fetching notarization status failed." case .fetchingNotarizationStatusThrew(let error): return "Fetching notarization status failed.\n\(error)" case .loadingNotarizationReceiptFailed: return "Loading notarization receipt failed." - case .notarizationFailed(let output): return "Notarization failed.\n\(output)" - case .exportingNotarizedAppFailed(let result): - return "Exporting notarized app failed.\n\(result)" + case .notarizationFailed: return "Notarization failed." + case .exportingNotarizedAppFailed: + return "Exporting notarized app failed." case .exportingNotarizedAppThrew(let error): return "Exporting notarized app failed.\n\(error)" case .missingArchive: return "Exporting notarized app couldn't find archive." } @@ -82,7 +82,7 @@ struct WaitForNotarizationCommand: AsyncParsableCommand { let tagResult = try git.run([ "tag", parsed.versionTag, "-f", "-m", "Uploaded with \(CommandLine.name)", ]) - try await tagResult.throwIfFailed(GeneralError.taggingFailed(tagResult)) + try await tagResult.throwIfFailed(GeneralError.taggingFailed) } func savedNotarizationReceipt(parsed: OptionParser) -> String? { @@ -110,7 +110,7 @@ struct WaitForNotarizationCommand: AsyncParsableCommand { try? fm.copyItem(at: parsed.exportedAppURL, to: stapledAppURL) let xcrun = XCRunRunner(parsed: parsed) let result = try xcrun.run(["stapler", "staple", stapledAppURL.path]) - try await result.throwIfFailed(WaitForNotarizationError.exportingNotarizedAppFailed(result)) + try await result.throwIfFailed(WaitForNotarizationError.exportingNotarizedAppFailed) } else { throw WaitForNotarizationError.missingArchive } @@ -125,7 +125,7 @@ struct WaitForNotarizationCommand: AsyncParsableCommand { "altool", "--notarization-info", request, "--username", parsed.user, "--password", "@keychain:AC_PASSWORD", "--output-format", "xml", ]) - try await result.throwIfFailed(WaitForNotarizationError.fetchingNotarizationStatusFailed(result)) + try await result.throwIfFailed(WaitForNotarizationError.fetchingNotarizationStatusFailed) parsed.log("Received response.") let data = await Data(result.stdout)