0001 // 0002 // ArgumentParser.swift 0003 // Commandant 0004 // 0005 // Created by Justin Spahr-Summers on 2014-11-21. 0006 // Copyright (c) 2014 Carthage. All rights reserved. 0007 // 0008 0009 import Foundation 0010 import Result 0011 0012 /// Represents an argument passed on the command line. 0013 private enum RawArgument: Equatable { 0014 /// A key corresponding to an option (e.g., `verbose` for `--verbose`). 0015 case Key
ArgumentParser.swift:25 private func ==(lhs: RawArgument, rhs: RawArgument) -> Bool {ArgumentParser.swift:25 private func ==(lhs: RawArgument, rhs: RawArgument) -> Bool {ArgumentParser.swift:41 extension RawArgument: CustomStringConvertible {ArgumentParser.swift:59 private var rawArguments: [RawArgument] = []ArgumentParser.swift:85 rawArguments.appendContentsOf(positional.map(RawArgument.Value))(String) 0016 0017 /// A value, either associated with an option or passed as a positional 0018 /// argument. 0019 case Value
ArgumentParser.swift:27 case let (.Key(left), .Key(right)):ArgumentParser.swift:27 case let (.Key(left), .Key(right)):ArgumentParser.swift:44 case let .Key(key):ArgumentParser.swift:73 return .Key(String(opt.dropFirst()))ArgumentParser.swift:105 if arg == .Key(key) {ArgumentParser.swift:107 } else if arg == .Key("no-\(key)") {ArgumentParser.swift:167 rawArguments = oldArguments.filter { $0 != .Key(key) }(String) 0020 0021 /// One or more flag arguments (e.g 'r' and 'f' for `-rf`) 0022 case Flag
ArgumentParser.swift:30 case let (.Value(left), .Value(right)):ArgumentParser.swift:30 case let (.Value(left), .Value(right)):ArgumentParser.swift:47 case let .Value(value):ArgumentParser.swift:78 return .Value(arg)ArgumentParser.swift:85 rawArguments.appendContentsOf(positional.map(RawArgument.Value))ArgumentParser.swift:140 guard index < oldArguments.count, case let .Value(value) = oldArguments[index] else {ArgumentParser.swift:154 if case let .Value(value) = arg {(Set<Character>) 0023 } 0024 0025 private func ==(lhs: RawArgument, rhs: RawArgument) -> Bool { 0026 switch (lhs, rhs) { 0027 case let (.Key(left), .Key(right)): 0028 return left == right 0029 0030 case let (.Value(left), .Value(right)): 0031 return left == right 0032 0033 case let (.Flag(left), .Flag(right)): 0034 return left == right 0035 0036 default: 0037 return false 0038 } 0039 } 0040 0041 extension RawArgument: CustomStringConvertible { 0042 private var description
ArgumentParser.swift:33 case let (.Flag(left), .Flag(right)):ArgumentParser.swift:33 case let (.Flag(left), .Flag(right)):ArgumentParser.swift:50 case let .Flag(flags):ArgumentParser.swift:75 return .Flag(Set(opt))ArgumentParser.swift:176 if case let .Flag(flags) = arg where flags.contains(flag) {ArgumentParser.swift:183 rawArguments[index] = .Flag(flags): String { 0043 switch self { 0044 case let .Key(key): 0045 return "--\(key)" 0046 0047 case let .Value(value): 0048 return "\"\(value)\"" 0049 0050 case let .Flag(flags): 0051 return "-\(String(flags))" 0052 } 0053 } 0054 } 0055 0056 /// Destructively parses a list of command-line arguments. 0057 public final class ArgumentParser
ArgumentParser.swift:91 return rawArguments.isEmpty ? nil : rawArguments.map { $0.description }{ 0058 /// The remaining arguments to be extracted, in their raw form. 0059 private var rawArguments
Command.swift:37 public let run: ArgumentParser -> Result<(), CommandantError<ClientError>>Command.swift:45 run = { (arguments: ArgumentParser) -> Result<(), CommandantError<ClientError>> inCommand.swift:71 case Arguments(ArgumentParser): [RawArgument] = [] 0060 0061 /// Initializes the generator from a simple list of command-line arguments. 0062 public init(_ arguments: [String]) { 0063 // The first instance of `--` terminates the option list. 0064 let params = arguments.split(1, allowEmptySlices: true) { $0 == "--" } 0065 0066 // Parse out the keyed and flag options. 0067 let options = params.first! 0068 rawArguments.appendContentsOf(options.map { arg in 0069 if arg.hasPrefix("-") { 0070 // Do we have `--{key}` or `-{flags}`. 0071 let opt = arg.characters.dropFirst() 0072 if opt.first == "-" { 0073 return .Key(String(opt.dropFirst())) 0074 } else { 0075 return .Flag(Set(opt)) 0076 } 0077 } else { 0078 return .Value(arg) 0079 } 0080 }) 0081 0082 // Remaining arguments are all positional parameters. 0083 if params.count == 2 { 0084 let positional = params.last! 0085 rawArguments.appendContentsOf(positional.map(RawArgument.Value)) 0086 } 0087 } 0088 0089 /// Returns the remaining arguments. 0090 internal var remainingArguments: [String]? { 0091 return rawArguments.isEmpty ? nil : rawArguments.map { $0.description } 0092 } 0093 0094 /// Returns whether the given key was enabled or disabled, or nil if it 0095 /// was not given at all. 0096 /// 0097 /// If the key is found, it is then removed from the list of arguments 0098 /// remaining to be parsed. 0099 internal func consumeBooleanKey
ArgumentParser.swift:68 rawArguments.appendContentsOf(options.map { arg inArgumentParser.swift:85 rawArguments.appendContentsOf(positional.map(RawArgument.Value))ArgumentParser.swift:91 return rawArguments.isEmpty ? nil : rawArguments.map { $0.description }ArgumentParser.swift:91 return rawArguments.isEmpty ? nil : rawArguments.map { $0.description }ArgumentParser.swift:100 let oldArguments = rawArgumentsArgumentParser.swift:101 rawArguments.removeAll()ArgumentParser.swift:110 rawArguments.append(arg)ArgumentParser.swift:124 let oldArguments = rawArgumentsArgumentParser.swift:125 rawArguments.removeAll()ArgumentParser.swift:135 rawArguments.append(arg)ArgumentParser.swift:153 for (index, arg) in rawArguments.enumerate() {ArgumentParser.swift:155 rawArguments.removeAtIndex(index)ArgumentParser.swift:166 let oldArguments = rawArgumentsArgumentParser.swift:167 rawArguments = oldArguments.filter { $0 != .Key(key) }ArgumentParser.swift:169 return rawArguments.count < oldArguments.countArgumentParser.swift:175 for (index, arg) in rawArguments.enumerate() {ArgumentParser.swift:181 rawArguments.removeAtIndex(index)ArgumentParser.swift:183 rawArguments[index] = .Flag(flags)(key: String) -> Bool? { 0100 let oldArguments = rawArguments 0101 rawArguments.removeAll() 0102 0103 var result: Bool? 0104 for arg in oldArguments { 0105 if arg == .Key(key) { 0106 result = true 0107 } else if arg == .Key("no-\(key)") { 0108 result = false 0109 } else { 0110 rawArguments.append(arg) 0111 } 0112 } 0113 0114 return result 0115 } 0116 0117 /// Returns the value associated with the given flag, or nil if the flag was 0118 /// not specified. If the key is presented, but no value was given, an error 0119 /// is returned. 0120 /// 0121 /// If a value is found, the key and the value are both removed from the 0122 /// list of arguments remaining to be parsed. 0123 internal func consumeValueForKey(key: String) -> Result<String?, CommandantError<NoError>> { 0124 let oldArguments = rawArguments 0125 rawArguments.removeAll() 0126 0127 var foundValue: String? 0128 var index = 0 0129 0130 while index < oldArguments.count { 0131 defer { index += 1 } 0132 let arg = oldArguments[index] 0133 0134 guard arg == .Key(key) else { 0135 rawArguments.append(arg) 0136 continue 0137 } 0138 0139 index += 1 0140 guard index < oldArguments.count, case let .Value(value) = oldArguments[index] else { 0141 return .Failure(missingArgumentError("--\(key)")) 0142 } 0143 0144 foundValue = value 0145 } 0146 0147 return .Success(foundValue) 0148 } 0149 0150 /// Returns the next positional argument that hasn't yet been returned, or 0151 /// nil if there are no more positional arguments. 0152 internal func consumePositionalArgument
Option.swift:205 if let value = arguments.consumeBooleanKey(option.key) {() -> String? { 0153 for (index, arg) in rawArguments.enumerate() { 0154 if case let .Value(value) = arg { 0155 rawArguments.removeAtIndex(index) 0156 return value 0157 } 0158 } 0159 0160 return nil 0161 } 0162 0163 /// Returns whether the given key was specified and removes it from the 0164 /// list of arguments remaining. 0165 internal func consumeKey
Argument.swift:41 guard let stringValue = arguments.consumePositionalArgument() else {Argument.swift:67 guard let firstValue = arguments.consumePositionalArgument() else {Argument.swift:83 while let nextValue = arguments.consumePositionalArgument() {(key: String) -> Bool { 0166 let oldArguments = rawArguments 0167 rawArguments = oldArguments.filter { $0 != .Key(key) } 0168 0169 return rawArguments.count < oldArguments.count 0170 } 0171 0172 /// Returns whether the given flag was specified and removes it from the 0173 /// list of arguments remaining. 0174 internal func consumeBooleanFlag
Switch.swift:55 var enabled = arguments.consumeKey(option.key)(flag: Character) -> Bool { 0175 for (index, arg) in rawArguments.enumerate() { 0176 if case let .Flag(flags) = arg where flags.contains(flag) { 0177 var flags = flags 0178 flags.remove(flag) 0179 0180 if flags.isEmpty { 0181 rawArguments.removeAtIndex(index) 0182 } else { 0183 rawArguments[index] = .Flag(flags) 0184 } 0185 0186 return true 0187 } 0188 } 0189 0190 return false 0191 } 0192 } 0193
Switch.swift:57 enabled = arguments.consumeBooleanFlag(flag)