@@ -32,129 +32,34 @@ import 'src/vm_interop_handler.dart';
3232/// analytics logic, it has been moved here.
3333Future <void > runDartdev (List <String > args, SendPort port) async {
3434 VmInteropHandler .initialize (port);
35-
36- int result;
37-
38- // The exit code for the dartdev process; null indicates that it has not been
39- // set yet. The value is set in the catch and finally blocks below.
40- int exitCode;
41-
42- // Any caught non-UsageExceptions when running the sub command.
43- Object exception;
44- StackTrace stackTrace;
45-
46- // The Analytics instance used to report information back to Google Analytics;
47- // see lib/src/analytics.dart.
48- final analytics = createAnalyticsInstance (
49- args.contains ('--disable-dartdev-analytics' ),
50- );
51-
52- // If we have not printed the analyticsNoticeOnFirstRunMessage to stdout,
53- // the user is on a terminal, and the machine is not a bot, then print the
54- // disclosure and set analytics.disclosureShownOnTerminal to true.
55- if (analytics is DartdevAnalytics &&
56- ! analytics.disclosureShownOnTerminal &&
57- io.stdout.hasTerminal &&
58- ! isBot ()) {
59- print (analyticsNoticeOnFirstRunMessage);
60- analytics.disclosureShownOnTerminal = true ;
35+ if (args.contains ('run' )) {
36+ // These flags have a format that can't be handled by package:args, so while
37+ // they are valid flags we'll assume the VM has verified them by this point.
38+ args = args
39+ .where (
40+ (element) => ! (element.contains ('--observe' ) ||
41+ element.contains ('--enable-vm-service' )),
42+ )
43+ .toList ();
6144 }
6245
63- // When `--disable-analytics` or `--enable-analytics` are called we perform
64- // the respective intention and print any notices to standard out and exit.
65- if (args.contains ('--disable-analytics' )) {
66- // This block also potentially catches the case of (disableAnalytics &&
67- // enableAnalytics), in which we favor the disabling of analytics.
68- analytics.enabled = false ;
69-
70- // Alert the user that analytics has been disabled.
71- print (analyticsDisabledNoticeMessage);
72- VmInteropHandler .exit (0 );
73- return ;
74- } else if (args.contains ('--enable-analytics' )) {
75- analytics.enabled = true ;
76-
77- // Alert the user again that anonymous data will be collected.
78- print (analyticsNoticeOnFirstRunMessage);
79- VmInteropHandler .exit (0 );
80- return ;
81- }
46+ // Finally, call the runner to execute the command; see DartdevRunner.
8247
48+ final runner = DartdevRunner (args);
49+ var exitCode = 1 ;
8350 try {
84- final runner = DartdevRunner (args, analytics);
85-
86- // Run can't be called with the '--disable-dartdev-analytics' flag; remove
87- // it if it is contained in args.
88- if (args.contains ('--disable-dartdev-analytics' )) {
89- args = List .from (args)..remove ('--disable-dartdev-analytics' );
90- }
91-
92- if (args.contains ('run' )) {
93- // These flags have a format that can't be handled by package:args, so while
94- // they are valid flags we'll assume the VM has verified them by this point.
95- args = args
96- .where (
97- (element) => ! (element.contains ('--observe' ) ||
98- element.contains ('--enable-vm-service' )),
99- )
100- .toList ();
101- }
102-
103- // If ... help pub ... is in the args list, remove 'help', and add '--help'
104- // to the end of the list. This will make it possible to use the help
105- // command to access subcommands of pub such as `dart help pub publish`; see
106- // https://github.com/dart-lang/sdk/issues/42965.
107- if (PubUtils .shouldModifyArgs (args, runner.commands.keys.toList ())) {
108- args = PubUtils .modifyArgs (args);
109- }
110-
111- // Finally, call the runner to execute the command; see DartdevRunner.
112- result = await runner.run (args);
113- } catch (e, st) {
114- if (e is UsageException ) {
115- io.stderr.writeln ('$e ' );
116- exitCode = 64 ;
117- } else {
118- // Set the exception and stack trace only for non-UsageException cases:
119- exception = e;
120- stackTrace = st;
121- io.stderr.writeln ('$e ' );
122- io.stderr.writeln ('$st ' );
123- exitCode = 1 ;
124- }
51+ exitCode = await runner.run (args);
52+ } on UsageException catch (e) {
53+ // TODO(sigurdm): It is unclear when a UsageException gets to here, and
54+ // when it is in DartdevRunner.runCommand.
55+ io.stderr.writeln ('$e ' );
56+ exitCode = 64 ;
12557 } finally {
126- // Set the exitCode, if it wasn't set in the catch block above.
127- exitCode ?? = result ?? 0 ;
128-
129- // Send analytics before exiting
130- if (analytics.enabled) {
131- // And now send the exceptions and events to Google Analytics:
132- if (exception != null ) {
133- unawaited (
134- analytics.sendException (
135- '${exception .runtimeType }\n ${sanitizeStacktrace (stackTrace )}' ,
136- fatal: true ),
137- );
138- }
139-
140- await analytics.waitForLastPing (
141- timeout: const Duration (milliseconds: 200 ));
142- }
143-
144- // Set the enabled flag in the analytics object to true. Note: this will not
145- // enable the analytics unless the disclosure was shown (terminal detected),
146- // and the machine is not detected to be a bot.
147- if (analytics.firstRun) {
148- analytics.enabled = true ;
149- }
150- analytics.close ();
15158 VmInteropHandler .exit (exitCode);
15259 }
15360}
15461
15562class DartdevRunner extends CommandRunner <int > {
156- final Analytics analytics;
157-
15863 @override
15964 final ArgParser argParser = ArgParser (
16065 usageLineLength: dartdevUsageLineLength,
@@ -164,8 +69,7 @@ class DartdevRunner extends CommandRunner<int> {
16469 static const String dartdevDescription =
16570 'A command-line utility for Dart development' ;
16671
167- DartdevRunner (List <String > args, this .analytics)
168- : super ('dart' , '$dartdevDescription .' ) {
72+ DartdevRunner (List <String > args) : super ('dart' , '$dartdevDescription .' ) {
16973 final bool verbose = args.contains ('-v' ) || args.contains ('--verbose' );
17074
17175 argParser.addFlag ('verbose' ,
@@ -180,12 +84,9 @@ class DartdevRunner extends CommandRunner<int> {
18084 argParser.addFlag ('diagnostics' ,
18185 negatable: false , help: 'Show tool diagnostic output.' , hide: ! verbose);
18286
183- // A hidden flag to disable analytics on this run, this constructor can be
184- // called with this flag, but should be removed before run() is called as
185- // the flag has not been added to all sub-commands.
18687 argParser.addFlag (
187- 'disable-dartdev- analytics' ,
188- negatable: false ,
88+ 'analytics' ,
89+ negatable: true ,
18990 help: 'Disable anonymous analytics for this `dart *` run' ,
19091 hide: true ,
19192 );
@@ -212,7 +113,38 @@ class DartdevRunner extends CommandRunner<int> {
212113 @override
213114 Future <int > runCommand (ArgResults topLevelResults) async {
214115 final stopwatch = Stopwatch ()..start ();
215- assert (! topLevelResults.arguments.contains ('--disable-dartdev-analytics' ));
116+ // The Analytics instance used to report information back to Google Analytics;
117+ // see lib/src/analytics.dart.
118+ final analytics = createAnalyticsInstance (! topLevelResults['analytics' ]);
119+
120+ // If we have not printed the analyticsNoticeOnFirstRunMessage to stdout,
121+ // the user is on a terminal, and the machine is not a bot, then print the
122+ // disclosure and set analytics.disclosureShownOnTerminal to true.
123+ if (analytics is DartdevAnalytics &&
124+ ! analytics.disclosureShownOnTerminal &&
125+ io.stdout.hasTerminal &&
126+ ! isBot ()) {
127+ print (analyticsNoticeOnFirstRunMessage);
128+ analytics.disclosureShownOnTerminal = true ;
129+ }
130+
131+ // When `--disable-analytics` or `--enable-analytics` are called we perform
132+ // the respective intention and print any notices to standard out and exit.
133+ if (topLevelResults['disable-analytics' ]) {
134+ // This block also potentially catches the case of (disableAnalytics &&
135+ // enableAnalytics), in which we favor the disabling of analytics.
136+ analytics.enabled = false ;
137+
138+ // Alert the user that analytics has been disabled.
139+ print (analyticsDisabledNoticeMessage);
140+ return 0 ;
141+ } else if (topLevelResults['enable-analytics' ]) {
142+ analytics.enabled = true ;
143+
144+ // Alert the user again that anonymous data will be collected.
145+ print (analyticsNoticeOnFirstRunMessage);
146+ return 0 ;
147+ }
216148
217149 if (topLevelResults.command == null &&
218150 topLevelResults.arguments.isNotEmpty) {
@@ -222,14 +154,12 @@ class DartdevRunner extends CommandRunner<int> {
222154 io.stderr.writeln (
223155 "Error when reading '$firstArg ': No such file or directory." );
224156 // This is the exit code used by the frontend.
225- VmInteropHandler . exit ( 254 ) ;
157+ return 254 ;
226158 }
227159 }
228160
229- isDiagnostics = topLevelResults['diagnostics' ];
230-
231161 final Ansi ansi = Ansi (Ansi .terminalSupportsAnsi);
232- log = isDiagnostics
162+ log = topLevelResults[ 'diagnostics' ]
233163 ? Logger .verbose (ansi: ansi)
234164 : Logger .standard (ansi: ansi);
235165
@@ -247,8 +177,15 @@ class DartdevRunner extends CommandRunner<int> {
247177 analytics.sendScreenView (path),
248178 );
249179
180+ // The exit code for the dartdev process; null indicates that it has not been
181+ // set yet. The value is set in the catch and finally blocks below.
182+ int exitCode;
183+
184+ // Any caught non-UsageExceptions when running the sub command.
185+ Object exception;
186+ StackTrace stackTrace;
250187 try {
251- final exitCode = await super .runCommand (topLevelResults);
188+ exitCode = await super .runCommand (topLevelResults);
252189
253190 if (path != null && analytics.enabled) {
254191 // Send the event to analytics
@@ -268,8 +205,16 @@ class DartdevRunner extends CommandRunner<int> {
268205 ),
269206 );
270207 }
271-
272- return exitCode;
208+ } on UsageException catch (e) {
209+ io.stderr.writeln ('$e ' );
210+ exitCode = 64 ;
211+ } catch (e, st) {
212+ // Set the exception and stack trace only for non-UsageException cases:
213+ exception = e;
214+ stackTrace = st;
215+ io.stderr.writeln ('$e ' );
216+ io.stderr.writeln ('$st ' );
217+ exitCode = 1 ;
273218 } finally {
274219 stopwatch.stop ();
275220 if (analytics.enabled) {
@@ -281,6 +226,32 @@ class DartdevRunner extends CommandRunner<int> {
281226 ),
282227 );
283228 }
229+ // Set the exitCode, if it wasn't set in the catch block above.
230+ exitCode ?? = 0 ;
231+
232+ // Send analytics before exiting
233+ if (analytics.enabled) {
234+ // And now send the exceptions and events to Google Analytics:
235+ if (exception != null ) {
236+ unawaited (
237+ analytics.sendException (
238+ '${exception .runtimeType }\n ${sanitizeStacktrace (stackTrace )}' ,
239+ fatal: true ),
240+ );
241+ }
242+
243+ await analytics.waitForLastPing (
244+ timeout: const Duration (milliseconds: 200 ));
245+ }
246+
247+ // Set the enabled flag in the analytics object to true. Note: this will not
248+ // enable the analytics unless the disclosure was shown (terminal detected),
249+ // and the machine is not detected to be a bot.
250+ if (analytics.firstRun) {
251+ analytics.enabled = true ;
252+ }
253+ analytics.close ();
254+ return exitCode;
284255 }
285256 }
286257}
0 commit comments