Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Side by Side Diff: lib/src/runner/configuration/load.dart

Issue 1782473005: Add support for configuration presets. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Code review changes Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/src/runner/configuration/args.dart ('k') | pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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:boolean_selector/boolean_selector.dart'; 7 import 'package:boolean_selector/boolean_selector.dart';
8 import 'package:glob/glob.dart'; 8 import 'package:glob/glob.dart';
9 import 'package:path/path.dart' as p; 9 import 'package:path/path.dart' as p;
10 import 'package:source_span/source_span.dart'; 10 import 'package:source_span/source_span.dart';
11 import 'package:yaml/yaml.dart'; 11 import 'package:yaml/yaml.dart';
12 12
13 import '../../backend/operating_system.dart'; 13 import '../../backend/operating_system.dart';
14 import '../../backend/platform_selector.dart'; 14 import '../../backend/platform_selector.dart';
15 import '../../backend/test_platform.dart'; 15 import '../../backend/test_platform.dart';
16 import '../../frontend/timeout.dart'; 16 import '../../frontend/timeout.dart';
17 import '../../utils.dart'; 17 import '../../utils.dart';
18 import '../../util/io.dart'; 18 import '../../util/io.dart';
19 import '../configuration.dart'; 19 import '../configuration.dart';
20 import 'values.dart'; 20 import 'values.dart';
21 21
22 /// Loads configuration information from a YAML file at [path]. 22 /// Loads configuration information from a YAML file at [path].
23 /// 23 ///
24 /// Throws a [FormatException] if the configuration is invalid, and a 24 /// Throws a [FormatException] if the configuration is invalid, and a
25 /// [FileSystemException] if it can't be read. 25 /// [FileSystemException] if it can't be read.
26 Configuration load(String path) { 26 Configuration load(String path) {
27 var source = new File(path).readAsStringSync(); 27 var source = new File(path).readAsStringSync();
28 var document = loadYamlNode(source, sourceUrl: p.toUri(path)); 28 var document = loadYamlNode(source, sourceUrl: p.toUri(path));
29 29
30 if (document.value == null) return new Configuration(); 30 if (document.value == null) return Configuration.empty;
31 31
32 if (document is! Map) { 32 if (document is! Map) {
33 throw new SourceSpanFormatException( 33 throw new SourceSpanFormatException(
34 "The configuration must be a YAML map.", document.span, source); 34 "The configuration must be a YAML map.", document.span, source);
35 } 35 }
36 36
37 var loader = new _ConfigurationLoader(document, source); 37 var loader = new _ConfigurationLoader(document, source);
38 return loader.load(); 38 return loader.load();
39 } 39 }
40 40
(...skipping 27 matching lines...) Expand all
68 if (skip is String) { 68 if (skip is String) {
69 skipReason = skip; 69 skipReason = skip;
70 skip = true; 70 skip = true;
71 } 71 }
72 72
73 var testOn = _parseValue("test_on", 73 var testOn = _parseValue("test_on",
74 (value) => new PlatformSelector.parse(value)); 74 (value) => new PlatformSelector.parse(value));
75 75
76 var timeout = _parseValue("timeout", (value) => new Timeout.parse(value)); 76 var timeout = _parseValue("timeout", (value) => new Timeout.parse(value));
77 77
78 var addTags = _getList("add_tags", (tagNode) { 78 var addTags = _getList("add_tags",
79 _validate(tagNode, "Tags must be strings.", (value) => value is String); 79 (tagNode) => _parseIdentifierLike(tagNode, "Tag name"));
80 _validate(
81 tagNode,
82 "Invalid tag. Tags must be (optionally hyphenated) Dart identifiers.",
83 (value) => value.contains(anchoredHyphenatedIdentifier));
84 return tagNode.value;
85 });
86 80
87 var tags = _getMap("tags", 81 var tags = _getMap("tags",
88 key: (keyNode) => _parseNode(keyNode, "tags key", 82 key: (keyNode) => _parseNode(keyNode, "tags key",
89 (value) => new BooleanSelector.parse(value)), 83 (value) => new BooleanSelector.parse(value)),
90 value: (valueNode) => 84 value: (valueNode) =>
91 _nestedConfig(valueNode, "tag value", runnerConfig: false)); 85 _nestedConfig(valueNode, "tag value", runnerConfig: false));
92 86
93 var onPlatform = _getMap("on_platform", 87 var onPlatform = _getMap("on_platform",
94 key: (keyNode) => _parseNode(keyNode, "on_platform key", 88 key: (keyNode) => _parseNode(keyNode, "on_platform key",
95 (value) => new PlatformSelector.parse(value)), 89 (value) => new PlatformSelector.parse(value)),
96 value: (valueNode) => 90 value: (valueNode) =>
97 _nestedConfig(valueNode, "on_platform value", runnerConfig: false)); 91 _nestedConfig(valueNode, "on_platform value", runnerConfig: false));
98 92
99 var onOS = _getMap("on_os", key: (keyNode) { 93 var onOS = _getMap("on_os", key: (keyNode) {
100 _validate(keyNode, "on_os key must be a string.", 94 _validate(keyNode, "on_os key must be a string.",
101 (value) => value is String); 95 (value) => value is String);
102 96
103 var os = OperatingSystem.find(keyNode.value); 97 var os = OperatingSystem.find(keyNode.value);
104 if (os != null) return os; 98 if (os != null) return os;
105 99
106 throw new SourceSpanFormatException( 100 throw new SourceSpanFormatException(
107 'Invalid on_os key: No such operating system.', 101 'Invalid on_os key: No such operating system.',
108 keyNode.span, _source); 102 keyNode.span, _source);
109 }, value: (valueNode) => _nestedConfig(valueNode, "on_os value")); 103 }, value: (valueNode) => _nestedConfig(valueNode, "on_os value"));
110 104
105 var presets = _getMap("presets",
106 key: (keyNode) => _parseIdentifierLike(keyNode, "presets key"),
107 value: (valueNode) => _nestedConfig(valueNode, "presets value"));
108
111 var config = new Configuration( 109 var config = new Configuration(
112 verboseTrace: verboseTrace, 110 verboseTrace: verboseTrace,
113 jsTrace: jsTrace, 111 jsTrace: jsTrace,
114 skip: skip, 112 skip: skip,
115 skipReason: skipReason, 113 skipReason: skipReason,
116 testOn: testOn, 114 testOn: testOn,
117 timeout: timeout, 115 timeout: timeout,
118 addTags: addTags, 116 addTags: addTags,
119 tags: tags, 117 tags: tags,
120 onPlatform: onPlatform); 118 onPlatform: onPlatform,
119 presets: presets);
121 120
122 var osConfig = onOS[currentOS]; 121 var osConfig = onOS[currentOS];
123 return osConfig == null ? config : config.merge(osConfig); 122 return osConfig == null ? config : config.merge(osConfig);
124 } 123 }
125 124
126 /// Loads runner configuration (but not test configuration). 125 /// Loads runner configuration (but not test configuration).
127 /// 126 ///
128 /// If [_runnerConfig] is `false`, this will error if there are any 127 /// If [_runnerConfig] is `false`, this will error if there are any
129 /// runner-level configuration fields. 128 /// runner-level configuration fields.
130 Configuration _loadRunnerConfig() { 129 Configuration _loadRunnerConfig() {
131 if (!_runnerConfig) { 130 if (!_runnerConfig) {
132 _disallow("reporter"); 131 _disallow("reporter");
133 _disallow("pub_serve"); 132 _disallow("pub_serve");
134 _disallow("concurrency"); 133 _disallow("concurrency");
135 _disallow("platforms"); 134 _disallow("platforms");
136 _disallow("paths"); 135 _disallow("paths");
137 _disallow("filename"); 136 _disallow("filename");
138 return new Configuration(); 137 _disallow("add_presets");
138 return Configuration.empty;
139 } 139 }
140 140
141 var reporter = _getString("reporter"); 141 var reporter = _getString("reporter");
142 if (reporter != null && !allReporters.contains(reporter)) { 142 if (reporter != null && !allReporters.contains(reporter)) {
143 _error('Unknown reporter "$reporter".', "reporter"); 143 _error('Unknown reporter "$reporter".', "reporter");
144 } 144 }
145 145
146 var pubServePort = _getInt("pub_serve"); 146 var pubServePort = _getInt("pub_serve");
147 var concurrency = _getInt("concurrency"); 147 var concurrency = _getInt("concurrency");
148 148
(...skipping 10 matching lines...) Expand all
159 159
160 var paths = _getList("paths", (pathNode) { 160 var paths = _getList("paths", (pathNode) {
161 _validate(pathNode, "Paths must be strings.", (value) => value is String); 161 _validate(pathNode, "Paths must be strings.", (value) => value is String);
162 _validate(pathNode, "Paths must be relative.", p.url.isRelative); 162 _validate(pathNode, "Paths must be relative.", p.url.isRelative);
163 163
164 return _parseNode(pathNode, "path", p.fromUri); 164 return _parseNode(pathNode, "path", p.fromUri);
165 }); 165 });
166 166
167 var filename = _parseValue("filename", (value) => new Glob(value)); 167 var filename = _parseValue("filename", (value) => new Glob(value));
168 168
169 var chosenPresets = _getList("add_presets",
170 (presetNode) => _parseIdentifierLike(presetNode, "Preset name"));
171
169 return new Configuration( 172 return new Configuration(
170 reporter: reporter, 173 reporter: reporter,
171 pubServePort: pubServePort, 174 pubServePort: pubServePort,
172 concurrency: concurrency, 175 concurrency: concurrency,
173 platforms: platforms, 176 platforms: platforms,
174 paths: paths, 177 paths: paths,
175 filename: filename); 178 filename: filename,
179 chosenPresets: chosenPresets);
176 } 180 }
177 181
178 /// Throws an exception with [message] if [test] returns `false` when passed 182 /// Throws an exception with [message] if [test] returns `false` when passed
179 /// [node]'s value. 183 /// [node]'s value.
180 void _validate(YamlNode node, String message, bool test(value)) { 184 void _validate(YamlNode node, String message, bool test(value)) {
181 if (test(node.value)) return; 185 if (test(node.value)) return;
182 throw new SourceSpanFormatException(message, node.span, _source); 186 throw new SourceSpanFormatException(message, node.span, _source);
183 } 187 }
184 188
185 /// Returns the value of the node at [field]. 189 /// Returns the value of the node at [field].
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 (value) => value is String); 250 (value) => value is String);
247 251
248 return valueNode.value; 252 return valueNode.value;
249 }; 253 };
250 254
251 return mapMap(node.nodes, 255 return mapMap(node.nodes,
252 key: (keyNode, _) => key(keyNode), 256 key: (keyNode, _) => key(keyNode),
253 value: (_, valueNode) => value(valueNode)); 257 value: (_, valueNode) => value(valueNode));
254 } 258 }
255 259
260 String _parseIdentifierLike(YamlNode node, String name) {
261 _validate(node, "$name must be a string.", (value) => value is String);
262 _validate(
263 node,
264 "$name must be an (optionally hyphenated) Dart identifier.",
265 (value) => value.contains(anchoredHyphenatedIdentifier));
266 return node.value;
267 }
268
256 /// Asserts that [node] is a string, passes its value to [parse], and returns 269 /// Asserts that [node] is a string, passes its value to [parse], and returns
257 /// the result. 270 /// the result.
258 /// 271 ///
259 /// If [parse] throws a [FormatException], it's wrapped to include [node]'s 272 /// If [parse] throws a [FormatException], it's wrapped to include [node]'s
260 /// span. 273 /// span.
261 _parseNode(YamlNode node, String name, parse(String value)) { 274 _parseNode(YamlNode node, String name, parse(String value)) {
262 _validate(node, "$name must be a string.", (value) => value is String); 275 _validate(node, "$name must be a string.", (value) => value is String);
263 276
264 try { 277 try {
265 return parse(node.value); 278 return parse(node.value);
(...skipping 14 matching lines...) Expand all
280 return _parseNode(node, field, parse); 293 return _parseNode(node, field, parse);
281 } 294 }
282 295
283 /// Parses a nested configuration document. 296 /// Parses a nested configuration document.
284 /// 297 ///
285 /// [name] is the name of the field, which is used for error-handling. 298 /// [name] is the name of the field, which is used for error-handling.
286 /// [runnerConfig] controls whether runner configuration is allowed in the 299 /// [runnerConfig] controls whether runner configuration is allowed in the
287 /// nested configuration. It defaults to [_runnerConfig]. 300 /// nested configuration. It defaults to [_runnerConfig].
288 Configuration _nestedConfig(YamlNode node, String name, 301 Configuration _nestedConfig(YamlNode node, String name,
289 {bool runnerConfig}) { 302 {bool runnerConfig}) {
290 if (node == null || node.value == null) return new Configuration(); 303 if (node == null || node.value == null) return Configuration.empty;
291 304
292 _validate(node, "$name must be a map.", (value) => value is Map); 305 _validate(node, "$name must be a map.", (value) => value is Map);
293 var loader = new _ConfigurationLoader(node, _source, 306 var loader = new _ConfigurationLoader(node, _source,
294 runnerConfig: runnerConfig ?? _runnerConfig); 307 runnerConfig: runnerConfig ?? _runnerConfig);
295 return loader.load(); 308 return loader.load();
296 } 309 }
297 310
298 /// Throws an error if a field named [field] exists at this level. 311 /// Throws an error if a field named [field] exists at this level.
299 void _disallow(String field) { 312 void _disallow(String field) {
300 if (!_document.containsKey(field)) return; 313 if (!_document.containsKey(field)) return;
301 _error("$field isn't supported here.", field); 314 _error("$field isn't supported here.", field);
302 } 315 }
303 316
304 /// Throws a [SourceSpanFormatException] with [message] about [field]. 317 /// Throws a [SourceSpanFormatException] with [message] about [field].
305 void _error(String message, String field) { 318 void _error(String message, String field) {
306 throw new SourceSpanFormatException( 319 throw new SourceSpanFormatException(
307 message, _document.nodes[field].span, _source); 320 message, _document.nodes[field].span, _source);
308 } 321 }
309 } 322 }
OLDNEW
« no previous file with comments | « lib/src/runner/configuration/args.dart ('k') | pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698