Skip to content

Commit 1682e0b

Browse files
committed
Support "--checked" in pub run and global run.
Fixes #1230. [email protected] Review URL: https://codereview.chromium.org//1272813003 .
1 parent 097ed87 commit 1682e0b

8 files changed

+112
-26
lines changed

lib/src/command/global_run.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class GlobalRunCommand extends PubCommand {
2626
BarbackMode get mode => new BarbackMode(argResults["mode"]);
2727

2828
GlobalRunCommand() {
29+
argParser.addFlag("checked", abbr: "c",
30+
help: "Enable runtime type checks and assertions.");
2931
argParser.addOption("mode", defaultsTo: "release",
3032
help: 'Mode to run transformers in.');
3133
}
@@ -48,14 +50,12 @@ class GlobalRunCommand extends PubCommand {
4850

4951
var args = argResults.rest.skip(1).toList();
5052
if (p.split(executable).length > 1) {
51-
// TODO(nweiz): Use adjacent strings when the new async/await compiler
52-
// lands.
53-
usageException('Cannot run an executable in a subdirectory of a global ' +
53+
usageException('Cannot run an executable in a subdirectory of a global '
5454
'package.');
5555
}
5656

5757
var exitCode = await globals.runExecutable(package, executable, args,
58-
mode: mode);
58+
checked: argResults["checked"], mode: mode);
5959
await flushThenExit(exitCode);
6060
}
6161
}

lib/src/command/run.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class RunCommand extends PubCommand {
2222
bool get allowTrailingOptions => false;
2323

2424
RunCommand() {
25+
argParser.addFlag("checked", abbr: "c",
26+
help: "Enable runtime type checks and assertions.");
2527
argParser.addOption("mode",
2628
help: 'Mode to run transformers in.\n'
2729
'(defaults to "release" for dependencies, "debug" for '
@@ -66,7 +68,7 @@ class RunCommand extends PubCommand {
6668
}
6769

6870
var exitCode = await runExecutable(entrypoint, package, executable, args,
69-
mode: mode);
71+
checked: argResults['checked'], mode: mode);
7072
await flushThenExit(exitCode);
7173
}
7274
}

lib/src/executable.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ final _catchableSignals = Platform.isWindows
4444
///
4545
/// Arguments from [args] will be passed to the spawned Dart application.
4646
///
47-
/// If [mode] is passed, it's used as the barback mode; it defaults to
48-
/// [BarbackMode.RELEASE].
47+
/// If [checked] is true, the program is run in checked mode. If [mode] is
48+
/// passed, it's used as the barback mode; it defaults to [BarbackMode.RELEASE].
4949
///
5050
/// Returns the exit code of the spawned app.
5151
Future<int> runExecutable(Entrypoint entrypoint, String package,
5252
String executable, Iterable<String> args, {bool isGlobal: false,
53-
BarbackMode mode}) async {
53+
bool checked: false, BarbackMode mode}) async {
5454
if (mode == null) mode = BarbackMode.RELEASE;
5555

5656
// Make sure the package is an immediate dependency of the entrypoint or the
@@ -84,7 +84,8 @@ Future<int> runExecutable(Entrypoint entrypoint, String package,
8484
// default mode for them to run. We can't run them in a different mode
8585
// using the snapshot.
8686
mode == BarbackMode.RELEASE) {
87-
return _runCachedExecutable(entrypoint, localSnapshotPath, args);
87+
return _runCachedExecutable(entrypoint, localSnapshotPath, args,
88+
checked: checked);
8889
}
8990

9091
// If the command has a path separator, then it's a path relative to the
@@ -95,8 +96,7 @@ Future<int> runExecutable(Entrypoint entrypoint, String package,
9596
var vmArgs = [];
9697

9798
// Run in checked mode.
98-
// TODO(rnystrom): Make this configurable.
99-
vmArgs.add("--checked");
99+
if (checked) vmArgs.add("--checked");
100100

101101
var executableUrl = await _executableUrl(
102102
entrypoint, package, executable, isGlobal: isGlobal, mode: mode);
@@ -268,8 +268,8 @@ void _forwardSignals(Process process) {
268268

269269
/// Runs the executable snapshot at [snapshotPath].
270270
Future<int> _runCachedExecutable(Entrypoint entrypoint, String snapshotPath,
271-
List<String> args) {
272-
return runSnapshot(snapshotPath, args, checked: true, recompile: () {
271+
List<String> args, {bool checked: false}) {
272+
return runSnapshot(snapshotPath, args, checked: checked, recompile: () {
273273
log.fine("Precompiled executable is out of date.");
274274
return entrypoint.precompileExecutables();
275275
});

lib/src/global_packages.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,20 +329,21 @@ class GlobalPackages {
329329
/// recompiled if the SDK has been upgraded since it was first compiled and
330330
/// then run. Otherwise, it will be run from source.
331331
///
332-
/// If [mode] is passed, it's used as the barback mode; it defaults to
332+
/// If [checked] is true, the program is run in checked mode. If [mode] is
333+
/// passed, it's used as the barback mode; it defaults to
333334
/// [BarbackMode.RELEASE].
334335
///
335336
/// Returns the exit code from the executable.
336337
Future<int> runExecutable(String package, String executable,
337-
Iterable<String> args, {BarbackMode mode}) {
338+
Iterable<String> args, {bool checked: false, BarbackMode mode}) {
338339
if (mode == null) mode = BarbackMode.RELEASE;
339340

340341
var binDir = p.join(_directory, package, 'bin');
341342
if (mode != BarbackMode.RELEASE ||
342343
!fileExists(p.join(binDir, '$executable.dart.snapshot'))) {
343344
return find(package).then((entrypoint) {
344345
return exe.runExecutable(entrypoint, package, executable, args,
345-
mode: mode, isGlobal: true);
346+
isGlobal: true, checked: checked, mode: mode);
346347
});
347348
}
348349

@@ -353,7 +354,7 @@ class GlobalPackages {
353354
}
354355

355356
var snapshotPath = p.join(binDir, '$executable.dart.snapshot');
356-
return exe.runSnapshot(snapshotPath, args, recompile: () {
357+
return exe.runSnapshot(snapshotPath, args, checked: checked, recompile: () {
357358
log.fine("$package:$executable is out of date and needs to be "
358359
"recompiled.");
359360
return find(package)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
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.
4+
5+
import 'package:scheduled_test/scheduled_test.dart';
6+
import 'package:scheduled_test/scheduled_stream.dart';
7+
8+
import '../../descriptor.dart' as d;
9+
import '../../test_pub.dart';
10+
11+
main() {
12+
integration('runs a script in checked mode', () {
13+
servePackages((builder) {
14+
builder.serve("foo", "1.0.0", contents: [
15+
d.dir("bin", [
16+
d.file("script.dart", "main() { int a = true; }")
17+
])
18+
]);
19+
});
20+
21+
schedulePub(args: ["global", "activate", "foo"]);
22+
23+
var pub = pubRun(global: true, args: ["--checked", "foo:script"]);
24+
pub.stderr.expect(consumeThrough(contains(
25+
"'bool' is not a subtype of type 'int' of 'a'")));
26+
pub.shouldExit(255);
27+
});
28+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
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.
4+
5+
import 'package:scheduled_test/scheduled_test.dart';
6+
7+
import '../../descriptor.dart' as d;
8+
import '../../test_pub.dart';
9+
10+
const SCRIPT = """
11+
main() {
12+
int a = true;
13+
print("no checks");
14+
}
15+
""";
16+
17+
main() {
18+
integration('runs a script in unchecked mode by default', () {
19+
servePackages((builder) {
20+
builder.serve("foo", "1.0.0", contents: [
21+
d.dir("bin", [
22+
d.file("script.dart", SCRIPT)
23+
])
24+
]);
25+
});
26+
27+
schedulePub(args: ["global", "activate", "foo"]);
28+
29+
var pub = pubRun(global: true, args: ["foo:script"]);
30+
pub.stdout.expect("no checks");
31+
pub.shouldExit();
32+
});
33+
}

test/run/runs_the_script_in_checked_mode_test.dart

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,16 @@ import 'package:scheduled_test/scheduled_test.dart';
77
import '../descriptor.dart' as d;
88
import '../test_pub.dart';
99

10-
const SCRIPT = """
1110
main() {
12-
int a = true;
13-
}
14-
""";
15-
16-
main() {
17-
integration('runs the script in checked mode by default', () {
11+
integration('runs the script in checked mode with "--checked"', () {
1812
d.dir(appPath, [
1913
d.appPubspec(),
2014
d.dir("bin", [
21-
d.file("script.dart", SCRIPT)
15+
d.file("script.dart", "main() { int a = true; }")
2216
])
2317
]).create();
2418

25-
schedulePub(args: ["run", "bin/script"],
19+
schedulePub(args: ["run", "--checked", "bin/script"],
2620
error: contains("'bool' is not a subtype of type 'int' of 'a'"),
2721
exitCode: 255);
2822
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
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.
4+
5+
import 'package:scheduled_test/scheduled_test.dart';
6+
7+
import '../descriptor.dart' as d;
8+
import '../test_pub.dart';
9+
10+
const SCRIPT = """
11+
main() {
12+
int a = true;
13+
print("no checks");
14+
}
15+
""";
16+
17+
main() {
18+
integration('runs the script in unchecked mode by default', () {
19+
d.dir(appPath, [
20+
d.appPubspec(),
21+
d.dir("bin", [
22+
d.file("script.dart", SCRIPT)
23+
])
24+
]).create();
25+
26+
schedulePub(args: ["run", "bin/script"], output: contains("no checks"));
27+
});
28+
}

0 commit comments

Comments
 (0)