From 89c9ee68c91a1edf7ec91d9148bd0f35fa164342 Mon Sep 17 00:00:00 2001 From: Ben Chatelain Date: Wed, 4 Jul 2018 14:52:00 -0600 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A5=20Deintegrate=20CocoaSeeds?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Seedfile | 7 - .../Sources/Commandant/Argument.swift | 99 ------- .../Sources/Commandant/ArgumentParser.swift | 191 ------------ .../Sources/Commandant/ArgumentProtocol.swift | 44 --- .../Sources/Commandant/Command.swift | 222 -------------- .../Sources/Commandant/Commandant.h | 17 -- .../Sources/Commandant/Errors.swift | 153 ---------- .../Sources/Commandant/HelpCommand.swift | 75 ----- .../Commandant/Sources/Commandant/Info.plist | 28 -- .../Sources/Commandant/Option.swift | 273 ----------------- .../Sources/Commandant/OrderedSet.swift | 51 ---- .../Sources/Commandant/Switch.swift | 68 ----- Seeds/Result/Result/Result.h | 8 - Seeds/Result/Result/Result.swift | 276 ------------------ Seeds/Result/Result/ResultProtocol.swift | 203 ------------- Seeds/Seedfile.lock | 6 - mas-cli.xcodeproj/project.pbxproj | 106 ------- 17 files changed, 1827 deletions(-) delete mode 100644 Seedfile delete mode 100644 Seeds/Commandant/Sources/Commandant/Argument.swift delete mode 100644 Seeds/Commandant/Sources/Commandant/ArgumentParser.swift delete mode 100644 Seeds/Commandant/Sources/Commandant/ArgumentProtocol.swift delete mode 100644 Seeds/Commandant/Sources/Commandant/Command.swift delete mode 100644 Seeds/Commandant/Sources/Commandant/Commandant.h delete mode 100644 Seeds/Commandant/Sources/Commandant/Errors.swift delete mode 100644 Seeds/Commandant/Sources/Commandant/HelpCommand.swift delete mode 100644 Seeds/Commandant/Sources/Commandant/Info.plist delete mode 100644 Seeds/Commandant/Sources/Commandant/Option.swift delete mode 100644 Seeds/Commandant/Sources/Commandant/OrderedSet.swift delete mode 100644 Seeds/Commandant/Sources/Commandant/Switch.swift delete mode 100644 Seeds/Result/Result/Result.h delete mode 100644 Seeds/Result/Result/Result.swift delete mode 100644 Seeds/Result/Result/ResultProtocol.swift delete mode 100644 Seeds/Seedfile.lock diff --git a/Seedfile b/Seedfile deleted file mode 100644 index b399aa5..0000000 --- a/Seedfile +++ /dev/null @@ -1,7 +0,0 @@ -github "carthage/Commandant", "0.13.0", files: "Sources/Commandant/*.swift" -github "antitypical/Result", "3.2.4", files: "Result/*.swift" - -target :"mas-tests" do - github "Quick/Nimble", "v7.0.3", files: "Nimble/**.{swift,h}" - github "Quick/Quick", "v1.2.0", files: "Quick/**.{swift,h}" -end diff --git a/Seeds/Commandant/Sources/Commandant/Argument.swift b/Seeds/Commandant/Sources/Commandant/Argument.swift deleted file mode 100644 index ceba4cf..0000000 --- a/Seeds/Commandant/Sources/Commandant/Argument.swift +++ /dev/null @@ -1,99 +0,0 @@ -// -// Argument.swift -// Commandant -// -// Created by Syo Ikeda on 12/14/15. -// Copyright (c) 2015 Carthage. All rights reserved. -// - - -/// Describes an argument that can be provided on the command line. -public struct Argument { - /// The default value for this argument. This is the value that will be used - /// if the argument is never explicitly specified on the command line. - /// - /// If this is nil, this argument is always required. - public let defaultValue: T? - - /// A human-readable string describing the purpose of this argument. This will - /// be shown in help messages. - public let usage: String - - public init(defaultValue: T? = nil, usage: String) { - self.defaultValue = defaultValue - self.usage = usage - } - - fileprivate func invalidUsageError(_ value: String) -> CommandantError { - let description = "Invalid value for '\(self)': \(value)" - return .usageError(description: description) - } -} - -// MARK: - Operators - -extension CommandMode { - /// Evaluates the given argument in the given mode. - /// - /// If parsing command line arguments, and no value was specified on the command - /// line, the argument's `defaultValue` is used. - public static func <| (mode: CommandMode, argument: Argument) -> Result> { - switch mode { - case let .arguments(arguments): - guard let stringValue = arguments.consumePositionalArgument() else { - if let defaultValue = argument.defaultValue { - return .success(defaultValue) - } else { - return .failure(missingArgumentError(argument.usage)) - } - } - - if let value = T.from(string: stringValue) { - return .success(value) - } else { - return .failure(argument.invalidUsageError(stringValue)) - } - - case .usage: - return .failure(informativeUsageError(argument)) - } - } - - /// Evaluates the given argument list in the given mode. - /// - /// If parsing command line arguments, and no value was specified on the command - /// line, the argument's `defaultValue` is used. - public static func <| (mode: CommandMode, argument: Argument<[T]>) -> Result<[T], CommandantError> { - switch mode { - case let .arguments(arguments): - guard let firstValue = arguments.consumePositionalArgument() else { - if let defaultValue = argument.defaultValue { - return .success(defaultValue) - } else { - return .failure(missingArgumentError(argument.usage)) - } - } - - var values = [T]() - - guard let value = T.from(string: firstValue) else { - return .failure(argument.invalidUsageError(firstValue)) - } - - values.append(value) - - while let nextValue = arguments.consumePositionalArgument() { - guard let value = T.from(string: nextValue) else { - return .failure(argument.invalidUsageError(nextValue)) - } - - values.append(value) - } - - return .success(values) - - case .usage: - return .failure(informativeUsageError(argument)) - } - } -} diff --git a/Seeds/Commandant/Sources/Commandant/ArgumentParser.swift b/Seeds/Commandant/Sources/Commandant/ArgumentParser.swift deleted file mode 100644 index 0ed0890..0000000 --- a/Seeds/Commandant/Sources/Commandant/ArgumentParser.swift +++ /dev/null @@ -1,191 +0,0 @@ -// -// ArgumentParser.swift -// Commandant -// -// Created by Justin Spahr-Summers on 2014-11-21. -// Copyright (c) 2014 Carthage. All rights reserved. -// - -import Foundation - -/// Represents an argument passed on the command line. -private enum RawArgument: Equatable { - /// A key corresponding to an option (e.g., `verbose` for `--verbose`). - case key(String) - - /// A value, either associated with an option or passed as a positional - /// argument. - case value(String) - - /// One or more flag arguments (e.g 'r' and 'f' for `-rf`) - case flag(OrderedSet) -} - -private func ==(lhs: RawArgument, rhs: RawArgument) -> Bool { - switch (lhs, rhs) { - case let (.key(left), .key(right)): - return left == right - - case let (.value(left), .value(right)): - return left == right - - case let (.flag(left), .flag(right)): - return left == right - - default: - return false - } -} - -extension RawArgument: CustomStringConvertible { - fileprivate var description: String { - switch self { - case let .key(key): - return "--\(key)" - - case let .value(value): - return "\"\(value)\"" - - case let .flag(flags): - return "-\(String(flags))" - } - } -} - -/// Destructively parses a list of command-line arguments. -public final class ArgumentParser { - /// The remaining arguments to be extracted, in their raw form. - private var rawArguments: [RawArgument] = [] - - /// Initializes the generator from a simple list of command-line arguments. - public init(_ arguments: [String]) { - // The first instance of `--` terminates the option list. - let params = arguments.split(maxSplits: 1, omittingEmptySubsequences: false) { $0 == "--" } - - // Parse out the keyed and flag options. - let options = params.first! - rawArguments.append(contentsOf: options.map { arg in - if arg.hasPrefix("-") { - // Do we have `--{key}` or `-{flags}`. - let opt = arg.dropFirst() - if opt.first == "-" { - return .key(String(opt.dropFirst())) - } else { - return .flag(OrderedSet(opt)) - } - } else { - return .value(arg) - } - }) - - // Remaining arguments are all positional parameters. - if params.count == 2 { - let positional = params.last! - rawArguments.append(contentsOf: positional.map(RawArgument.value)) - } - } - - /// Returns the remaining arguments. - internal var remainingArguments: [String]? { - return rawArguments.isEmpty ? nil : rawArguments.map { $0.description } - } - - /// Returns whether the given key was enabled or disabled, or nil if it - /// was not given at all. - /// - /// If the key is found, it is then removed from the list of arguments - /// remaining to be parsed. - internal func consumeBoolean(forKey key: String) -> Bool? { - let oldArguments = rawArguments - rawArguments.removeAll() - - var result: Bool? - for arg in oldArguments { - if arg == .key(key) { - result = true - } else if arg == .key("no-\(key)") { - result = false - } else { - rawArguments.append(arg) - } - } - - return result - } - - /// Returns the value associated with the given flag, or nil if the flag was - /// not specified. If the key is presented, but no value was given, an error - /// is returned. - /// - /// If a value is found, the key and the value are both removed from the - /// list of arguments remaining to be parsed. - internal func consumeValue(forKey key: String) -> Result> { - let oldArguments = rawArguments - rawArguments.removeAll() - - var foundValue: String? - var index = 0 - - while index < oldArguments.count { - defer { index += 1 } - let arg = oldArguments[index] - - guard arg == .key(key) else { - rawArguments.append(arg) - continue - } - - index += 1 - guard index < oldArguments.count, case let .value(value) = oldArguments[index] else { - return .failure(missingArgumentError("--\(key)")) - } - - foundValue = value - } - - return .success(foundValue) - } - - /// Returns the next positional argument that hasn't yet been returned, or - /// nil if there are no more positional arguments. - internal func consumePositionalArgument() -> String? { - for (index, arg) in rawArguments.enumerated() { - if case let .value(value) = arg { - rawArguments.remove(at: index) - return value - } - } - - return nil - } - - /// Returns whether the given key was specified and removes it from the - /// list of arguments remaining. - internal func consume(key: String) -> Bool { - let oldArguments = rawArguments - rawArguments = oldArguments.filter { $0 != .key(key) } - - return rawArguments.count < oldArguments.count - } - - /// Returns whether the given flag was specified and removes it from the - /// list of arguments remaining. - internal func consumeBoolean(flag: Character) -> Bool { - for (index, arg) in rawArguments.enumerated() { - if case let .flag(flags) = arg, flags.contains(flag) { - var flags = flags - flags.remove(flag) - - if flags.isEmpty { - rawArguments.remove(at: index) - } else { - rawArguments[index] = .flag(flags) - } - - return true - } - } - - return false - } -} diff --git a/Seeds/Commandant/Sources/Commandant/ArgumentProtocol.swift b/Seeds/Commandant/Sources/Commandant/ArgumentProtocol.swift deleted file mode 100644 index cf73b25..0000000 --- a/Seeds/Commandant/Sources/Commandant/ArgumentProtocol.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// ArgumentProtocol.swift -// Commandant -// -// Created by Syo Ikeda on 12/14/15. -// Copyright (c) 2015 Carthage. All rights reserved. -// - -/// Represents a value that can be converted from a command-line argument. -public protocol ArgumentProtocol { - /// A human-readable name for this type. - static var name: String { get } - - /// Attempts to parse a value from the given command-line argument. - static func from(string: String) -> Self? -} - -extension Int: ArgumentProtocol { - public static let name = "integer" - - public static func from(string: String) -> Int? { - return Int(string) - } -} - -extension String: ArgumentProtocol { - public static let name = "string" - - public static func from(string: String) -> String? { - return string - } -} - -extension RawRepresentable where RawValue: StringProtocol, Self: ArgumentProtocol { - public static func from(string: String) -> Self? { - return RawValue(string).flatMap(Self.init(rawValue:)) - } -} - -extension RawRepresentable where RawValue: FixedWidthInteger, Self: ArgumentProtocol { - public static func from(string: String) -> Self? { - return RawValue(string).flatMap(Self.init(rawValue:)) - } -} diff --git a/Seeds/Commandant/Sources/Commandant/Command.swift b/Seeds/Commandant/Sources/Commandant/Command.swift deleted file mode 100644 index 5fb6109..0000000 --- a/Seeds/Commandant/Sources/Commandant/Command.swift +++ /dev/null @@ -1,222 +0,0 @@ -// -// Command.swift -// Commandant -// -// Created by Justin Spahr-Summers on 2014-10-10. -// Copyright (c) 2014 Carthage. All rights reserved. -// - -import Foundation - -/// Represents a subcommand that can be executed with its own set of arguments. -public protocol CommandProtocol { - - /// The command's options type. - associatedtype Options: OptionsProtocol - - associatedtype ClientError: Error = Options.ClientError - - /// The action that users should specify to use this subcommand (e.g., - /// `help`). - var verb: String { get } - - /// A human-readable, high-level description of what this command is used - /// for. - var function: String { get } - - /// Runs this subcommand with the given options. - func run(_ options: Options) -> Result<(), ClientError> -} - -/// A type-erased command. -public struct CommandWrapper { - public let verb: String - public let function: String - - public let run: (ArgumentParser) -> Result<(), CommandantError> - - public let usage: () -> CommandantError? - - /// Creates a command that wraps another. - fileprivate init(_ command: C) where C.ClientError == ClientError, C.Options.ClientError == ClientError { - verb = command.verb - function = command.function - run = { (arguments: ArgumentParser) -> Result<(), CommandantError> in - let options = C.Options.evaluate(.arguments(arguments)) - - if let remainingArguments = arguments.remainingArguments { - return .failure(unrecognizedArgumentsError(remainingArguments)) - } - - switch options { - case let .success(options): - return command - .run(options) - .mapError(CommandantError.commandError) - - case let .failure(error): - return .failure(error) - } - } - usage = { () -> CommandantError? in - return C.Options.evaluate(.usage).error - } - } -} - -/// Describes the "mode" in which a command should run. -public enum CommandMode { - /// Options should be parsed from the given command-line arguments. - case arguments(ArgumentParser) - - /// Each option should record its usage information in an error, for - /// presentation to the user. - case usage -} - -/// Maintains the list of commands available to run. -public final class CommandRegistry { - private var commandsByVerb: [String: CommandWrapper] = [:] - - /// All available commands. - public var commands: [CommandWrapper] { - return commandsByVerb.values.sorted { return $0.verb < $1.verb } - } - - public init() {} - - /// Registers the given commands, making those available to run. - /// - /// If another commands were already registered with the same `verb`s, those - /// will be overwritten. - @discardableResult - public func register(_ commands: C...) - -> CommandRegistry - where C.ClientError == ClientError, C.Options.ClientError == ClientError - { - for command in commands { - commandsByVerb[command.verb] = CommandWrapper(command) - } - return self - } - - /// Runs the command corresponding to the given verb, passing it the given - /// arguments. - /// - /// Returns the results of the execution, or nil if no such command exists. - public func run(command verb: String, arguments: [String]) -> Result<(), CommandantError>? { - return self[verb]?.run(ArgumentParser(arguments)) - } - - /// Returns the command matching the given verb, or nil if no such command - /// is registered. - public subscript(verb: String) -> CommandWrapper? { - return commandsByVerb[verb] - } -} - -extension CommandRegistry { - /// Hands off execution to the CommandRegistry, by parsing CommandLine.arguments - /// and then running whichever command has been identified in the argument - /// list. - /// - /// If the chosen command executes successfully, the process will exit with - /// a successful exit code. - /// - /// If the chosen command fails, the provided error handler will be invoked, - /// then the process will exit with a failure exit code. - /// - /// If a matching command could not be found but there is any `executable-verb` - /// style subcommand executable in the caller's `$PATH`, the subcommand will - /// be executed. - /// - /// If a matching command could not be found or a usage error occurred, - /// a helpful error message will be written to `stderr`, then the process - /// will exit with a failure error code. - public func main(defaultVerb: String, errorHandler: (ClientError) -> ()) -> Never { - main(arguments: CommandLine.arguments, defaultVerb: defaultVerb, errorHandler: errorHandler) - } - - /// Hands off execution to the CommandRegistry, by parsing `arguments` - /// and then running whichever command has been identified in the argument - /// list. - /// - /// If the chosen command executes successfully, the process will exit with - /// a successful exit code. - /// - /// If the chosen command fails, the provided error handler will be invoked, - /// then the process will exit with a failure exit code. - /// - /// If a matching command could not be found but there is any `executable-verb` - /// style subcommand executable in the caller's `$PATH`, the subcommand will - /// be executed. - /// - /// If a matching command could not be found or a usage error occurred, - /// a helpful error message will be written to `stderr`, then the process - /// will exit with a failure error code. - public func main(arguments: [String], defaultVerb: String, errorHandler: (ClientError) -> ()) -> Never { - assert(arguments.count >= 1) - - var arguments = arguments - - // Extract the executable name. - let executableName = arguments.remove(at: 0) - - // use the default verb even if we have other arguments - var verb = defaultVerb - if let argument = arguments.first, !argument.hasPrefix("-") { - verb = argument - // Remove the command name. - arguments.remove(at: 0) - } - - switch run(command: verb, arguments: arguments) { - case .success?: - exit(EXIT_SUCCESS) - - case let .failure(error)?: - switch error { - case let .usageError(description): - fputs(description + "\n", stderr) - - case let .commandError(error): - errorHandler(error) - } - - exit(EXIT_FAILURE) - - case nil: - if let subcommandExecuted = executeSubcommandIfExists(executableName, verb: verb, arguments: arguments) { - exit(subcommandExecuted) - } - - fputs("Unrecognized command: '\(verb)'. See `\(executableName) help`.\n", stderr) - exit(EXIT_FAILURE) - } - } - - /// Finds and executes a subcommand which exists in your $PATH. The executable - /// name must be in the form of `executable-verb`. - /// - /// - Returns: The exit status of found subcommand or nil. - private func executeSubcommandIfExists(_ executableName: String, verb: String, arguments: [String]) -> Int32? { - let subcommand = "\(NSString(string: executableName).lastPathComponent)-\(verb)" - - func launchTask(_ path: String, arguments: [String]) -> Int32 { - let task = Process() - task.launchPath = path - task.arguments = arguments - - task.launch() - task.waitUntilExit() - - return task.terminationStatus - } - - guard launchTask("/usr/bin/which", arguments: [ "-s", subcommand ]) == 0 else { - return nil - } - - return launchTask("/usr/bin/env", arguments: [ subcommand ] + arguments) - } -} diff --git a/Seeds/Commandant/Sources/Commandant/Commandant.h b/Seeds/Commandant/Sources/Commandant/Commandant.h deleted file mode 100644 index 4507251..0000000 --- a/Seeds/Commandant/Sources/Commandant/Commandant.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// Commandant.h -// Commandant -// -// Created by Justin Spahr-Summers on 2014-11-21. -// Copyright (c) 2014 Carthage. All rights reserved. -// - -#import - -//! Project version number for Commandant. -FOUNDATION_EXPORT double CommandantVersionNumber; - -//! Project version string for Commandant. -FOUNDATION_EXPORT const unsigned char CommandantVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import diff --git a/Seeds/Commandant/Sources/Commandant/Errors.swift b/Seeds/Commandant/Sources/Commandant/Errors.swift deleted file mode 100644 index 1e894ab..0000000 --- a/Seeds/Commandant/Sources/Commandant/Errors.swift +++ /dev/null @@ -1,153 +0,0 @@ -// -// Errors.swift -// Commandant -// -// Created by Justin Spahr-Summers on 2014-10-24. -// Copyright (c) 2014 Carthage. All rights reserved. -// - -import Foundation - -/// Possible errors that can originate from Commandant. -/// -/// `ClientError` should be the type of error (if any) that can occur when -/// running commands. -public enum CommandantError: Error { - /// An option was used incorrectly. - case usageError(description: String) - - /// An error occurred while running a command. - case commandError(ClientError) -} - -extension CommandantError: CustomStringConvertible { - public var description: String { - switch self { - case let .usageError(description): - return description - - case let .commandError(error): - return String(describing: error) - } - } -} - -/// Constructs an `InvalidArgument` error that indicates a missing value for -/// the argument by the given name. -internal func missingArgumentError(_ argumentName: String) -> CommandantError { - let description = "Missing argument for \(argumentName)" - return .usageError(description: description) -} - -/// Constructs an error by combining the example of key (and value, if applicable) -/// with the usage description. -internal func informativeUsageError(_ keyValueExample: String, usage: String) -> CommandantError { - let lines = usage.components(separatedBy: .newlines) - - return .usageError(description: lines.reduce(keyValueExample) { previous, value in - return previous + "\n\t" + value - }) -} - -/// Combines the text of the two errors, if they're both `UsageError`s. -/// Otherwise, uses whichever one is not (biased toward the left). -internal func combineUsageErrors(_ lhs: CommandantError, _ rhs: CommandantError) -> CommandantError { - switch (lhs, rhs) { - case let (.usageError(left), .usageError(right)): - let combinedDescription = "\(left)\n\n\(right)" - return .usageError(description: combinedDescription) - - case (.usageError, _): - return rhs - - case (_, .usageError), (_, _): - return lhs - } -} - -/// Constructs an error that indicates unrecognized arguments remains. -internal func unrecognizedArgumentsError(_ options: [String]) -> CommandantError { - return .usageError(description: "Unrecognized arguments: " + options.joined(separator: ", ")) -} - -// MARK: Argument - -/// Constructs an error that describes how to use the argument, with the given -/// example of value usage if applicable. -internal func informativeUsageError(_ valueExample: String, argument: Argument) -> CommandantError { - if argument.defaultValue != nil { - return informativeUsageError("[\(valueExample)]", usage: argument.usage) - } else { - return informativeUsageError(valueExample, usage: argument.usage) - } -} - -/// Constructs an error that describes how to use the argument. -internal func informativeUsageError(_ argument: Argument) -> CommandantError { - var example = "" - - var valueExample = "" - if let defaultValue = argument.defaultValue { - valueExample = "\(defaultValue)" - } - - if valueExample.isEmpty { - example += "(\(T.name))" - } else { - example += valueExample - } - - return informativeUsageError(example, argument: argument) -} - -/// Constructs an error that describes how to use the argument list. -internal func informativeUsageError(_ argument: Argument<[T]>) -> CommandantError { - var example = "" - - var valueExample = "" - if let defaultValue = argument.defaultValue { - valueExample = "\(defaultValue)" - } - - if valueExample.isEmpty { - example += "(\(T.name))" - } else { - example += valueExample - } - - return informativeUsageError(example, argument: argument) -} - -// MARK: Option - -/// Constructs an error that describes how to use the option, with the given -/// example of key (and value, if applicable) usage. -internal func informativeUsageError(_ keyValueExample: String, option: Option) -> CommandantError { - return informativeUsageError("[\(keyValueExample)]", usage: option.usage) -} - -/// Constructs an error that describes how to use the option. -internal func informativeUsageError(_ option: Option) -> CommandantError { - return informativeUsageError("--\(option.key) \(option.defaultValue)", option: option) -} - -/// Constructs an error that describes how to use the option. -internal func informativeUsageError(_ option: Option) -> CommandantError { - return informativeUsageError("--\(option.key) (\(T.name))", option: option) -} - -/// Constructs an error that describes how to use the option. -internal func informativeUsageError(_ option: Option<[T]>) -> CommandantError { - return informativeUsageError("--\(option.key) (\(option.defaultValue))", option: option) -} - -/// Constructs an error that describes how to use the option. -internal func informativeUsageError(_ option: Option<[T]?>) -> CommandantError { - return informativeUsageError("--\(option.key) (\(T.name))", option: option) -} - -/// Constructs an error that describes how to use the given boolean option. -internal func informativeUsageError(_ option: Option) -> CommandantError { - let key = option.key - return informativeUsageError((option.defaultValue ? "--no-\(key)" : "--\(key)"), option: option) -} diff --git a/Seeds/Commandant/Sources/Commandant/HelpCommand.swift b/Seeds/Commandant/Sources/Commandant/HelpCommand.swift deleted file mode 100644 index be5b305..0000000 --- a/Seeds/Commandant/Sources/Commandant/HelpCommand.swift +++ /dev/null @@ -1,75 +0,0 @@ -// -// HelpCommand.swift -// Commandant -// -// Created by Justin Spahr-Summers on 2014-10-10. -// Copyright (c) 2014 Carthage. All rights reserved. -// - -import Foundation - -/// A basic implementation of a `help` command, using information available in a -/// `CommandRegistry`. -/// -/// If you want to use this command, initialize it with the registry, then add -/// it to that same registry: -/// -/// let commands: CommandRegistry = … -/// let helpCommand = HelpCommand(registry: commands) -/// commands.register(helpCommand) -public struct HelpCommand: CommandProtocol { - public typealias Options = HelpOptions - - public let verb = "help" - public let function = "Display general or command-specific help" - - private let registry: CommandRegistry - - /// Initializes the command to provide help from the given registry of - /// commands. - public init(registry: CommandRegistry) { - self.registry = registry - } - - public func run(_ options: Options) -> Result<(), ClientError> { - if let verb = options.verb { - if let command = self.registry[verb] { - print(command.function) - if let usageError = command.usage() { - print("\n\(usageError)") - } - return .success(()) - } else { - fputs("Unrecognized command: '\(verb)'\n", stderr) - } - } - - print("Available commands:\n") - - let maxVerbLength = self.registry.commands.map { $0.verb.count }.max() ?? 0 - - for command in self.registry.commands { - let padding = repeatElement(Character(" "), count: maxVerbLength - command.verb.count) - print(" \(command.verb)\(String(padding)) \(command.function)") - } - - return .success(()) - } -} - -public struct HelpOptions: OptionsProtocol { - fileprivate let verb: String? - - private init(verb: String?) { - self.verb = verb - } - - private static func create(_ verb: String) -> HelpOptions { - return self.init(verb: (verb == "" ? nil : verb)) - } - - public static func evaluate(_ m: CommandMode) -> Result> { - return create - <*> m <| Argument(defaultValue: "", usage: "the command to display help for") - } -} diff --git a/Seeds/Commandant/Sources/Commandant/Info.plist b/Seeds/Commandant/Sources/Commandant/Info.plist deleted file mode 100644 index 4877061..0000000 --- a/Seeds/Commandant/Sources/Commandant/Info.plist +++ /dev/null @@ -1,28 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 0.13.0 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSHumanReadableCopyright - Copyright © 2014 Carthage. All rights reserved. - NSPrincipalClass - - - diff --git a/Seeds/Commandant/Sources/Commandant/Option.swift b/Seeds/Commandant/Sources/Commandant/Option.swift deleted file mode 100644 index c11207c..0000000 --- a/Seeds/Commandant/Sources/Commandant/Option.swift +++ /dev/null @@ -1,273 +0,0 @@ -// -// Option.swift -// Commandant -// -// Created by Justin Spahr-Summers on 2014-11-21. -// Copyright (c) 2014 Carthage. All rights reserved. -// - -import Foundation - -/// Represents a record of options for a command, which can be parsed from -/// a list of command-line arguments. -/// -/// This is most helpful when used in conjunction with the `Option` and `Switch` -/// types, and `<*>` and `<|` combinators. -/// -/// Example: -/// -/// struct LogOptions: OptionsProtocol { -/// let verbosity: Int -/// let outputFilename: String -/// let shouldDelete: Bool -/// let logName: String -/// -/// static func create(_ verbosity: Int) -> (String) -> (Bool) -> (String) -> LogOptions { -/// return { outputFilename in { shouldDelete in { logName in LogOptions(verbosity: verbosity, outputFilename: outputFilename, shouldDelete: shouldDelete, logName: logName) } } } -/// } -/// -/// static func evaluate(_ m: CommandMode) -> Result> { -/// return create -/// <*> m <| Option(key: "verbose", defaultValue: 0, usage: "the verbosity level with which to read the logs") -/// <*> m <| Option(key: "outputFilename", defaultValue: "", usage: "a file to print output to, instead of stdout") -/// <*> m <| Switch(flag: "d", key: "delete", usage: "delete the logs when finished") -/// <*> m <| Argument(usage: "the log to read") -/// } -/// } -public protocol OptionsProtocol { - associatedtype ClientError: Error - - /// Evaluates this set of options in the given mode. - /// - /// Returns the parsed options or a `UsageError`. - static func evaluate(_ m: CommandMode) -> Result> -} - -/// An `OptionsProtocol` that has no options. -public struct NoOptions: OptionsProtocol { - public init() {} - - public static func evaluate(_ m: CommandMode) -> Result> { - return .success(NoOptions()) - } -} - -/// Describes an option that can be provided on the command line. -public struct Option { - /// The key that controls this option. For example, a key of `verbose` would - /// be used for a `--verbose` option. - public let key: String - - /// The default value for this option. This is the value that will be used - /// if the option is never explicitly specified on the command line. - public let defaultValue: T - - /// A human-readable string describing the purpose of this option. This will - /// be shown in help messages. - /// - /// For boolean operations, this should describe the effect of _not_ using - /// the default value (i.e., what will happen if you disable/enable the flag - /// differently from the default). - public let usage: String - - public init(key: String, defaultValue: T, usage: String) { - self.key = key - self.defaultValue = defaultValue - self.usage = usage - } -} - -extension Option: CustomStringConvertible { - public var description: String { - return "--\(key)" - } -} - -// MARK: - Operators - -// Inspired by the Argo library: -// https://github.com/thoughtbot/Argo -/* - Copyright (c) 2014 thoughtbot, inc. - - MIT License - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -infix operator <*> : LogicalDisjunctionPrecedence - -infix operator <| : MultiplicationPrecedence - -/// Applies `f` to the value in the given result. -/// -/// In the context of command-line option parsing, this is used to chain -/// together the parsing of multiple arguments. See OptionsProtocol for an example. -public func <*> (f: (T) -> U, value: Result>) -> Result> { - return value.map(f) -} - -/// Applies the function in `f` to the value in the given result. -/// -/// In the context of command-line option parsing, this is used to chain -/// together the parsing of multiple arguments. See OptionsProtocol for an example. -public func <*> (f: Result<((T) -> U), CommandantError>, value: Result>) -> Result> { - switch (f, value) { - case let (.failure(left), .failure(right)): - return .failure(combineUsageErrors(left, right)) - - case let (.failure(left), .success): - return .failure(left) - - case let (.success, .failure(right)): - return .failure(right) - - case let (.success(f), .success(value)): - let newValue = f(value) - return .success(newValue) - } -} - -extension CommandMode { - /// Evaluates the given option in the given mode. - /// - /// If parsing command line arguments, and no value was specified on the command - /// line, the option's `defaultValue` is used. - public static func <| (mode: CommandMode, option: Option) -> Result> { - let wrapped = Option(key: option.key, defaultValue: option.defaultValue, usage: option.usage) - // Since we are passing a non-nil default value, we can safely unwrap the - // result. - return (mode <| wrapped).map { $0! } - } - - /// Evaluates the given option in the given mode. - /// - /// If parsing command line arguments, and no value was specified on the command - /// line, `nil` is used. - public static func <| (mode: CommandMode, option: Option) -> Result> { - let key = option.key - switch mode { - case let .arguments(arguments): - var stringValue: String? - switch arguments.consumeValue(forKey: key) { - case let .success(value): - stringValue = value - - case let .failure(error): - switch error { - case let .usageError(description): - return .failure(.usageError(description: description)) - - case .commandError: - fatalError("CommandError should be impossible when parameterized over NoError") - } - } - - if let stringValue = stringValue { - if let value = T.from(string: stringValue) { - return .success(value) - } - - let description = "Invalid value for '--\(key)': \(stringValue)" - return .failure(.usageError(description: description)) - } else { - return .success(option.defaultValue) - } - - case .usage: - return .failure(informativeUsageError(option)) - } - } - - /// Evaluates the given option in the given mode. - /// - /// If parsing command line arguments, and no value was specified on the command - /// line, the option's `defaultValue` is used. - public static func <| (mode: CommandMode, option: Option<[T]>) -> Result<[T], CommandantError> { - let wrapped = Option<[T]?>(key: option.key, defaultValue: option.defaultValue, usage: option.usage) - // Since we are passing a non-nil default value, we can safely unwrap the - // result. - return (mode <| wrapped).map { $0! } - } - - /// Evaluates the given option in the given mode. - /// - /// If parsing command line arguments, and no value was specified on the command - /// line, `nil` is used. - public static func <| (mode: CommandMode, option: Option<[T]?>) -> Result<[T]?, CommandantError> { - let key = option.key - - switch mode { - case let .arguments(arguments): - let stringValue: String? - switch arguments.consumeValue(forKey: key) { - case let .success(value): - stringValue = value - - case let .failure(error): - switch error { - case let .usageError(description): - return .failure(.usageError(description: description)) - - case .commandError: - fatalError("CommandError should be impossible when parameterized over NoError") - } - } - - guard let unwrappedStringValue = stringValue else { - return .success(option.defaultValue) - } - - let components = unwrappedStringValue.split( - omittingEmptySubsequences: true, - whereSeparator: [",", " "].contains - ) - var resultValues: [T] = [] - for component in components { - guard let value = T.from(string: String(component)) else { - let description = "Invalid value for '--\(key)': \(unwrappedStringValue)" - return .failure(.usageError(description: description)) - } - resultValues.append(value) - } - return .success(resultValues) - - case .usage: - return .failure(informativeUsageError(option)) - } - } - - /// Evaluates the given boolean option in the given mode. - /// - /// If parsing command line arguments, and no value was specified on the command - /// line, the option's `defaultValue` is used. - public static func <| (mode: CommandMode, option: Option) -> Result> { - switch mode { - case let .arguments(arguments): - if let value = arguments.consumeBoolean(forKey: option.key) { - return .success(value) - } else { - return .success(option.defaultValue) - } - - case .usage: - return .failure(informativeUsageError(option)) - } - } -} diff --git a/Seeds/Commandant/Sources/Commandant/OrderedSet.swift b/Seeds/Commandant/Sources/Commandant/OrderedSet.swift deleted file mode 100644 index e2a9351..0000000 --- a/Seeds/Commandant/Sources/Commandant/OrderedSet.swift +++ /dev/null @@ -1,51 +0,0 @@ -/// A poor man's ordered set. -internal struct OrderedSet { - fileprivate var values: [T] = [] - - init(_ sequence: S) where S.Element == T { - for e in sequence where !values.contains(e) { - values.append(e) - } - } - - @discardableResult - mutating func remove(_ member: T) -> T? { - if let index = values.index(of: member) { - return values.remove(at: index) - } else { - return nil - } - } -} - -extension OrderedSet: Equatable { - static func == (_ lhs: OrderedSet, rhs: OrderedSet) -> Bool { - return lhs.values == rhs.values - } -} - -extension OrderedSet: Collection { - subscript(position: Int) -> T { - return values[position] - } - - var count: Int { - return values.count - } - - var isEmpty: Bool { - return values.isEmpty - } - - var startIndex: Int { - return values.startIndex - } - - var endIndex: Int { - return values.endIndex - } - - func index(after i: Int) -> Int { - return values.index(after: i) - } -} diff --git a/Seeds/Commandant/Sources/Commandant/Switch.swift b/Seeds/Commandant/Sources/Commandant/Switch.swift deleted file mode 100644 index c6bc791..0000000 --- a/Seeds/Commandant/Sources/Commandant/Switch.swift +++ /dev/null @@ -1,68 +0,0 @@ -// -// Switch.swift -// Commandant -// -// Created by Neil Pankey on 3/31/15. -// Copyright (c) 2015 Carthage. All rights reserved. -// - - -/// Describes a parameterless command line flag that defaults to false and can only -/// be switched on. Canonical examples include `--force` and `--recurse`. -/// -/// For a boolean toggle that can be enabled and disabled use `Option`. -public struct Switch { - /// The key that enables this switch. For example, a key of `verbose` would be - /// used for a `--verbose` option. - public let key: String - - /// Optional single letter flag that enables this switch. For example, `-v` would - /// be used as a shorthand for `--verbose`. - /// - /// Multiple flags can be grouped together as a single argument and will split - /// when parsing (e.g. `rm -rf` treats 'r' and 'f' as inidividual flags). - public let flag: Character? - - /// A human-readable string describing the purpose of this option. This will - /// be shown in help messages. - public let usage: String - - public init(flag: Character? = nil, key: String, usage: String) { - self.flag = flag - self.key = key - self.usage = usage - } -} - -extension Switch: CustomStringConvertible { - public var description: String { - var options = "--\(key)" - if let flag = self.flag { - options += "|-\(flag)" - } - return options - } -} - -// MARK: - Operators - -extension CommandMode { - /// Evaluates the given boolean switch in the given mode. - /// - /// If parsing command line arguments, and no value was specified on the command - /// line, the option's `defaultValue` is used. - public static func <| (mode: CommandMode, option: Switch) -> Result> { - switch mode { - case let .arguments(arguments): - var enabled = arguments.consume(key: option.key) - - if let flag = option.flag, !enabled { - enabled = arguments.consumeBoolean(flag: flag) - } - return .success(enabled) - - case .usage: - return .failure(informativeUsageError(option.description, usage: option.usage)) - } - } -} diff --git a/Seeds/Result/Result/Result.h b/Seeds/Result/Result/Result.h deleted file mode 100644 index 4742701..0000000 --- a/Seeds/Result/Result/Result.h +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2015 Rob Rix. All rights reserved. - -/// Project version number for Result. -extern double ResultVersionNumber; - -/// Project version string for Result. -extern const unsigned char ResultVersionString[]; - diff --git a/Seeds/Result/Result/Result.swift b/Seeds/Result/Result/Result.swift deleted file mode 100644 index c92524d..0000000 --- a/Seeds/Result/Result/Result.swift +++ /dev/null @@ -1,276 +0,0 @@ -// Copyright (c) 2015 Rob Rix. All rights reserved. - -/// An enum representing either a failure with an explanatory error, or a success with a result value. -public enum Result: ResultProtocol, CustomStringConvertible, CustomDebugStringConvertible { - case success(T) - case failure(Error) - - // MARK: Constructors - - /// Constructs a success wrapping a `value`. - public init(value: T) { - self = .success(value) - } - - /// Constructs a failure wrapping an `error`. - public init(error: Error) { - self = .failure(error) - } - - /// Constructs a result from an `Optional`, failing with `Error` if `nil`. - public init(_ value: T?, failWith: @autoclosure () -> Error) { - self = value.map(Result.success) ?? .failure(failWith()) - } - - /// Constructs a result from a function that uses `throw`, failing with `Error` if throws. - public init(_ f: @autoclosure () throws -> T) { - self.init(attempt: f) - } - - /// Constructs a result from a function that uses `throw`, failing with `Error` if throws. - public init(attempt f: () throws -> T) { - do { - self = .success(try f()) - } catch var error { - if Error.self == AnyError.self { - error = AnyError(error) - } - self = .failure(error as! Error) - } - } - - // MARK: Deconstruction - - /// Returns the value from `success` Results or `throw`s the error. - public func dematerialize() throws -> T { - switch self { - case let .success(value): - return value - case let .failure(error): - throw error - } - } - - /// Case analysis for Result. - /// - /// Returns the value produced by applying `ifFailure` to `failure` Results, or `ifSuccess` to `success` Results. - public func analysis(ifSuccess: (T) -> Result, ifFailure: (Error) -> Result) -> Result { - switch self { - case let .success(value): - return ifSuccess(value) - case let .failure(value): - return ifFailure(value) - } - } - - // MARK: Errors - - /// The domain for errors constructed by Result. - public static var errorDomain: String { return "com.antitypical.Result" } - - /// The userInfo key for source functions in errors constructed by Result. - public static var functionKey: String { return "\(errorDomain).function" } - - /// The userInfo key for source file paths in errors constructed by Result. - public static var fileKey: String { return "\(errorDomain).file" } - - /// The userInfo key for source file line numbers in errors constructed by Result. - public static var lineKey: String { return "\(errorDomain).line" } - - /// Constructs an error. - public static func error(_ message: String? = nil, function: String = #function, file: String = #file, line: Int = #line) -> NSError { - var userInfo: [String: Any] = [ - functionKey: function, - fileKey: file, - lineKey: line, - ] - - if let message = message { - userInfo[NSLocalizedDescriptionKey] = message - } - - return NSError(domain: errorDomain, code: 0, userInfo: userInfo) - } - - - // MARK: CustomStringConvertible - - public var description: String { - return analysis( - ifSuccess: { ".success(\($0))" }, - ifFailure: { ".failure(\($0))" }) - } - - - // MARK: CustomDebugStringConvertible - - public var debugDescription: String { - return description - } -} - -// MARK: - Derive result from failable closure - -public func materialize(_ f: () throws -> T) -> Result { - return materialize(try f()) -} - -public func materialize(_ f: @autoclosure () throws -> T) -> Result { - do { - return .success(try f()) - } catch { - return .failure(AnyError(error)) - } -} - -@available(*, deprecated, message: "Use the overload which returns `Result` instead") -public func materialize(_ f: () throws -> T) -> Result { - return materialize(try f()) -} - -@available(*, deprecated, message: "Use the overload which returns `Result` instead") -public func materialize(_ f: @autoclosure () throws -> T) -> Result { - do { - return .success(try f()) - } catch { -// This isn't great, but it lets us maintain compatibility until this deprecated -// method can be removed. -#if _runtime(_ObjC) - return .failure(error as NSError) -#else - // https://github.com/apple/swift-corelibs-foundation/blob/swift-3.0.2-RELEASE/Foundation/NSError.swift#L314 - let userInfo = _swift_Foundation_getErrorDefaultUserInfo(error) as? [String: Any] - let nsError = NSError(domain: error._domain, code: error._code, userInfo: userInfo) - return .failure(nsError) -#endif - } -} - -// MARK: - Cocoa API conveniences - -#if !os(Linux) - -/// Constructs a `Result` with the result of calling `try` with an error pointer. -/// -/// This is convenient for wrapping Cocoa API which returns an object or `nil` + an error, by reference. e.g.: -/// -/// Result.try { NSData(contentsOfURL: URL, options: .dataReadingMapped, error: $0) } -@available(*, deprecated, message: "This will be removed in Result 4.0. Use `Result.init(attempt:)` instead. See https://github.com/antitypical/Result/issues/85 for the details.") -public func `try`(_ function: String = #function, file: String = #file, line: Int = #line, `try`: (NSErrorPointer) -> T?) -> Result { - var error: NSError? - return `try`(&error).map(Result.success) ?? .failure(error ?? Result.error(function: function, file: file, line: line)) -} - -/// Constructs a `Result` with the result of calling `try` with an error pointer. -/// -/// This is convenient for wrapping Cocoa API which returns a `Bool` + an error, by reference. e.g.: -/// -/// Result.try { NSFileManager.defaultManager().removeItemAtURL(URL, error: $0) } -@available(*, deprecated, message: "This will be removed in Result 4.0. Use `Result.init(attempt:)` instead. See https://github.com/antitypical/Result/issues/85 for the details.") -public func `try`(_ function: String = #function, file: String = #file, line: Int = #line, `try`: (NSErrorPointer) -> Bool) -> Result<(), NSError> { - var error: NSError? - return `try`(&error) ? - .success(()) - : .failure(error ?? Result<(), NSError>.error(function: function, file: file, line: line)) -} - -#endif - -// MARK: - ErrorConvertible conformance - -extension NSError: ErrorConvertible { - public static func error(from error: Swift.Error) -> Self { - func cast(_ error: Swift.Error) -> T { - return error as! T - } - - return cast(error) - } -} - -// MARK: - Errors - -/// An “error” that is impossible to construct. -/// -/// This can be used to describe `Result`s where failures will never -/// be generated. For example, `Result` describes a result that -/// contains an `Int`eger and is guaranteed never to be a `failure`. -public enum NoError: Swift.Error, Equatable { - public static func ==(lhs: NoError, rhs: NoError) -> Bool { - return true - } -} - -/// A type-erased error which wraps an arbitrary error instance. This should be -/// useful for generic contexts. -public struct AnyError: Swift.Error { - /// The underlying error. - public let error: Swift.Error - - public init(_ error: Swift.Error) { - if let anyError = error as? AnyError { - self = anyError - } else { - self.error = error - } - } -} - -extension AnyError: ErrorConvertible { - public static func error(from error: Error) -> AnyError { - return AnyError(error) - } -} - -extension AnyError: CustomStringConvertible { - public var description: String { - return String(describing: error) - } -} - -// There appears to be a bug in Foundation on Linux which prevents this from working: -// https://bugs.swift.org/browse/SR-3565 -// Don't forget to comment the tests back in when removing this check when it's fixed! -#if !os(Linux) - -extension AnyError: LocalizedError { - public var errorDescription: String? { - return error.localizedDescription - } - - public var failureReason: String? { - return (error as? LocalizedError)?.failureReason - } - - public var helpAnchor: String? { - return (error as? LocalizedError)?.helpAnchor - } - - public var recoverySuggestion: String? { - return (error as? LocalizedError)?.recoverySuggestion - } -} - -#endif - -// MARK: - migration support -extension Result { - @available(*, unavailable, renamed: "success") - public static func Success(_: T) -> Result { - fatalError() - } - - @available(*, unavailable, renamed: "failure") - public static func Failure(_: Error) -> Result { - fatalError() - } -} - -extension NSError { - @available(*, unavailable, renamed: "error(from:)") - public static func errorFromErrorType(_ error: Swift.Error) -> Self { - fatalError() - } -} - -import Foundation diff --git a/Seeds/Result/Result/ResultProtocol.swift b/Seeds/Result/Result/ResultProtocol.swift deleted file mode 100644 index 678f294..0000000 --- a/Seeds/Result/Result/ResultProtocol.swift +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (c) 2015 Rob Rix. All rights reserved. - -/// A type that can represent either failure with an error or success with a result value. -public protocol ResultProtocol { - associatedtype Value - associatedtype Error: Swift.Error - - /// Constructs a successful result wrapping a `value`. - init(value: Value) - - /// Constructs a failed result wrapping an `error`. - init(error: Error) - - /// Case analysis for ResultProtocol. - /// - /// Returns the value produced by appliying `ifFailure` to the error if self represents a failure, or `ifSuccess` to the result value if self represents a success. - func analysis(ifSuccess: (Value) -> U, ifFailure: (Error) -> U) -> U - - /// Returns the value if self represents a success, `nil` otherwise. - /// - /// A default implementation is provided by a protocol extension. Conforming types may specialize it. - var value: Value? { get } - - /// Returns the error if self represents a failure, `nil` otherwise. - /// - /// A default implementation is provided by a protocol extension. Conforming types may specialize it. - var error: Error? { get } -} - -public extension ResultProtocol { - - /// Returns the value if self represents a success, `nil` otherwise. - public var value: Value? { - return analysis(ifSuccess: { $0 }, ifFailure: { _ in nil }) - } - - /// Returns the error if self represents a failure, `nil` otherwise. - public var error: Error? { - return analysis(ifSuccess: { _ in nil }, ifFailure: { $0 }) - } - - /// Returns a new Result by mapping `Success`es’ values using `transform`, or re-wrapping `Failure`s’ errors. - public func map(_ transform: (Value) -> U) -> Result { - return flatMap { .success(transform($0)) } - } - - /// Returns the result of applying `transform` to `Success`es’ values, or re-wrapping `Failure`’s errors. - public func flatMap(_ transform: (Value) -> Result) -> Result { - return analysis( - ifSuccess: transform, - ifFailure: Result.failure) - } - - /// Returns a Result with a tuple of the receiver and `other` values if both - /// are `Success`es, or re-wrapping the error of the earlier `Failure`. - public func fanout(_ other: @autoclosure () -> R) -> Result<(Value, R.Value), Error> - where Error == R.Error - { - return self.flatMap { left in other().map { right in (left, right) } } - } - - /// Returns a new Result by mapping `Failure`'s values using `transform`, or re-wrapping `Success`es’ values. - public func mapError(_ transform: (Error) -> Error2) -> Result { - return flatMapError { .failure(transform($0)) } - } - - /// Returns the result of applying `transform` to `Failure`’s errors, or re-wrapping `Success`es’ values. - public func flatMapError(_ transform: (Error) -> Result) -> Result { - return analysis( - ifSuccess: Result.success, - ifFailure: transform) - } - - /// Returns a new Result by mapping `Success`es’ values using `success`, and by mapping `Failure`'s values using `failure`. - public func bimap(success: (Value) -> U, failure: (Error) -> Error2) -> Result { - return analysis( - ifSuccess: { .success(success($0)) }, - ifFailure: { .failure(failure($0)) } - ) - } -} - -public extension ResultProtocol { - - // MARK: Higher-order functions - - /// Returns `self.value` if this result is a .Success, or the given value otherwise. Equivalent with `??` - public func recover(_ value: @autoclosure () -> Value) -> Value { - return self.value ?? value() - } - - /// Returns this result if it is a .Success, or the given result otherwise. Equivalent with `??` - public func recover(with result: @autoclosure () -> Self) -> Self { - return analysis( - ifSuccess: { _ in self }, - ifFailure: { _ in result() }) - } -} - -/// Protocol used to constrain `tryMap` to `Result`s with compatible `Error`s. -public protocol ErrorConvertible: Swift.Error { - static func error(from error: Swift.Error) -> Self -} - -public extension ResultProtocol where Error: ErrorConvertible { - - /// Returns the result of applying `transform` to `Success`es’ values, or wrapping thrown errors. - public func tryMap(_ transform: (Value) throws -> U) -> Result { - return flatMap { value in - do { - return .success(try transform(value)) - } - catch { - let convertedError = Error.error(from: error) - // Revisit this in a future version of Swift. https://twitter.com/jckarter/status/672931114944696321 - return .failure(convertedError) - } - } - } -} - -// MARK: - Operators - -infix operator &&& : LogicalConjunctionPrecedence - -/// Returns a Result with a tuple of `left` and `right` values if both are `Success`es, or re-wrapping the error of the earlier `Failure`. -@available(*, deprecated, renamed: "ResultProtocol.fanout(self:_:)") -public func &&& (left: L, right: @autoclosure () -> R) -> Result<(L.Value, R.Value), L.Error> - where L.Error == R.Error -{ - return left.fanout(right) -} - -precedencegroup ChainingPrecedence { - associativity: left - higherThan: TernaryPrecedence -} - -infix operator >>- : ChainingPrecedence - -/// Returns the result of applying `transform` to `Success`es’ values, or re-wrapping `Failure`’s errors. -/// -/// This is a synonym for `flatMap`. -@available(*, deprecated, renamed: "ResultProtocol.flatMap(self:_:)") -public func >>- (result: T, transform: (T.Value) -> Result) -> Result { - return result.flatMap(transform) -} - -/// Returns `true` if `left` and `right` are both `Success`es and their values are equal, or if `left` and `right` are both `Failure`s and their errors are equal. -public func == (left: T, right: T) -> Bool - where T.Value: Equatable, T.Error: Equatable -{ - if let left = left.value, let right = right.value { - return left == right - } else if let left = left.error, let right = right.error { - return left == right - } - return false -} - -/// Returns `true` if `left` and `right` represent different cases, or if they represent the same case but different values. -public func != (left: T, right: T) -> Bool - where T.Value: Equatable, T.Error: Equatable -{ - return !(left == right) -} - -/// Returns the value of `left` if it is a `Success`, or `right` otherwise. Short-circuits. -public func ?? (left: T, right: @autoclosure () -> T.Value) -> T.Value { - return left.recover(right()) -} - -/// Returns `left` if it is a `Success`es, or `right` otherwise. Short-circuits. -public func ?? (left: T, right: @autoclosure () -> T) -> T { - return left.recover(with: right()) -} - -// MARK: - migration support -@available(*, unavailable, renamed: "ResultProtocol") -public typealias ResultType = ResultProtocol - -@available(*, unavailable, renamed: "Error") -public typealias ResultErrorType = Swift.Error - -@available(*, unavailable, renamed: "ErrorConvertible") -public typealias ErrorTypeConvertible = ErrorConvertible - -@available(*, deprecated, renamed: "ErrorConvertible") -public protocol ErrorProtocolConvertible: ErrorConvertible {} - -extension ResultProtocol { - @available(*, unavailable, renamed: "recover(with:)") - public func recoverWith(_ result: @autoclosure () -> Self) -> Self { - fatalError() - } -} - -extension ErrorConvertible { - @available(*, unavailable, renamed: "error(from:)") - public static func errorFromErrorType(_ error: Swift.Error) -> Self { - fatalError() - } -} diff --git a/Seeds/Seedfile.lock b/Seeds/Seedfile.lock deleted file mode 100644 index e5a3a57..0000000 --- a/Seeds/Seedfile.lock +++ /dev/null @@ -1,6 +0,0 @@ ---- -SEEDS: -- Commandant (0.13.0) -- Result (3.2.4) -- Nimble (v7.0.3) -- Quick (v1.2.0) diff --git a/mas-cli.xcodeproj/project.pbxproj b/mas-cli.xcodeproj/project.pbxproj index 00ddb8d..9b391b3 100644 --- a/mas-cli.xcodeproj/project.pbxproj +++ b/mas-cli.xcodeproj/project.pbxproj @@ -7,30 +7,11 @@ objects = { /* Begin PBXBuildFile section */ - 073998C12AE3BEEC41CE0DAD /* OrderedSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9871C2273F4D762A1F19B07 /* OrderedSet.swift */; }; - 09756A23E9102359296C821B /* ResultProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5150F7FB7CF2A77F675D8E92 /* ResultProtocol.swift */; }; - 09A04CB22DC02B86AE4ACC8A /* ArgumentParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9D96DDBBCCCC5944160ABE /* ArgumentParser.swift */; }; - 0C47E694564FCB59996690DD /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = 326E4D331CCD66ADFE19CE39 /* Command.swift */; }; - 0EBF5CDD379D7462C3389536 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9257C5FABA335E5F060CB7F7 /* Result.swift */; }; - 15E27926A580EABEB1B218EF /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF1B6BEDF32AF3F8A575FB1F /* Switch.swift */; }; - 27340A5BB9F2A5B166E3A72A /* ArgumentProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4237E5AA1A289D03D2A2FB8 /* ArgumentProtocol.swift */; }; - 3053D11E74A22A4C5A6BE833 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = F547B3DC473CFB1BE0AEB70A /* Errors.swift */; }; - 30EA893640B02CCF679F9C57 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD7FE171F643805F7BC38A7 /* Option.swift */; }; - 3F177C62A7053BA3ED415E5E /* Argument.swift in Sources */ = {isa = PBXBuildFile; fileRef = F36A4ABD8025E13060312925 /* Argument.swift */; }; 4913269B1F48921D0010EB86 /* CKSoftwareMap+AppLookup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4913269A1F48921D0010EB86 /* CKSoftwareMap+AppLookup.swift */; }; - 49C2F3FDD805256BE934A70E /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF1B6BEDF32AF3F8A575FB1F /* Switch.swift */; }; - 4C8321353B9AE40539A1AC8A /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = F547B3DC473CFB1BE0AEB70A /* Errors.swift */; }; 693A98991CBFFA760004D3B4 /* Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 693A98981CBFFA760004D3B4 /* Search.swift */; }; 693A989B1CBFFAAA0004D3B4 /* NSURLSession+Synchronous.swift in Sources */ = {isa = PBXBuildFile; fileRef = 693A989A1CBFFAAA0004D3B4 /* NSURLSession+Synchronous.swift */; }; 8078FAA81EC4F2FB004B5B3F /* Lucky.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8078FAA71EC4F2FB004B5B3F /* Lucky.swift */; }; 900A1E811DBAC8CB0069B1A8 /* Info.swift in Sources */ = {isa = PBXBuildFile; fileRef = 900A1E801DBAC8CB0069B1A8 /* Info.swift */; }; - 92AE0FD7BE06D64692E6C1E6 /* OrderedSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9871C2273F4D762A1F19B07 /* OrderedSet.swift */; }; - AD0785BC0EC6BBF4ED560DCC /* ArgumentParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9D96DDBBCCCC5944160ABE /* ArgumentParser.swift */; }; - ADE553C828AF4EAFF39ED3E1 /* ArgumentProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4237E5AA1A289D03D2A2FB8 /* ArgumentProtocol.swift */; }; - C50DD25454FC5CAA1F37763F /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9257C5FABA335E5F060CB7F7 /* Result.swift */; }; - DE6E193A6671F3D6807F746D /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = 326E4D331CCD66ADFE19CE39 /* Command.swift */; }; - EBD6B44FDF65E0253153629F /* HelpCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FDC2B8063EC231E28353D23 /* HelpCommand.swift */; }; - EC113CE6C98E8D8358228D33 /* ResultProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5150F7FB7CF2A77F675D8E92 /* ResultProtocol.swift */; }; ED031A7C1B5127C00097692E /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED031A7B1B5127C00097692E /* main.swift */; }; ED0F237F1B87522400AE40CD /* Install.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F237E1B87522400AE40CD /* Install.swift */; }; ED0F23831B87533A00AE40CD /* List.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F23821B87533A00AE40CD /* List.swift */; }; @@ -49,9 +30,6 @@ EDE296531C700F4300554778 /* SignOut.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDE296521C700F4300554778 /* SignOut.swift */; }; EDEAA0C01B51CE6200F2FC3F /* StoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDEAA0BF1B51CE6200F2FC3F /* StoreFoundation.framework */; }; EDEAA17D1B5C579100F2FC3F /* CommerceKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDEAA17C1B5C579100F2FC3F /* CommerceKit.framework */; }; - F184B6B7CD9C013CACDED0FB /* Argument.swift in Sources */ = {isa = PBXBuildFile; fileRef = F36A4ABD8025E13060312925 /* Argument.swift */; }; - F48562FA81B0C0258AC063B4 /* HelpCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FDC2B8063EC231E28353D23 /* HelpCommand.swift */; }; - F6D2058A70757D3477185A50 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD7FE171F643805F7BC38A7 /* Option.swift */; }; F865880B2030F6DE0093DE57 /* MASErrorTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F865880A2030F6DE0093DE57 /* MASErrorTestCase.swift */; }; F86588272030FAE70093DE57 /* MASError.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F238C1B8756E600AE40CD /* MASError.swift */; }; /* End PBXBuildFile section */ @@ -79,20 +57,11 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 2AD7FE171F643805F7BC38A7 /* Option.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Option.swift; path = Seeds/Commandant/Sources/Commandant/Option.swift; sourceTree = ""; }; - 326E4D331CCD66ADFE19CE39 /* Command.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Command.swift; path = Seeds/Commandant/Sources/Commandant/Command.swift; sourceTree = ""; }; 4913269A1F48921D0010EB86 /* CKSoftwareMap+AppLookup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CKSoftwareMap+AppLookup.swift"; sourceTree = ""; }; - 5150F7FB7CF2A77F675D8E92 /* ResultProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResultProtocol.swift; path = Seeds/Result/Result/ResultProtocol.swift; sourceTree = ""; }; 693A98981CBFFA760004D3B4 /* Search.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Search.swift; sourceTree = ""; }; 693A989A1CBFFAAA0004D3B4 /* NSURLSession+Synchronous.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSURLSession+Synchronous.swift"; sourceTree = ""; }; 8078FAA71EC4F2FB004B5B3F /* Lucky.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Lucky.swift; sourceTree = ""; }; - 8FDC2B8063EC231E28353D23 /* HelpCommand.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HelpCommand.swift; path = Seeds/Commandant/Sources/Commandant/HelpCommand.swift; sourceTree = ""; }; 900A1E801DBAC8CB0069B1A8 /* Info.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Info.swift; sourceTree = ""; }; - 9257C5FABA335E5F060CB7F7 /* Result.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Result.swift; path = Seeds/Result/Result/Result.swift; sourceTree = ""; }; - AF1B6BEDF32AF3F8A575FB1F /* Switch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Switch.swift; path = Seeds/Commandant/Sources/Commandant/Switch.swift; sourceTree = ""; }; - B4237E5AA1A289D03D2A2FB8 /* ArgumentProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ArgumentProtocol.swift; path = Seeds/Commandant/Sources/Commandant/ArgumentProtocol.swift; sourceTree = ""; }; - D9871C2273F4D762A1F19B07 /* OrderedSet.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OrderedSet.swift; path = Seeds/Commandant/Sources/Commandant/OrderedSet.swift; sourceTree = ""; }; - EA9D96DDBBCCCC5944160ABE /* ArgumentParser.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ArgumentParser.swift; path = Seeds/Commandant/Sources/Commandant/ArgumentParser.swift; sourceTree = ""; }; ED031A781B5127C00097692E /* mas */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = mas; sourceTree = BUILT_PRODUCTS_DIR; }; ED031A7B1B5127C00097692E /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; ED0F237E1B87522400AE40CD /* Install.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Install.swift; sourceTree = ""; }; @@ -137,8 +106,6 @@ EDEAA1551B5C576D00F2FC3F /* CKUpdateController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKUpdateController.h; sourceTree = ""; }; EDEAA1661B5C576D00F2FC3F /* ISStoreURLOperationDelegate-Protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ISStoreURLOperationDelegate-Protocol.h"; sourceTree = ""; }; EDEAA17C1B5C579100F2FC3F /* CommerceKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CommerceKit.framework; path = /System/Library/PrivateFrameworks/CommerceKit.framework; sourceTree = ""; }; - F36A4ABD8025E13060312925 /* Argument.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Argument.swift; path = Seeds/Commandant/Sources/Commandant/Argument.swift; sourceTree = ""; }; - F547B3DC473CFB1BE0AEB70A /* Errors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Errors.swift; path = Seeds/Commandant/Sources/Commandant/Errors.swift; sourceTree = ""; }; F8233C87201EBDF000268278 /* mas-tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "mas-tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; F8233C8B201EBDF100268278 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F865880A2030F6DE0093DE57 /* MASErrorTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MASErrorTestCase.swift; sourceTree = ""; }; @@ -164,56 +131,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 0739FA024AB80925B32D64D1 /* Seeds */ = { - isa = PBXGroup; - children = ( - A49C8EB621015CD588C621FD /* Commandant */, - A96B40B5852A4F029AFDA669 /* Nimble */, - 6EB4B681BB79E32622860164 /* Quick */, - 6569B225928F21A4A639BB22 /* Result */, - ); - name = Seeds; - sourceTree = ""; - }; - 6569B225928F21A4A639BB22 /* Result */ = { - isa = PBXGroup; - children = ( - 9257C5FABA335E5F060CB7F7 /* Result.swift */, - 5150F7FB7CF2A77F675D8E92 /* ResultProtocol.swift */, - ); - name = Result; - sourceTree = ""; - }; - 6EB4B681BB79E32622860164 /* Quick */ = { - isa = PBXGroup; - children = ( - ); - name = Quick; - sourceTree = ""; - }; - A49C8EB621015CD588C621FD /* Commandant */ = { - isa = PBXGroup; - children = ( - F36A4ABD8025E13060312925 /* Argument.swift */, - EA9D96DDBBCCCC5944160ABE /* ArgumentParser.swift */, - B4237E5AA1A289D03D2A2FB8 /* ArgumentProtocol.swift */, - 326E4D331CCD66ADFE19CE39 /* Command.swift */, - F547B3DC473CFB1BE0AEB70A /* Errors.swift */, - 8FDC2B8063EC231E28353D23 /* HelpCommand.swift */, - 2AD7FE171F643805F7BC38A7 /* Option.swift */, - D9871C2273F4D762A1F19B07 /* OrderedSet.swift */, - AF1B6BEDF32AF3F8A575FB1F /* Switch.swift */, - ); - name = Commandant; - sourceTree = ""; - }; - A96B40B5852A4F029AFDA669 /* Nimble */ = { - isa = PBXGroup; - children = ( - ); - name = Nimble; - sourceTree = ""; - }; ED031A6F1B5127C00097692E = { isa = PBXGroup; children = ( @@ -222,7 +139,6 @@ EDFC76381B642A2E00D0DBD7 /* Frameworks */, EDEAA0C11B51CEBD00F2FC3F /* PrivateHeaders */, ED031A791B5127C00097692E /* Products */, - 0739FA024AB80925B32D64D1 /* Seeds */, ); sourceTree = ""; }; @@ -448,14 +364,8 @@ buildActionMask = 2147483647; files = ( ED0F23871B87537200AE40CD /* Account.swift in Sources */, - F184B6B7CD9C013CACDED0FB /* Argument.swift in Sources */, - AD0785BC0EC6BBF4ED560DCC /* ArgumentParser.swift in Sources */, - ADE553C828AF4EAFF39ED3E1 /* ArgumentProtocol.swift in Sources */, 4913269B1F48921D0010EB86 /* CKSoftwareMap+AppLookup.swift in Sources */, - 0C47E694564FCB59996690DD /* Command.swift in Sources */, ED0F238B1B87569C00AE40CD /* Downloader.swift in Sources */, - 3053D11E74A22A4C5A6BE833 /* Errors.swift in Sources */, - EBD6B44FDF65E0253153629F /* HelpCommand.swift in Sources */, 900A1E811DBAC8CB0069B1A8 /* Info.swift in Sources */, ED0F237F1B87522400AE40CD /* Install.swift in Sources */, ED0F23901B87A56F00AE40CD /* ISStoreAccount.swift in Sources */, @@ -464,18 +374,13 @@ ED031A7C1B5127C00097692E /* main.swift in Sources */, ED0F238D1B8756E600AE40CD /* MASError.swift in Sources */, 693A989B1CBFFAAA0004D3B4 /* NSURLSession+Synchronous.swift in Sources */, - 30EA893640B02CCF679F9C57 /* Option.swift in Sources */, - 92AE0FD7BE06D64692E6C1E6 /* OrderedSet.swift in Sources */, ED0F23851B87536A00AE40CD /* Outdated.swift in Sources */, ED0F23891B87543D00AE40CD /* PurchaseDownloadObserver.swift in Sources */, EDCBF9531D89AC6F000039C6 /* Reset.swift in Sources */, - 0EBF5CDD379D7462C3389536 /* Result.swift in Sources */, - 09756A23E9102359296C821B /* ResultProtocol.swift in Sources */, 693A98991CBFFA760004D3B4 /* Search.swift in Sources */, EDC90B651C70045E0019E396 /* SignIn.swift in Sources */, EDE296531C700F4300554778 /* SignOut.swift in Sources */, EDA3BE521B8B84AF00C18D70 /* SSPurchase.swift in Sources */, - 15E27926A580EABEB1B218EF /* Switch.swift in Sources */, EDD3B3631C34709400B56B88 /* Upgrade.swift in Sources */, EDCBF9551D89CFC7000039C6 /* Utilities.swift in Sources */, EDB6CE8C1BAEC3D400648B4D /* Version.swift in Sources */, @@ -486,19 +391,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3F177C62A7053BA3ED415E5E /* Argument.swift in Sources */, - 09A04CB22DC02B86AE4ACC8A /* ArgumentParser.swift in Sources */, - 27340A5BB9F2A5B166E3A72A /* ArgumentProtocol.swift in Sources */, - DE6E193A6671F3D6807F746D /* Command.swift in Sources */, - 4C8321353B9AE40539A1AC8A /* Errors.swift in Sources */, - F48562FA81B0C0258AC063B4 /* HelpCommand.swift in Sources */, F86588272030FAE70093DE57 /* MASError.swift in Sources */, F865880B2030F6DE0093DE57 /* MASErrorTestCase.swift in Sources */, - F6D2058A70757D3477185A50 /* Option.swift in Sources */, - 073998C12AE3BEEC41CE0DAD /* OrderedSet.swift in Sources */, - C50DD25454FC5CAA1F37763F /* Result.swift in Sources */, - EC113CE6C98E8D8358228D33 /* ResultProtocol.swift in Sources */, - 49C2F3FDD805256BE934A70E /* Switch.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };