@@ -32,129 +32,34 @@ import 'src/vm_interop_handler.dart';
32
32
/// analytics logic, it has been moved here.
33
33
Future <void > runDartdev (List <String > args, SendPort port) async {
34
34
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 ();
61
44
}
62
45
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.
82
47
48
+ final runner = DartdevRunner (args);
49
+ var exitCode = 1 ;
83
50
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 ;
125
57
} 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 ();
151
58
VmInteropHandler .exit (exitCode);
152
59
}
153
60
}
154
61
155
62
class DartdevRunner extends CommandRunner <int > {
156
- final Analytics analytics;
157
-
158
63
@override
159
64
final ArgParser argParser = ArgParser (
160
65
usageLineLength: dartdevUsageLineLength,
@@ -164,8 +69,7 @@ class DartdevRunner extends CommandRunner<int> {
164
69
static const String dartdevDescription =
165
70
'A command-line utility for Dart development' ;
166
71
167
- DartdevRunner (List <String > args, this .analytics)
168
- : super ('dart' , '$dartdevDescription .' ) {
72
+ DartdevRunner (List <String > args) : super ('dart' , '$dartdevDescription .' ) {
169
73
final bool verbose = args.contains ('-v' ) || args.contains ('--verbose' );
170
74
171
75
argParser.addFlag ('verbose' ,
@@ -180,12 +84,9 @@ class DartdevRunner extends CommandRunner<int> {
180
84
argParser.addFlag ('diagnostics' ,
181
85
negatable: false , help: 'Show tool diagnostic output.' , hide: ! verbose);
182
86
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.
186
87
argParser.addFlag (
187
- 'disable-dartdev- analytics' ,
188
- negatable: false ,
88
+ 'analytics' ,
89
+ negatable: true ,
189
90
help: 'Disable anonymous analytics for this `dart *` run' ,
190
91
hide: true ,
191
92
);
@@ -212,7 +113,38 @@ class DartdevRunner extends CommandRunner<int> {
212
113
@override
213
114
Future <int > runCommand (ArgResults topLevelResults) async {
214
115
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
+ }
216
148
217
149
if (topLevelResults.command == null &&
218
150
topLevelResults.arguments.isNotEmpty) {
@@ -222,14 +154,12 @@ class DartdevRunner extends CommandRunner<int> {
222
154
io.stderr.writeln (
223
155
"Error when reading '$firstArg ': No such file or directory." );
224
156
// This is the exit code used by the frontend.
225
- VmInteropHandler . exit ( 254 ) ;
157
+ return 254 ;
226
158
}
227
159
}
228
160
229
- isDiagnostics = topLevelResults['diagnostics' ];
230
-
231
161
final Ansi ansi = Ansi (Ansi .terminalSupportsAnsi);
232
- log = isDiagnostics
162
+ log = topLevelResults[ 'diagnostics' ]
233
163
? Logger .verbose (ansi: ansi)
234
164
: Logger .standard (ansi: ansi);
235
165
@@ -247,8 +177,15 @@ class DartdevRunner extends CommandRunner<int> {
247
177
analytics.sendScreenView (path),
248
178
);
249
179
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;
250
187
try {
251
- final exitCode = await super .runCommand (topLevelResults);
188
+ exitCode = await super .runCommand (topLevelResults);
252
189
253
190
if (path != null && analytics.enabled) {
254
191
// Send the event to analytics
@@ -268,8 +205,16 @@ class DartdevRunner extends CommandRunner<int> {
268
205
),
269
206
);
270
207
}
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 ;
273
218
} finally {
274
219
stopwatch.stop ();
275
220
if (analytics.enabled) {
@@ -281,6 +226,32 @@ class DartdevRunner extends CommandRunner<int> {
281
226
),
282
227
);
283
228
}
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;
284
255
}
285
256
}
286
257
}
0 commit comments