@@ -10,6 +10,18 @@ import Cocoa
10
10
11
11
private let EmptyResultDictionary = Options ( )
12
12
13
+ private let optionReporterType : [ String : Option . Type ] = [
14
+ PathLong: PathOption . self, PathShort: PathOption . self,
15
+ TypeLong: TypeOption . self, TypeShort: TypeOption . self,
16
+ FileLong: FileOption . self, FileShort: FileOption . self,
17
+ ExcludeLong: ExcludeOption . self, ExcludeShort: ExcludeOption . self,
18
+ ExcludesFileLong: ExcludesFileOption . self, ExcludesFileShort: ExcludesFileOption . self,
19
+ ReporterLong: ReporterOption . self, ReporterShort: ReporterOption . self,
20
+ RuleCustomizationLong: RuleCustomizationOption . self,
21
+ RuleCustomizationShort: RuleCustomizationOption . self,
22
+ VerbosityLong: VerbosityOption . self, VerbosityShort: VerbosityOption . self
23
+ ]
24
+
13
25
/*
14
26
If you change this class don't forget to fix his mock for actual right tests (if is case)
15
27
*/
@@ -23,11 +35,12 @@ class OptionsProcessor {
23
35
var executableOptions = [ ExecutableOption] ( )
24
36
25
37
func processOptions( arguments: [ String ] ) -> Options {
26
- let options = optionsFromArguments ( arguments)
27
- if options . isEmpty {
28
- return EmptyResultDictionary
38
+ let options = try ! Array ( arguments [ 1 ..< arguments . count ] ) . reduceTwoElements ( [ Option ] ( ) ) {
39
+ if let optionObject = optionObjectFromOption ( $1 , argument : $2 ) { return $0 + optionObject }
40
+ throw CommandLineError . InvalidArguments ( " Error committed on option ` \( $1 ) `. " )
29
41
}
30
- analyzePath = currentAnalyzedPath ( options)
42
+ if options. isEmpty { return EmptyResultDictionary }
43
+ analyzePath = options. filter { $0 is PathOption } . first? . optionArgument. absolutePath ( ) ?? analyzePath
31
44
if !OptionsValidator( ) . validateForSingleOptions ( options) { return EmptyResultDictionary }
32
45
let resultDictionary = buildResultDictionaryFromOptions ( executableOptions)
33
46
guard processInformationalOptions ( ) else { return EmptyResultDictionary }
@@ -46,11 +59,6 @@ class OptionsProcessor {
46
59
return true
47
60
}
48
61
49
- func currentAnalyzedPath( options: [ Option ] ) -> String {
50
- return options. filter { $0 is PathOption } . first? . optionArgument. absolutePath ( ) ?? analyzePath
51
- }
52
-
53
-
54
62
private func buildResultDictionaryFromOptions( options: [ ExecutableOption ] ) -> Options {
55
63
var resultDictionary = EmptyResultDictionary
56
64
if executeOptionsOnDictionary ( & resultDictionary, options: options) {
@@ -111,52 +119,36 @@ class OptionsProcessor {
111
119
}
112
120
113
121
114
- private func optionsFromArguments( arguments: [ String ] ) -> [ Option ] {
115
- var options = [ Option] ( )
116
- for var index = 1 ; in dex < arguments . count ; index+= 2 {
117
- let option = arguments [ index]
118
- let optionArgument = arguments [ index + 1 ]
119
- let optionObject = optionObjectFromOption ( option, argument: optionArgument)
120
- if optionObject == nil {
121
- errorPrinter. printError ( " Error committed on option ` \( option) `. " )
122
- return [ ]
123
- }
124
- options. append ( optionObject!)
122
+ private func optionObjectFromOption( option: String , argument: String ) -> Option ? {
123
+ if option == ExcludesFileLong || option == ExcludesFileShort { isExcludesFileIndicated = true }
124
+ if let optionType = optionReporterType [ option] {
125
+ return configureOption ( optionType, argument: argument)
125
126
}
126
-
127
- return options
127
+ return nil
128
128
}
129
129
130
-
131
- private func optionObjectFromOption( option: String, argument: String) - > Option? {
132
- switch option {
133
- case PathLong, PathShort:
134
- return configureOption ( PathOption . self, argument: argument)
135
- case TypeLong, TypeShort:
136
- return configureOption ( TypeOption . self, argument: argument)
137
- case FileLong, FileShort:
138
- return configureOption ( FileOption . self, argument: argument)
139
- case ExcludeLong, ExcludeShort:
140
- return configureOption ( ExcludeOption . self, argument: argument)
141
- case ExcludesFileLong, ExcludesFileShort:
142
- isExcludesFileIndicated = true
143
- return configureOption ( ExcludesFileOption . self, argument: argument)
144
- case ReporterLong, ReporterShort:
145
- return configureOption ( ReporterOption . self, argument: argument)
146
- case RuleCustomizationLong, RuleCustomizationShort:
147
- return configureOption ( RuleCustomizationOption . self, argument: argument)
148
- case VerbosityLong, VerbosityShort:
149
- return configureOption ( VerbosityOption . self, argument: argument)
150
- default :
151
- return nil
152
- }
153
- }
154
-
155
- func configureOption< T: Option> ( option: T . Type, argument: String) - > T {
156
- let option = T ( argument: argument)
130
+ func configureOption( optionType: Option . Type , argument: String ) -> Option {
131
+ let option = optionType. init ( argument: argument)
157
132
if let infoOption = option as? InformationalOption { infoOptions. append ( infoOption) }
158
133
else { executableOptions. append ( option as! ExecutableOption ) } // Safe to force unwrap
159
134
160
135
return option
161
136
}
162
137
}
138
+
139
+ extension Array {
140
+ func reduceTwoElements< T> ( initial: T , @noescape combine: ( T , Array . Generator . Element , Array . Generator . Element ) throws -> T ) rethrows -> T {
141
+ var result = initial
142
+ for (first, second) in Zip2Sequence ( self . enumerate ( ) . filter { $0. 0 . isEven } . map { $0. 1 } ,
143
+ self . enumerate ( ) . filter { $0. 0 . isOdd } . map { $0. 1 } ) {
144
+ do {
145
+ result = try combine ( result, first, second)
146
+ } catch let error as NSError {
147
+ errorPrinter. printError ( error. localizedDescription)
148
+ return initial
149
+ }
150
+
151
+ }
152
+ return result
153
+ }
154
+ }
0 commit comments