OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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:analyzer/file_system/physical_file_system.dart'; | 7 import 'package:analyzer/file_system/physical_file_system.dart'; |
8 import 'package:analyzer/src/command_line/arguments.dart'; | 8 import 'package:analyzer/src/command_line/arguments.dart'; |
9 import 'package:analyzer/src/context/builder.dart'; | 9 import 'package:analyzer/src/context/builder.dart'; |
10 import 'package:analyzer/src/util/sdk.dart'; | 10 import 'package:analyzer/src/util/sdk.dart'; |
11 import 'package:analyzer_cli/src/ansi.dart' as ansi; | 11 import 'package:analyzer_cli/src/ansi.dart' as ansi; |
12 import 'package:analyzer_cli/src/driver.dart'; | 12 import 'package:analyzer_cli/src/driver.dart'; |
13 import 'package:args/args.dart'; | 13 import 'package:args/args.dart'; |
| 14 import 'package:telemetry/telemetry.dart' as telemetry; |
14 | 15 |
15 const _binaryName = 'dartanalyzer'; | 16 const _binaryName = 'dartanalyzer'; |
16 | 17 |
17 /// Shared exit handler. | 18 /// Shared exit handler. |
18 /// | 19 /// |
19 /// *Visible for testing.* | 20 /// *Visible for testing.* |
20 ExitHandler exitHandler = exit; | 21 ExitHandler exitHandler = exit; |
21 | 22 |
22 /// Print the given [message] to stderr and exit with the given [exitCode]. | 23 /// Print the given [message] to stderr and exit with the given [exitCode]. |
23 void printAndFail(String message, {int exitCode: 15}) { | 24 void printAndFail(String message, {int exitCode: 15}) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 final bool log; | 109 final bool log; |
109 | 110 |
110 /// Whether to use machine format for error display | 111 /// Whether to use machine format for error display |
111 final bool machineFormat; | 112 final bool machineFormat; |
112 | 113 |
113 /// The path to a file to write a performance log. | 114 /// The path to a file to write a performance log. |
114 /// (Or null if not enabled.) | 115 /// (Or null if not enabled.) |
115 final String perfReport; | 116 final String perfReport; |
116 | 117 |
117 /// Batch mode (for unit testing) | 118 /// Batch mode (for unit testing) |
118 final bool shouldBatch; | 119 final bool batchMode; |
119 | 120 |
120 /// Whether to show package: warnings | 121 /// Whether to show package: warnings |
121 final bool showPackageWarnings; | 122 final bool showPackageWarnings; |
122 | 123 |
123 /// If not null, show package: warnings only for matching packages. | 124 /// If not null, show package: warnings only for matching packages. |
124 final String showPackageWarningsPrefix; | 125 final String showPackageWarningsPrefix; |
125 | 126 |
126 /// Whether to show SDK warnings | 127 /// Whether to show SDK warnings |
127 final bool showSdkWarnings; | 128 final bool showSdkWarnings; |
128 | 129 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 disableCacheFlushing = args['disable-cache-flushing'], | 178 disableCacheFlushing = args['disable-cache-flushing'], |
178 disableHints = args['no-hints'], | 179 disableHints = args['no-hints'], |
179 displayVersion = args['version'], | 180 displayVersion = args['version'], |
180 enableTypeChecks = args['enable_type_checks'], | 181 enableTypeChecks = args['enable_type_checks'], |
181 enableAssertInitializer = args['enable-assert-initializers'], | 182 enableAssertInitializer = args['enable-assert-initializers'], |
182 ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'], | 183 ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'], |
183 lints = args[lintsFlag], | 184 lints = args[lintsFlag], |
184 log = args['log'], | 185 log = args['log'], |
185 machineFormat = args['format'] == 'machine', | 186 machineFormat = args['format'] == 'machine', |
186 perfReport = args['x-perf-report'], | 187 perfReport = args['x-perf-report'], |
187 shouldBatch = args['batch'], | 188 batchMode = args['batch'], |
188 showPackageWarnings = args['show-package-warnings'] || | 189 showPackageWarnings = args['show-package-warnings'] || |
189 args['package-warnings'] || | 190 args['package-warnings'] || |
190 args['x-package-warnings-prefix'] != null, | 191 args['x-package-warnings-prefix'] != null, |
191 showPackageWarningsPrefix = args['x-package-warnings-prefix'], | 192 showPackageWarningsPrefix = args['x-package-warnings-prefix'], |
192 showSdkWarnings = args['sdk-warnings'], | 193 showSdkWarnings = args['sdk-warnings'], |
193 _sourceFiles = args.rest, | 194 _sourceFiles = args.rest, |
194 infosAreFatal = args['fatal-infos'] || args['fatal-hints'], | 195 infosAreFatal = args['fatal-infos'] || args['fatal-hints'], |
195 warningsAreFatal = args['fatal-warnings'], | 196 warningsAreFatal = args['fatal-warnings'], |
196 lintsAreFatal = args['fatal-lints'], | 197 lintsAreFatal = args['fatal-lints'], |
197 strongMode = args['strong'], | 198 strongMode = args['strong'], |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 | 232 |
232 /// Replace the sourceFiles parsed from the command line. | 233 /// Replace the sourceFiles parsed from the command line. |
233 void rewriteSourceFiles(List<String> newSourceFiles) { | 234 void rewriteSourceFiles(List<String> newSourceFiles) { |
234 _sourceFiles = newSourceFiles; | 235 _sourceFiles = newSourceFiles; |
235 } | 236 } |
236 | 237 |
237 /// Parse [args] into [CommandLineOptions] describing the specified | 238 /// Parse [args] into [CommandLineOptions] describing the specified |
238 /// analyzer options. In case of a format error, calls [printAndFail], which | 239 /// analyzer options. In case of a format error, calls [printAndFail], which |
239 /// by default prints an error message to stderr and exits. | 240 /// by default prints an error message to stderr and exits. |
240 static CommandLineOptions parse(List<String> args, | 241 static CommandLineOptions parse(List<String> args, |
241 [printAndFail(String msg) = printAndFail]) { | 242 {printAndFail(String msg) = printAndFail}) { |
242 CommandLineOptions options = _parse(args); | 243 CommandLineOptions options = _parse(args); |
| 244 |
| 245 /// Only happens in testing. |
| 246 if (options == null) { |
| 247 return null; |
| 248 } |
| 249 |
243 // Check SDK. | 250 // Check SDK. |
244 if (!options.buildModePersistentWorker) { | 251 if (!options.buildModePersistentWorker) { |
245 // Infer if unspecified. | 252 // Infer if unspecified. |
246 options.dartSdkPath ??= getSdkPath(args); | 253 options.dartSdkPath ??= getSdkPath(args); |
247 | 254 |
248 String sdkPath = options.dartSdkPath; | 255 String sdkPath = options.dartSdkPath; |
249 | 256 |
250 // Check that SDK is specified. | 257 // Check that SDK is specified. |
251 if (sdkPath == null) { | 258 if (sdkPath == null) { |
252 printAndFail('No Dart SDK found.'); | 259 printAndFail('No Dart SDK found.'); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 ..addFlag('no-hints', | 346 ..addFlag('no-hints', |
340 help: 'Do not show hint results.', | 347 help: 'Do not show hint results.', |
341 defaultsTo: false, | 348 defaultsTo: false, |
342 negatable: false) | 349 negatable: false) |
343 ..addFlag('fatal-infos', | 350 ..addFlag('fatal-infos', |
344 help: 'Treat infos as fatal.', defaultsTo: false, negatable: false) | 351 help: 'Treat infos as fatal.', defaultsTo: false, negatable: false) |
345 ..addFlag('fatal-warnings', | 352 ..addFlag('fatal-warnings', |
346 help: 'Treat non-type warnings as fatal.', | 353 help: 'Treat non-type warnings as fatal.', |
347 defaultsTo: false, | 354 defaultsTo: false, |
348 negatable: false) | 355 negatable: false) |
| 356 ..addFlag('analytics', |
| 357 help: 'Enable or disable sending analytics information to Google.') |
349 ..addFlag('help', | 358 ..addFlag('help', |
350 abbr: 'h', | 359 abbr: 'h', |
351 help: | 360 help: |
352 'Display this help message. Add --verbose to show hidden options.'
, | 361 'Display this help message. Add --verbose to show hidden options.'
, |
353 defaultsTo: false, | 362 defaultsTo: false, |
354 negatable: false) | 363 negatable: false) |
355 ..addFlag('verbose', | 364 ..addFlag('verbose', |
356 abbr: 'v', | 365 abbr: 'v', |
357 defaultsTo: false, | 366 defaultsTo: false, |
358 help: 'Verbose output.', | 367 help: 'Verbose output.', |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 printAndFail('The --persistent_worker flag should be used with and ' | 530 printAndFail('The --persistent_worker flag should be used with and ' |
522 'only with the --build-mode flag, and possibly the --dart-sdk ' | 531 'only with the --build-mode flag, and possibly the --dart-sdk ' |
523 'option. Got: $args'); | 532 'option. Got: $args'); |
524 return null; // Only reachable in testing. | 533 return null; // Only reachable in testing. |
525 } | 534 } |
526 return new CommandLineOptions._fromArgs(results); | 535 return new CommandLineOptions._fromArgs(results); |
527 } | 536 } |
528 | 537 |
529 // Help requests. | 538 // Help requests. |
530 if (results['help']) { | 539 if (results['help']) { |
531 _showUsage(parser); | 540 _showUsage(parser, analytics, fromHelp: true); |
532 exitHandler(0); | 541 exitHandler(0); |
533 return null; // Only reachable in testing. | 542 return null; // Only reachable in testing. |
534 } | 543 } |
| 544 |
| 545 // Enable / disable analytics. |
| 546 if (results.wasParsed('analytics')) { |
| 547 analytics.enabled = results['analytics']; |
| 548 outSink |
| 549 .writeln(telemetry.createAnalyticsStatusMessage(analytics.enabled)); |
| 550 exitHandler(0); |
| 551 return null; // Only reachable in testing. |
| 552 } |
| 553 |
535 // Batch mode and input files. | 554 // Batch mode and input files. |
536 if (results['batch']) { | 555 if (results['batch']) { |
537 if (results.rest.isNotEmpty) { | 556 if (results.rest.isNotEmpty) { |
538 errorSink.writeln('No source files expected in the batch mode.'); | 557 errorSink.writeln('No source files expected in the batch mode.'); |
539 _showUsage(parser); | 558 _showUsage(parser, analytics); |
540 exitHandler(15); | 559 exitHandler(15); |
541 return null; // Only reachable in testing. | 560 return null; // Only reachable in testing. |
542 } | 561 } |
543 } else if (results['persistent_worker']) { | 562 } else if (results['persistent_worker']) { |
544 if (results.rest.isNotEmpty) { | 563 if (results.rest.isNotEmpty) { |
545 errorSink.writeln( | 564 errorSink.writeln( |
546 'No source files expected in the persistent worker mode.'); | 565 'No source files expected in the persistent worker mode.'); |
547 _showUsage(parser); | 566 _showUsage(parser, analytics); |
548 exitHandler(15); | 567 exitHandler(15); |
549 return null; // Only reachable in testing. | 568 return null; // Only reachable in testing. |
550 } | 569 } |
551 } else if (results['version']) { | 570 } else if (results['version']) { |
552 outSink.writeln('$_binaryName version ${_getVersion()}'); | 571 outSink.writeln('$_binaryName version ${_getVersion()}'); |
553 exitHandler(0); | 572 exitHandler(0); |
554 return null; // Only reachable in testing. | 573 return null; // Only reachable in testing. |
555 } else { | 574 } else { |
556 if (results.rest.isEmpty && !results['build-mode']) { | 575 if (results.rest.isEmpty && !results['build-mode']) { |
557 _showUsage(parser); | 576 _showUsage(parser, analytics, fromHelp: true); |
558 exitHandler(15); | 577 exitHandler(15); |
559 return null; // Only reachable in testing. | 578 return null; // Only reachable in testing. |
560 } | 579 } |
561 } | 580 } |
562 return new CommandLineOptions._fromArgs(results); | 581 return new CommandLineOptions._fromArgs(results); |
563 } on FormatException catch (e) { | 582 } on FormatException catch (e) { |
564 errorSink.writeln(e.message); | 583 errorSink.writeln(e.message); |
565 _showUsage(parser); | 584 _showUsage(parser, null); |
566 exitHandler(15); | 585 exitHandler(15); |
567 return null; // Only reachable in testing. | 586 return null; // Only reachable in testing. |
568 } | 587 } |
569 } | 588 } |
570 | 589 |
571 static _showUsage(ArgParser parser) { | 590 static _showUsage(ArgParser parser, telemetry.Analytics analytics, |
| 591 {bool fromHelp: false}) { |
| 592 void printAnalyticsInfo() { |
| 593 if (fromHelp) { |
| 594 errorSink.writeln(''); |
| 595 errorSink.writeln(telemetry.analyticsNotice); |
| 596 } |
| 597 |
| 598 if (analytics != null) { |
| 599 errorSink.writeln(''); |
| 600 errorSink.writeln(telemetry.createAnalyticsStatusMessage( |
| 601 analytics.enabled, |
| 602 command: 'analytics')); |
| 603 } |
| 604 } |
| 605 |
572 errorSink.writeln( | 606 errorSink.writeln( |
573 'Usage: $_binaryName [options...] <directory or list of files>'); | 607 'Usage: $_binaryName [options...] <directory or list of files>'); |
| 608 |
| 609 // If it's our first run, we display the analytics info more prominently. |
| 610 if (analytics != null && analytics.firstRun) { |
| 611 printAnalyticsInfo(); |
| 612 } |
| 613 |
574 errorSink.writeln(''); | 614 errorSink.writeln(''); |
575 errorSink.writeln(parser.usage); | 615 errorSink.writeln(parser.usage); |
| 616 |
| 617 if (analytics != null && !analytics.firstRun) { |
| 618 printAnalyticsInfo(); |
| 619 } |
| 620 |
576 errorSink.writeln(''); | 621 errorSink.writeln(''); |
577 errorSink.writeln(''' | 622 errorSink.writeln(''' |
578 Run "dartanalyzer -h -v" for verbose help output, including less commonly used o
ptions. | 623 Run "dartanalyzer -h -v" for verbose help output, including less commonly used o
ptions. |
579 For more information, see http://www.dartlang.org/tools/analyzer. | 624 For more information, see https://www.dartlang.org/tools/analyzer.\n'''); |
580 '''); | |
581 } | 625 } |
582 } | 626 } |
OLD | NEW |