diff --git a/lib/src/command/get.dart b/lib/src/command/get.dart index b94114001..a5ea74299 100644 --- a/lib/src/command/get.dart +++ b/lib/src/command/get.dart @@ -27,7 +27,7 @@ class GetCommand extends PubCommand { help: "Report what dependencies would change but don't change any."); argParser.addFlag('precompile', - defaultsTo: true, + defaultsTo: false, help: "Precompile executables in immediate dependencies."); argParser.addFlag('packages-dir', negatable: true, hide: true); diff --git a/lib/src/command/run.dart b/lib/src/command/run.dart index 7014348ec..c5da1b3c9 100644 --- a/lib/src/command/run.dart +++ b/lib/src/command/run.dart @@ -71,8 +71,13 @@ class RunCommand extends PubCommand { var exitCode = await runExecutable(entrypoint, package, executable, args, checked: argResults['enable-asserts'] || argResults['checked'], - snapshotPath: useSnapshot ? snapshotPath : null, - recompile: entrypoint.precompileExecutables); + snapshotPath: useSnapshot ? snapshotPath : null, recompile: () { + final pkg = entrypoint.packageGraph.packages[package]; + // The recompile function will only be called when [package] exists. + assert(pkg != null); + final executablePath = pkg.path(p.join("bin", executable)); + return entrypoint.precompileExecutable(package, executablePath); + }); await flushThenExit(exitCode); } } diff --git a/lib/src/command/upgrade.dart b/lib/src/command/upgrade.dart index e65e75c6f..98e44ae7e 100644 --- a/lib/src/command/upgrade.dart +++ b/lib/src/command/upgrade.dart @@ -29,7 +29,7 @@ class UpgradeCommand extends PubCommand { help: "Report what dependencies would change but don't change any."); argParser.addFlag('precompile', - defaultsTo: true, + defaultsTo: false, help: "Precompile executables in immediate dependencies."); argParser.addFlag('packages-dir', negatable: true, hide: true); diff --git a/lib/src/entrypoint.dart b/lib/src/entrypoint.dart index 1b407fce2..36a9d2b32 100644 --- a/lib/src/entrypoint.dart +++ b/lib/src/entrypoint.dart @@ -213,7 +213,7 @@ class Entrypoint { Future acquireDependencies(SolveType type, {List useLatest, bool dryRun = false, - bool precompile = true}) async { + bool precompile = false}) async { var result = await resolveVersions(type, cache, root, lockFile: lockFile, useLatest: useLatest); @@ -294,20 +294,32 @@ class Entrypoint { } //// Precompiles [executables] to snapshots from the filesystem. - Future _precompileExecutables(Map> executables) { + Future _precompileExecutables(Map> executables) { return waitAndPrintErrors(executables.keys.map((package) { var dir = p.join(_snapshotPath, package); cleanDir(dir); - return waitAndPrintErrors(executables[package].map((path) { - var url = p.toUri(p.join(packageGraph.packages[package].dir, path)); - return dart.snapshot( - url, p.join(dir, p.basename(path) + '.snapshot.dart2'), - packagesFile: p.toUri(packagesFile), - name: '$package:${p.basenameWithoutExtension(path)}'); - })); + return waitAndPrintErrors(executables[package] + .map((path) => _precompileExecutable(package, path))); })); } + /// Precompiles executable .dart file at [path] to a snapshot. + Future precompileExecutable(String package, String path) async { + return await log.progress("Precompiling executable", () async { + var dir = p.join(_snapshotPath, package); + ensureDir(dir); + return waitAndPrintErrors([_precompileExecutable(package, path)]); + }); + } + + Future _precompileExecutable(String package, String path) async { + var dir = p.join(_snapshotPath, package); + var url = p.toUri(p.join(packageGraph.packages[package].dir, path)); + await dart.snapshot(url, p.join(dir, p.basename(path) + '.snapshot.dart2'), + packagesFile: p.toUri(packagesFile), + name: '$package:${p.basenameWithoutExtension(path)}'); + } + /// Deletes outdated cached executable snapshots. /// /// If [changed] is passed, only dependencies whose contents might be changed diff --git a/lib/src/executable.dart b/lib/src/executable.dart index e38188807..a48c33342 100644 --- a/lib/src/executable.dart +++ b/lib/src/executable.dart @@ -58,8 +58,10 @@ Future runExecutable(Entrypoint entrypoint, String package, entrypoint.migrateCache(); // Unless the user overrides the verbosity, we want to filter out the - // normal pub output that may be shown when recompiling snapshots. - if (log.verbosity == log.Verbosity.NORMAL) { + // normal pub output that may be shown when recompiling snapshots if we are + // not attached to a terminal. This is to not pollute stdout when the output + // of `pub run` is piped somewhere. + if (log.verbosity == log.Verbosity.NORMAL && !stdout.hasTerminal) { log.verbosity = log.Verbosity.WARNING; } diff --git a/lib/src/global_packages.dart b/lib/src/global_packages.dart index e13c63ee7..eafdea814 100644 --- a/lib/src/global_packages.dart +++ b/lib/src/global_packages.dart @@ -145,7 +145,7 @@ class GlobalPackages { var entrypoint = Entrypoint(path, cache); // Get the package's dependencies. - await entrypoint.acquireDependencies(SolveType.GET); + await entrypoint.acquireDependencies(SolveType.GET, precompile: true); var name = entrypoint.root.name; // Call this just to log what the current active package is, if any. diff --git a/test/run/package_api_test.dart b/test/run/package_api_test.dart index cdb6b5ba6..e79e841f6 100644 --- a/test/run/package_api_test.dart +++ b/test/run/package_api_test.dart @@ -56,10 +56,12 @@ main() { d.appPubspec({"foo": "any"}) ]).create(); - await pubGet(output: contains("Precompiled foo:script.")); + await pubGet(); var pub = await pubRun(args: ["foo:script"]); + expect(pub.stdout, emits('Precompiling executable...')); + expect(pub.stdout, emits('Precompiled foo:script.')); expect(pub.stdout, emits("null")); expect(pub.stdout, emits(p.toUri(p.join(d.sandbox, "myapp/.packages")).toString())); diff --git a/test/run/runs_from_a_dependency_override_after_dependency_test.dart b/test/run/runs_from_a_dependency_override_after_dependency_test.dart index 12d0f9958..b283169ac 100644 --- a/test/run/runs_from_a_dependency_override_after_dependency_test.dart +++ b/test/run/runs_from_a_dependency_override_after_dependency_test.dart @@ -23,7 +23,7 @@ main() { d.appPubspec({"foo": null}) ]).create(); - await pubGet(); + await pubGet(args: ['--precompile']); var pub = await pubRun(args: ["foo:bar"]); expect(pub.stdout, emits("foobar")); diff --git a/test/snapshot_test.dart b/test/snapshot_test.dart index bc3ff7329..310b6850e 100644 --- a/test/snapshot_test.dart +++ b/test/snapshot_test.dart @@ -26,10 +26,11 @@ main() { await d.appDir({"foo": "1.2.3"}).create(); await pubGet( + args: ['--precompile'], output: allOf([ - contains("Precompiled foo:hello."), - contains("Precompiled foo:goodbye.") - ])); + contains("Precompiled foo:hello."), + contains("Precompiled foo:goodbye.") + ])); await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin'), [ d.file('sdk-version', '0.1.2+3\n'), @@ -67,10 +68,11 @@ main() { await d.appDir({"foo": "1.2.3"}).create(); await pubGet( + args: ['--precompile'], output: allOf([ - contains("Precompiled foo:hello."), - contains("Precompiled foo:goodbye.") - ])); + contains("Precompiled foo:hello."), + contains("Precompiled foo:goodbye.") + ])); await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin'), [ d.file('sdk-version', '0.1.2+3\n'), @@ -102,7 +104,8 @@ main() { await d.appDir({"foo": "any"}).create(); - await pubGet(output: contains("Precompiled foo:hello.")); + await pubGet( + args: ['--precompile'], output: contains("Precompiled foo:hello.")); await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [ d.file('hello.dart.snapshot.dart2', contains('hello!')) @@ -115,7 +118,8 @@ main() { ]); }); - await pubUpgrade(output: contains("Precompiled foo:hello.")); + await pubUpgrade( + args: ['--precompile'], output: contains("Precompiled foo:hello.")); await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [ d.file('hello.dart.snapshot.dart2', contains('hello 2!')) @@ -146,7 +150,8 @@ main() { await d.appDir({"foo": "any"}).create(); - await pubGet(output: contains("Precompiled foo:hello.")); + await pubGet( + args: ['--precompile'], output: contains("Precompiled foo:hello.")); await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [ d.file('hello.dart.snapshot.dart2', contains('hello!')) @@ -158,7 +163,8 @@ main() { ]); }); - await pubUpgrade(output: contains("Precompiled foo:hello.")); + await pubUpgrade( + args: ['--precompile'], output: contains("Precompiled foo:hello.")); await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [ d.file('hello.dart.snapshot.dart2', contains('hello 2!')) @@ -182,7 +188,8 @@ main() { "foo": {"git": "../foo.git"} }).create(); - await pubGet(output: contains("Precompiled foo:hello.")); + await pubGet( + args: ['--precompile'], output: contains("Precompiled foo:hello.")); await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [ d.file('hello.dart.snapshot.dart2', contains('Hello!')) @@ -193,7 +200,8 @@ main() { [d.file("hello.dart", "void main() => print('Goodbye!');")]) ]).commit(); - await pubUpgrade(output: contains("Precompiled foo:hello.")); + await pubUpgrade( + args: ['--precompile'], output: contains("Precompiled foo:hello.")); await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [ d.file('hello.dart.snapshot.dart2', contains('Goodbye!')) @@ -214,7 +222,8 @@ main() { await d.appDir({"foo": "5.6.7"}).create(); - await pubGet(output: contains("Precompiled foo:hello.")); + await pubGet( + args: ['--precompile'], output: contains("Precompiled foo:hello.")); await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin'), [ d.dir('foo', [d.outOfDateSnapshot('hello.dart.snapshot.dart2')]) @@ -224,7 +233,7 @@ main() { // In the real world this would just print "hello!", but since we collect // all output we see the precompilation messages as well. - expect(process.stdout, emits("Precompiling executables...")); + expect(process.stdout, emits("Precompiling executable...")); expect(process.stdout, emitsThrough("hello!")); await process.shouldExit();