| 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 |