OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:io'; | 5 import 'dart:io'; |
6 | 6 |
7 import 'package:args/args.dart'; | 7 import 'package:args/args.dart'; |
8 import 'package:boolean_selector/boolean_selector.dart'; | 8 import 'package:boolean_selector/boolean_selector.dart'; |
9 | 9 |
10 import '../../backend/test_platform.dart'; | 10 import '../../backend/test_platform.dart'; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 | 105 |
106 return parser; | 106 return parser; |
107 })(); | 107 })(); |
108 | 108 |
109 /// The usage string for the command-line arguments. | 109 /// The usage string for the command-line arguments. |
110 String get usage => _parser.usage; | 110 String get usage => _parser.usage; |
111 | 111 |
112 /// Parses the configuration from [args]. | 112 /// Parses the configuration from [args]. |
113 /// | 113 /// |
114 /// Throws a [FormatException] if [args] are invalid. | 114 /// Throws a [FormatException] if [args] are invalid. |
115 Configuration parse(List<String> args) { | 115 Configuration parse(List<String> args) => new _Parser(args).parse(); |
116 var options = _parser.parse(args); | |
117 | 116 |
118 var patterns = options['name'] | 117 /// A class for parsing an argument list. |
119 .map((value) => _wrapFormatException('name', () => new RegExp(value))) | 118 /// |
120 .toList() | 119 /// This is used to provide access to the arg results across helper methods. |
121 ..addAll(options['plain-name']); | 120 class _Parser { |
| 121 /// The parsed options. |
| 122 final ArgResults _options; |
122 | 123 |
123 var includeTagSet = new Set.from(options['tags'] ?? []) | 124 _Parser(List<String> args) : _options = _parser.parse(args); |
124 ..addAll(options['tag'] ?? []); | |
125 | 125 |
126 var includeTags = includeTagSet.fold(BooleanSelector.all, (selector, tag) { | 126 /// Returns the parsed configuration. |
127 var tagSelector = new BooleanSelector.parse(tag); | 127 Configuration parse() { |
128 return selector.intersection(tagSelector); | 128 var patterns = _options['name'] |
129 }); | 129 .map((value) => _wrapFormatException('name', () => new RegExp(value))) |
| 130 .toList() |
| 131 ..addAll(_options['plain-name']); |
130 | 132 |
131 var excludeTagSet = new Set.from(options['exclude-tags'] ?? []) | 133 var includeTagSet = new Set.from(_options['tags'] ?? []) |
132 ..addAll(options['exclude-tag'] ?? []); | 134 ..addAll(_options['tag'] ?? []); |
133 | 135 |
134 var excludeTags = excludeTagSet.fold(BooleanSelector.none, (selector, tag) { | 136 var includeTags = includeTagSet.fold(BooleanSelector.all, (selector, tag) { |
135 var tagSelector = new BooleanSelector.parse(tag); | 137 var tagSelector = new BooleanSelector.parse(tag); |
136 return selector.union(tagSelector); | 138 return selector.intersection(tagSelector); |
137 }); | 139 }); |
138 | 140 |
139 // If the user hasn't explicitly chosen a value, we want to pass null values | 141 var excludeTagSet = new Set.from(_options['exclude-tags'] ?? []) |
140 // to [new Configuration] so that it considers those fields unset when merging | 142 ..addAll(_options['exclude-tag'] ?? []); |
141 // with configuration from the config file. | |
142 ifParsed(name) => options.wasParsed(name) ? options[name] : null; | |
143 | 143 |
144 return new Configuration( | 144 var excludeTags = excludeTagSet.fold(BooleanSelector.none, (selector, tag) { |
145 help: ifParsed('help'), | 145 var tagSelector = new BooleanSelector.parse(tag); |
146 version: ifParsed('version'), | 146 return selector.union(tagSelector); |
147 verboseTrace: ifParsed('verbose-trace'), | 147 }); |
148 jsTrace: ifParsed('js-trace'), | |
149 pauseAfterLoad: ifParsed('pause-after-load'), | |
150 color: ifParsed('color'), | |
151 packageRoot: ifParsed('package-root'), | |
152 reporter: ifParsed('reporter'), | |
153 pubServePort: _parseOption(options, 'pub-serve', int.parse), | |
154 concurrency: _parseOption(options, 'concurrency', int.parse), | |
155 timeout: _parseOption(options, 'timeout', | |
156 (value) => new Timeout.parse(value)), | |
157 patterns: patterns, | |
158 platforms: ifParsed('platform')?.map(TestPlatform.find), | |
159 chosenPresets: ifParsed('preset'), | |
160 paths: options.rest.isEmpty ? null : options.rest, | |
161 includeTags: includeTags, | |
162 excludeTags: excludeTags); | |
163 } | |
164 | 148 |
165 /// Runs [parse] on the value of the option [name], and wraps any | 149 return new Configuration( |
166 /// [FormatException] it throws with additional information. | 150 help: _ifParsed('help'), |
167 _parseOption(ArgResults options, String name, parse(value)) { | 151 version: _ifParsed('version'), |
168 if (!options.wasParsed(name)) return null; | 152 verboseTrace: _ifParsed('verbose-trace'), |
| 153 jsTrace: _ifParsed('js-trace'), |
| 154 pauseAfterLoad: _ifParsed('pause-after-load'), |
| 155 color: _ifParsed('color'), |
| 156 packageRoot: _ifParsed('package-root'), |
| 157 reporter: _ifParsed('reporter'), |
| 158 pubServePort: _parseOption('pub-serve', int.parse), |
| 159 concurrency: _parseOption('concurrency', int.parse), |
| 160 timeout: _parseOption('timeout', (value) => new Timeout.parse(value)), |
| 161 patterns: patterns, |
| 162 platforms: _ifParsed('platform')?.map(TestPlatform.find), |
| 163 chosenPresets: _ifParsed('preset'), |
| 164 paths: _options.rest.isEmpty ? null : _options.rest, |
| 165 includeTags: includeTags, |
| 166 excludeTags: excludeTags); |
| 167 } |
169 | 168 |
170 var value = options[name]; | 169 /// Returns the parsed option for [name], or `null` if none was parsed. |
171 if (value == null) return null; | 170 /// |
| 171 /// If the user hasn't explicitly chosen a value, we want to pass null values |
| 172 /// to [new Configuration] so that it considers those fields unset when |
| 173 /// merging with configuration from the config file. |
| 174 _ifParsed(String name) => _options.wasParsed(name) ? _options[name] : null; |
172 | 175 |
173 return _wrapFormatException(name, () => parse(value)); | 176 /// Runs [parse] on the value of the option [name], and wraps any |
174 } | 177 /// [FormatException] it throws with additional information. |
| 178 _parseOption(String name, parse(value)) { |
| 179 if (!_options.wasParsed(name)) return null; |
175 | 180 |
176 /// Runs [parse], and wraps any [FormatException] it throws with additional | 181 var value = _options[name]; |
177 /// information. | 182 if (value == null) return null; |
178 _wrapFormatException(String name, parse()) { | 183 |
179 try { | 184 return _wrapFormatException(name, () => parse(value)); |
180 return parse(); | 185 } |
181 } on FormatException catch (error) { | 186 |
182 throw new FormatException('Couldn\'t parse --$name "${options[name]}": ' | 187 /// Runs [parse], and wraps any [FormatException] it throws with additional |
183 '${error.message}'); | 188 /// information. |
| 189 _wrapFormatException(String name, parse()) { |
| 190 try { |
| 191 return parse(); |
| 192 } on FormatException catch (error) { |
| 193 throw new FormatException('Couldn\'t parse --$name "${_options[name]}": ' |
| 194 '${error.message}'); |
| 195 } |
184 } | 196 } |
185 } | 197 } |
OLD | NEW |