From 0d9a9659c6f1700af01d87f2df784352f6902232 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 1 Feb 2018 15:37:43 -0800 Subject: [PATCH 1/2] Consolidate snapshot tests into one file These were in separate files for infrastructure reasons that no longer apply. --- ...for_immediate_and_transitive_dep_test.dart | 53 -- test/snapshot/creates_a_snapshot_test.dart | 51 -- ...snt_load_irrelevant_transformers_test.dart | 53 -- ...t_when_a_dependency_is_unchanged_test.dart | 35 -- ...napshot_an_entrypoint_dependency_test.dart | 33 -- .../doesnt_snapshot_path_dependency_test.dart | 29 - ...snapshot_transitive_dependencies_test.dart | 29 - test/snapshot/no_precompile_test.dart | 100 ---- ...ints_errors_for_broken_snapshots_test.dart | 53 -- ...mpiles_if_the_sdk_is_out_of_date_test.dart | 41 -- .../snapshots_transformed_code_test.dart | 63 -- ...ates_snapshot_for_git_dependency_test.dart | 42 -- ...upgrades_snapshot_for_dependency_test.dart | 52 -- test/snapshot/upgrades_snapshot_test.dart | 42 -- test/snapshot_test.dart | 536 ++++++++++++++++++ 15 files changed, 536 insertions(+), 676 deletions(-) delete mode 100644 test/snapshot/creates_a_snapshot_for_immediate_and_transitive_dep_test.dart delete mode 100644 test/snapshot/creates_a_snapshot_test.dart delete mode 100644 test/snapshot/doesnt_load_irrelevant_transformers_test.dart delete mode 100644 test/snapshot/doesnt_resnapshot_when_a_dependency_is_unchanged_test.dart delete mode 100644 test/snapshot/doesnt_snapshot_an_entrypoint_dependency_test.dart delete mode 100644 test/snapshot/doesnt_snapshot_path_dependency_test.dart delete mode 100644 test/snapshot/doesnt_snapshot_transitive_dependencies_test.dart delete mode 100644 test/snapshot/no_precompile_test.dart delete mode 100644 test/snapshot/prints_errors_for_broken_snapshots_test.dart delete mode 100644 test/snapshot/recompiles_if_the_sdk_is_out_of_date_test.dart delete mode 100644 test/snapshot/snapshots_transformed_code_test.dart delete mode 100644 test/snapshot/updates_snapshot_for_git_dependency_test.dart delete mode 100644 test/snapshot/upgrades_snapshot_for_dependency_test.dart delete mode 100644 test/snapshot/upgrades_snapshot_test.dart create mode 100644 test/snapshot_test.dart diff --git a/test/snapshot/creates_a_snapshot_for_immediate_and_transitive_dep_test.dart b/test/snapshot/creates_a_snapshot_for_immediate_and_transitive_dep_test.dart deleted file mode 100644 index ddcc58956..000000000 --- a/test/snapshot/creates_a_snapshot_for_immediate_and_transitive_dep_test.dart +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -main() { - test( - "creates a snapshot for an immediate dependency that's also a " - "transitive dependency", () async { - await servePackages((builder) { - builder.serve("foo", "1.2.3", contents: [ - d.dir("bin", [ - d.file("hello.dart", "void main() => print('hello!');"), - d.file("goodbye.dart", "void main() => print('goodbye!');"), - d.file("shell.sh", "echo shell"), - d.dir("subdir", [d.file("sub.dart", "void main() => print('sub!');")]) - ]) - ]); - builder.serve("bar", "1.2.3", deps: {"foo": "1.2.3"}); - }); - - await d.appDir({"foo": "1.2.3"}).create(); - - await pubGet( - output: allOf([ - contains("Precompiled foo:hello."), - contains("Precompiled foo:goodbye.") - ])); - - await d.dir(p.join(appPath, '.pub', 'bin'), [ - d.file('sdk-version', '0.1.2+3\n'), - d.dir('foo', [ - d.file('hello.dart.snapshot', contains('hello!')), - d.file('goodbye.dart.snapshot', contains('goodbye!')), - d.nothing('shell.sh.snapshot'), - d.nothing('subdir') - ]) - ]).validate(); - - var process = await pubRun(args: ['foo:hello']); - expect(process.stdout, emits("hello!")); - await process.shouldExit(); - - process = await pubRun(args: ['foo:goodbye']); - expect(process.stdout, emits("goodbye!")); - await process.shouldExit(); - }); -} diff --git a/test/snapshot/creates_a_snapshot_test.dart b/test/snapshot/creates_a_snapshot_test.dart deleted file mode 100644 index cbf5f4ffb..000000000 --- a/test/snapshot/creates_a_snapshot_test.dart +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -main() { - test("creates a snapshot for an immediate dependency's executables", - () async { - await servePackages((builder) { - builder.serve("foo", "1.2.3", contents: [ - d.dir("bin", [ - d.file("hello.dart", "void main() => print('hello!');"), - d.file("goodbye.dart", "void main() => print('goodbye!');"), - d.file("shell.sh", "echo shell"), - d.dir("subdir", [d.file("sub.dart", "void main() => print('sub!');")]) - ]) - ]); - }); - - await d.appDir({"foo": "1.2.3"}).create(); - - await pubGet( - output: allOf([ - contains("Precompiled foo:hello."), - contains("Precompiled foo:goodbye.") - ])); - - await d.dir(p.join(appPath, '.pub', 'bin'), [ - d.file('sdk-version', '0.1.2+3\n'), - d.dir('foo', [ - d.file('hello.dart.snapshot', contains('hello!')), - d.file('goodbye.dart.snapshot', contains('goodbye!')), - d.nothing('shell.sh.snapshot'), - d.nothing('subdir') - ]) - ]).validate(); - - var process = await pubRun(args: ['foo:hello']); - expect(process.stdout, emits("hello!")); - await process.shouldExit(); - - process = await pubRun(args: ['foo:goodbye']); - expect(process.stdout, emits("goodbye!")); - await process.shouldExit(); - }); -} diff --git a/test/snapshot/doesnt_load_irrelevant_transformers_test.dart b/test/snapshot/doesnt_load_irrelevant_transformers_test.dart deleted file mode 100644 index 5b9d634b0..000000000 --- a/test/snapshot/doesnt_load_irrelevant_transformers_test.dart +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -const BROKEN_TRANSFORMER = """ -import 'dart:async'; - -import 'package:barback/barback.dart'; - -class BrokenTransformer extends Transformer { - BrokenTransformer.asPlugin(); - - // This file intentionally has a syntax error so that any attempt to load it - // will crash. -"""; - -main() { - // Regression test for issue 20917. - test("snapshots the transformed version of an executable", () async { - await servePackages((builder) { - builder.serveRealPackage('barback'); - - builder.serve("foo", "1.2.3", contents: [ - d.dir("bin", [d.file("hello.dart", "void main() => print('hello!');")]) - ]); - }); - - await d.dir(appPath, [ - d.pubspec({ - "name": "myapp", - "dependencies": {"foo": "1.2.3", "barback": "any"}, - "transformers": ["myapp"] - }), - d.dir("lib", [d.file("transformer.dart", BROKEN_TRANSFORMER)]) - ]).create(); - - await pubGet(output: contains("Precompiled foo:hello.")); - - await d.dir(p.join(appPath, '.pub', 'bin'), [ - d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) - ]).validate(); - - var process = await pubRun(args: ['foo:hello']); - expect(process.stdout, emits("hello!")); - await process.shouldExit(); - }); -} diff --git a/test/snapshot/doesnt_resnapshot_when_a_dependency_is_unchanged_test.dart b/test/snapshot/doesnt_resnapshot_when_a_dependency_is_unchanged_test.dart deleted file mode 100644 index 3d242adf8..000000000 --- a/test/snapshot/doesnt_resnapshot_when_a_dependency_is_unchanged_test.dart +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -main() { - test( - "doesn't recreate a snapshot when no dependencies of a package " - "have changed", () async { - await servePackages((builder) { - builder.serve("foo", "1.2.3", deps: { - "bar": "any" - }, contents: [ - d.dir("bin", [d.file("hello.dart", "void main() => print('hello!');")]) - ]); - builder.serve("bar", "1.2.3"); - }); - - await d.appDir({"foo": "1.2.3"}).create(); - - await pubGet(output: contains("Precompiled foo:hello.")); - - await pubUpgrade(output: isNot(contains("Precompiled foo:hello."))); - - await d.dir(p.join(appPath, '.pub', 'bin'), [ - d.file('sdk-version', '0.1.2+3\n'), - d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) - ]).validate(); - }); -} diff --git a/test/snapshot/doesnt_snapshot_an_entrypoint_dependency_test.dart b/test/snapshot/doesnt_snapshot_an_entrypoint_dependency_test.dart deleted file mode 100644 index f5c5f3cb4..000000000 --- a/test/snapshot/doesnt_snapshot_an_entrypoint_dependency_test.dart +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:test/test.dart'; - -import 'package:path/path.dart' as p; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -main() { - test( - "doesn't create a snapshot for a package that depends on the " - "entrypoint", () async { - await servePackages((builder) { - builder.serve("foo", "1.2.3", deps: { - 'bar': '1.2.3' - }, contents: [ - d.dir("bin", [d.file("hello.dart", "void main() => print('hello!');")]) - ]); - builder.serve("bar", "1.2.3", deps: {'myapp': 'any'}); - }); - - await d.appDir({"foo": "1.2.3"}).create(); - - await pubGet(); - - // No local cache should be created, since all dependencies transitively - // depend on the entrypoint. - await d.nothing(p.join(appPath, '.pub', 'bin')).validate(); - }); -} diff --git a/test/snapshot/doesnt_snapshot_path_dependency_test.dart b/test/snapshot/doesnt_snapshot_path_dependency_test.dart deleted file mode 100644 index 56e69f5d3..000000000 --- a/test/snapshot/doesnt_snapshot_path_dependency_test.dart +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:test/test.dart'; - -import 'package:path/path.dart' as p; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -main() { - test("doesn't create a snapshot for a path dependency", () async { - await d.dir("foo", [ - d.libPubspec("foo", "1.2.3"), - d.dir("bin", [ - d.dir("bin", [d.file("hello.dart", "void main() => print('hello!');")]) - ]) - ]).create(); - - await d.appDir({ - "foo": {"path": "../foo"} - }).create(); - - await pubGet(); - - await d.nothing(p.join(appPath, '.pub', 'bin')).validate(); - }); -} diff --git a/test/snapshot/doesnt_snapshot_transitive_dependencies_test.dart b/test/snapshot/doesnt_snapshot_transitive_dependencies_test.dart deleted file mode 100644 index 3cacdfb7d..000000000 --- a/test/snapshot/doesnt_snapshot_transitive_dependencies_test.dart +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:test/test.dart'; - -import 'package:path/path.dart' as p; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -main() { - test( - "doesn't create a snapshot for transitive dependencies' " - "executables", () async { - await servePackages((builder) { - builder.serve("foo", "1.2.3", deps: {'bar': '1.2.3'}); - builder.serve("bar", "1.2.3", contents: [ - d.dir("bin", [d.file("hello.dart", "void main() => print('hello!');")]) - ]); - }); - - await d.appDir({"foo": "1.2.3"}).create(); - - await pubGet(); - - await d.nothing(p.join(appPath, '.pub', 'bin', 'bar')).validate(); - }); -} diff --git a/test/snapshot/no_precompile_test.dart b/test/snapshot/no_precompile_test.dart deleted file mode 100644 index d90e7fa60..000000000 --- a/test/snapshot/no_precompile_test.dart +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -main() { - group("with --no-precompile,", () { - test("doesn't create a new snapshot", () async { - await servePackages((builder) { - builder.serve("foo", "1.2.3", contents: [ - d.dir("bin", [ - d.file("hello.dart", "void main() => print('hello!');"), - d.file("goodbye.dart", "void main() => print('goodbye!');"), - d.file("shell.sh", "echo shell"), - d.dir( - "subdir", [d.file("sub.dart", "void main() => print('sub!');")]) - ]) - ]); - }); - - await d.appDir({"foo": "1.2.3"}).create(); - - await pubGet( - args: ["--no-precompile"], output: isNot(contains("Precompiled"))); - - await d.nothing(p.join(appPath, '.pub')).validate(); - - var process = await pubRun(args: ['foo:hello']); - expect(process.stdout, emits("hello!")); - await process.shouldExit(); - - process = await pubRun(args: ['foo:goodbye']); - expect(process.stdout, emits("goodbye!")); - await process.shouldExit(); - }); - - test("deletes a snapshot when its package is upgraded", () async { - await servePackages((builder) { - builder.serve("foo", "1.2.3", contents: [ - d.dir( - "bin", [d.file("hello.dart", "void main() => print('hello!');")]) - ]); - }); - - await d.appDir({"foo": "any"}).create(); - - await pubGet(output: contains("Precompiled foo:hello.")); - - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), - [d.file('hello.dart.snapshot', contains('hello!'))]).validate(); - - await globalPackageServer.add((builder) { - builder.serve("foo", "1.2.4", contents: [ - d.dir("bin", - [d.file("hello.dart", "void main() => print('hello 2!');")]) - ]); - }); - - await pubUpgrade( - args: ["--no-precompile"], output: isNot(contains("Precompiled"))); - - await d.nothing(p.join(appPath, '.pub', 'bin', 'foo')).validate(); - - var process = await pubRun(args: ['foo:hello']); - expect(process.stdout, emits("hello 2!")); - await process.shouldExit(); - }); - - test( - "doesn't delete a snapshot when no dependencies of a package " - "have changed", () async { - await servePackages((builder) { - builder.serve("foo", "1.2.3", deps: { - "bar": "any" - }, contents: [ - d.dir( - "bin", [d.file("hello.dart", "void main() => print('hello!');")]) - ]); - builder.serve("bar", "1.2.3"); - }); - - await d.appDir({"foo": "1.2.3"}).create(); - - await pubGet(output: contains("Precompiled foo:hello.")); - - await pubUpgrade( - args: ["--no-precompile"], output: isNot(contains("Precompiled"))); - - await d.dir(p.join(appPath, '.pub', 'bin'), [ - d.file('sdk-version', '0.1.2+3\n'), - d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) - ]).validate(); - }); - }); -} diff --git a/test/snapshot/prints_errors_for_broken_snapshots_test.dart b/test/snapshot/prints_errors_for_broken_snapshots_test.dart deleted file mode 100644 index 956184c96..000000000 --- a/test/snapshot/prints_errors_for_broken_snapshots_test.dart +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -main() { - test("prints errors for broken snapshot compilation", () async { - await servePackages((builder) { - builder.serve("foo", "1.2.3", contents: [ - d.dir("bin", [ - d.file("hello.dart", "void main() { no closing brace"), - d.file("goodbye.dart", "void main() { no closing brace"), - ]) - ]); - builder.serve("bar", "1.2.3", contents: [ - d.dir("bin", [ - d.file("hello.dart", "void main() { no closing brace"), - d.file("goodbye.dart", "void main() { no closing brace"), - ]) - ]); - }); - - await d.appDir({"foo": "1.2.3", "bar": "1.2.3"}).create(); - - // This should still have a 0 exit code, since installation succeeded even - // if precompilation didn't. - await pubGet( - error: allOf([ - contains("Failed to precompile foo:hello"), - contains("Failed to precompile foo:goodbye"), - contains("Failed to precompile bar:hello"), - contains("Failed to precompile bar:goodbye") - ]), - exitCode: 0); - - await d.dir(p.join(appPath, '.pub', 'bin'), [ - d.file('sdk-version', '0.1.2+3\n'), - d.dir('foo', [ - d.nothing('hello.dart.snapshot'), - d.nothing('goodbye.dart.snapshot') - ]), - d.dir('bar', [ - d.nothing('hello.dart.snapshot'), - d.nothing('goodbye.dart.snapshot') - ]) - ]).validate(); - }); -} diff --git a/test/snapshot/recompiles_if_the_sdk_is_out_of_date_test.dart b/test/snapshot/recompiles_if_the_sdk_is_out_of_date_test.dart deleted file mode 100644 index 6968ab8bd..000000000 --- a/test/snapshot/recompiles_if_the_sdk_is_out_of_date_test.dart +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -main() { - test("creates a snapshot for an immediate dependency's executables", - () async { - await servePackages((builder) { - builder.serve("foo", "5.6.7", contents: [ - d.dir("bin", [d.file("hello.dart", "void main() => print('hello!');")]) - ]); - }); - - await d.appDir({"foo": "5.6.7"}).create(); - - await pubGet(output: contains("Precompiled foo:hello.")); - - await d.dir(p.join(appPath, '.pub', 'bin'), [ - d.dir('foo', [d.outOfDateSnapshot('hello.dart.snapshot')]) - ]).create(); - - var process = await pubRun(args: ['foo:hello']); - - // 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, emitsThrough("hello!")); - await process.shouldExit(); - - await d.dir(p.join(appPath, '.pub', 'bin'), [ - d.file('sdk-version', '0.1.2+3\n'), - d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) - ]).validate(); - }); -} diff --git a/test/snapshot/snapshots_transformed_code_test.dart b/test/snapshot/snapshots_transformed_code_test.dart deleted file mode 100644 index f18e64653..000000000 --- a/test/snapshot/snapshots_transformed_code_test.dart +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -const REPLACE_TRANSFORMER = """ -import 'dart:async'; - -import 'package:barback/barback.dart'; - -class ReplaceTransformer extends Transformer { - ReplaceTransformer.asPlugin(); - - String get allowedExtensions => '.dart'; - - Future apply(Transform transform) { - return transform.primaryInput.readAsString().then((contents) { - transform.addOutput(new Asset.fromString(transform.primaryInput.id, - contents.replaceAll("REPLACE ME", "hello!"))); - }); - } -} -"""; - -main() { - test("snapshots the transformed version of an executable", () async { - await servePackages((builder) { - builder.serveRealPackage('barback'); - - builder.serve("foo", "1.2.3", deps: { - "barback": "any" - }, pubspec: { - 'transformers': ['foo'] - }, contents: [ - d.dir("lib", [d.file("foo.dart", REPLACE_TRANSFORMER)]), - d.dir("bin", [ - d.file("hello.dart", """ -final message = 'REPLACE ME'; - -void main() => print(message); -"""), - ]) - ]); - }); - - await d.appDir({"foo": "1.2.3"}).create(); - - await pubGet(output: contains("Precompiled foo:hello.")); - - await d.dir(p.join(appPath, '.pub', 'bin'), [ - d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) - ]).validate(); - - var process = await pubRun(args: ['foo:hello']); - expect(process.stdout, emits("hello!")); - await process.shouldExit(); - }); -} diff --git a/test/snapshot/updates_snapshot_for_git_dependency_test.dart b/test/snapshot/updates_snapshot_for_git_dependency_test.dart deleted file mode 100644 index 001e99f31..000000000 --- a/test/snapshot/updates_snapshot_for_git_dependency_test.dart +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -main() { - test("upgrades a snapshot when a git dependency is upgraded", () async { - await ensureGit(); - - await d.git('foo.git', [ - d.pubspec({"name": "foo", "version": "0.0.1"}), - d.dir("bin", [d.file("hello.dart", "void main() => print('Hello!');")]) - ]).create(); - - await d.appDir({ - "foo": {"git": "../foo.git"} - }).create(); - - await pubGet(output: contains("Precompiled foo:hello.")); - - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), - [d.file('hello.dart.snapshot', contains('Hello!'))]).validate(); - - await d.git('foo.git', [ - d.dir("bin", [d.file("hello.dart", "void main() => print('Goodbye!');")]) - ]).commit(); - - await pubUpgrade(output: contains("Precompiled foo:hello.")); - - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), - [d.file('hello.dart.snapshot', contains('Goodbye!'))]).validate(); - - var process = await pubRun(args: ['foo:hello']); - expect(process.stdout, emits("Goodbye!")); - await process.shouldExit(); - }); -} diff --git a/test/snapshot/upgrades_snapshot_for_dependency_test.dart b/test/snapshot/upgrades_snapshot_for_dependency_test.dart deleted file mode 100644 index fec15d84d..000000000 --- a/test/snapshot/upgrades_snapshot_for_dependency_test.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -main() { - test("upgrades a snapshot when a dependency is upgraded", () async { - await servePackages((builder) { - builder.serve("foo", "1.2.3", pubspec: { - "dependencies": {"bar": "any"} - }, contents: [ - d.dir("bin", [ - d.file("hello.dart", """ -import 'package:bar/bar.dart'; - -void main() => print(message); -""") - ]) - ]); - builder.serve("bar", "1.2.3", contents: [ - d.dir("lib", [d.file("bar.dart", "final message = 'hello!';")]) - ]); - }); - - await d.appDir({"foo": "any"}).create(); - - await pubGet(output: contains("Precompiled foo:hello.")); - - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), - [d.file('hello.dart.snapshot', contains('hello!'))]).validate(); - - await globalPackageServer.add((builder) { - builder.serve("bar", "1.2.4", contents: [ - d.dir("lib", [d.file("bar.dart", "final message = 'hello 2!';")]), - ]); - }); - - await pubUpgrade(output: contains("Precompiled foo:hello.")); - - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), - [d.file('hello.dart.snapshot', contains('hello 2!'))]).validate(); - - var process = await pubRun(args: ['foo:hello']); - expect(process.stdout, emits("hello 2!")); - await process.shouldExit(); - }); -} diff --git a/test/snapshot/upgrades_snapshot_test.dart b/test/snapshot/upgrades_snapshot_test.dart deleted file mode 100644 index f569ab555..000000000 --- a/test/snapshot/upgrades_snapshot_test.dart +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -main() { - test("upgrades a snapshot when its package is upgraded", () async { - await servePackages((builder) { - builder.serve("foo", "1.2.3", contents: [ - d.dir("bin", [d.file("hello.dart", "void main() => print('hello!');")]) - ]); - }); - - await d.appDir({"foo": "any"}).create(); - - await pubGet(output: contains("Precompiled foo:hello.")); - - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), - [d.file('hello.dart.snapshot', contains('hello!'))]).validate(); - - await globalPackageServer.add((builder) { - builder.serve("foo", "1.2.4", contents: [ - d.dir( - "bin", [d.file("hello.dart", "void main() => print('hello 2!');")]) - ]); - }); - - await pubUpgrade(output: contains("Precompiled foo:hello.")); - - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), - [d.file('hello.dart.snapshot', contains('hello 2!'))]).validate(); - - var process = await pubRun(args: ['foo:hello']); - expect(process.stdout, emits("hello 2!")); - await process.shouldExit(); - }); -} diff --git a/test/snapshot_test.dart b/test/snapshot_test.dart new file mode 100644 index 000000000..5093aa3b6 --- /dev/null +++ b/test/snapshot_test.dart @@ -0,0 +1,536 @@ +// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:path/path.dart' as p; +import 'package:test/test.dart'; + +import 'descriptor.dart' as d; +import 'test_pub.dart'; + +main() { + group("creates a snapshot", () { + test("for an immediate dependency", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", contents: [ + d.dir("bin", [ + d.file("hello.dart", "void main() => print('hello!');"), + d.file("goodbye.dart", "void main() => print('goodbye!');"), + d.file("shell.sh", "echo shell"), + d.dir( + "subdir", [d.file("sub.dart", "void main() => print('sub!');")]) + ]) + ]); + }); + + await d.appDir({"foo": "1.2.3"}).create(); + + await pubGet( + output: allOf([ + contains("Precompiled foo:hello."), + contains("Precompiled foo:goodbye.") + ])); + + await d.dir(p.join(appPath, '.pub', 'bin'), [ + d.file('sdk-version', '0.1.2+3\n'), + d.dir('foo', [ + d.file('hello.dart.snapshot', contains('hello!')), + d.file('goodbye.dart.snapshot', contains('goodbye!')), + d.nothing('shell.sh.snapshot'), + d.nothing('subdir') + ]) + ]).validate(); + + var process = await pubRun(args: ['foo:hello']); + expect(process.stdout, emits("hello!")); + await process.shouldExit(); + + process = await pubRun(args: ['foo:goodbye']); + expect(process.stdout, emits("goodbye!")); + await process.shouldExit(); + }); + + test("for an immediate dependency that's also transitive", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", contents: [ + d.dir("bin", [ + d.file("hello.dart", "void main() => print('hello!');"), + d.file("goodbye.dart", "void main() => print('goodbye!');"), + d.file("shell.sh", "echo shell"), + d.dir( + "subdir", [d.file("sub.dart", "void main() => print('sub!');")]) + ]) + ]); + builder.serve("bar", "1.2.3", deps: {"foo": "1.2.3"}); + }); + + await d.appDir({"foo": "1.2.3"}).create(); + + await pubGet( + output: allOf([ + contains("Precompiled foo:hello."), + contains("Precompiled foo:goodbye.") + ])); + + await d.dir(p.join(appPath, '.pub', 'bin'), [ + d.file('sdk-version', '0.1.2+3\n'), + d.dir('foo', [ + d.file('hello.dart.snapshot', contains('hello!')), + d.file('goodbye.dart.snapshot', contains('goodbye!')), + d.nothing('shell.sh.snapshot'), + d.nothing('subdir') + ]) + ]).validate(); + + var process = await pubRun(args: ['foo:hello']); + expect(process.stdout, emits("hello!")); + await process.shouldExit(); + + process = await pubRun(args: ['foo:goodbye']); + expect(process.stdout, emits("goodbye!")); + await process.shouldExit(); + }); + + test("of the transformed version of an executable", () async { + await servePackages((builder) { + builder.serveRealPackage('barback'); + + builder.serve("foo", "1.2.3", deps: { + "barback": "any" + }, pubspec: { + 'transformers': ['foo'] + }, contents: [ + d.dir("lib", [ + d.file("foo.dart", """ + import 'dart:async'; + + import 'package:barback/barback.dart'; + + class ReplaceTransformer extends Transformer { + ReplaceTransformer.asPlugin(); + + String get allowedExtensions => '.dart'; + + Future apply(Transform transform) { + return transform.primaryInput.readAsString().then((contents) { + transform.addOutput(new Asset.fromString(transform.primaryInput.id, + contents.replaceAll("REPLACE ME", "hello!"))); + }); + } + } + """) + ]), + d.dir("bin", [ + d.file("hello.dart", """ + final message = 'REPLACE ME'; + + void main() => print(message); + """), + ]) + ]); + }); + + await d.appDir({"foo": "1.2.3"}).create(); + + await pubGet(output: contains("Precompiled foo:hello.")); + + await d.dir(p.join(appPath, '.pub', 'bin'), [ + d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) + ]).validate(); + + var process = await pubRun(args: ['foo:hello']); + expect(process.stdout, emits("hello!")); + await process.shouldExit(); + }); + + group("again if", () { + test("its package is updated", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", contents: [ + d.dir("bin", + [d.file("hello.dart", "void main() => print('hello!');")]) + ]); + }); + + await d.appDir({"foo": "any"}).create(); + + await pubGet(output: contains("Precompiled foo:hello.")); + + await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + [d.file('hello.dart.snapshot', contains('hello!'))]).validate(); + + await globalPackageServer.add((builder) { + builder.serve("foo", "1.2.4", contents: [ + d.dir("bin", + [d.file("hello.dart", "void main() => print('hello 2!');")]) + ]); + }); + + await pubUpgrade(output: contains("Precompiled foo:hello.")); + + await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + [d.file('hello.dart.snapshot', contains('hello 2!'))]).validate(); + + var process = await pubRun(args: ['foo:hello']); + expect(process.stdout, emits("hello 2!")); + await process.shouldExit(); + }); + + test("a dependency of its package is updated", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", pubspec: { + "dependencies": {"bar": "any"} + }, contents: [ + d.dir("bin", [ + d.file("hello.dart", """ + import 'package:bar/bar.dart'; + + void main() => print(message); + """) + ]) + ]); + builder.serve("bar", "1.2.3", contents: [ + d.dir("lib", [d.file("bar.dart", "final message = 'hello!';")]) + ]); + }); + + await d.appDir({"foo": "any"}).create(); + + await pubGet(output: contains("Precompiled foo:hello.")); + + await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + [d.file('hello.dart.snapshot', contains('hello!'))]).validate(); + + await globalPackageServer.add((builder) { + builder.serve("bar", "1.2.4", contents: [ + d.dir("lib", [d.file("bar.dart", "final message = 'hello 2!';")]), + ]); + }); + + await pubUpgrade(output: contains("Precompiled foo:hello.")); + + await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + [d.file('hello.dart.snapshot', contains('hello 2!'))]).validate(); + + var process = await pubRun(args: ['foo:hello']); + expect(process.stdout, emits("hello 2!")); + await process.shouldExit(); + }); + + test("a git dependency of its package is updated", () async { + await ensureGit(); + + await d.git('foo.git', [ + d.pubspec({"name": "foo", "version": "0.0.1"}), + d.dir( + "bin", [d.file("hello.dart", "void main() => print('Hello!');")]) + ]).create(); + + await d.appDir({ + "foo": {"git": "../foo.git"} + }).create(); + + await pubGet(output: contains("Precompiled foo:hello.")); + + await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + [d.file('hello.dart.snapshot', contains('Hello!'))]).validate(); + + await d.git('foo.git', [ + d.dir("bin", + [d.file("hello.dart", "void main() => print('Goodbye!');")]) + ]).commit(); + + await pubUpgrade(output: contains("Precompiled foo:hello.")); + + await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + [d.file('hello.dart.snapshot', contains('Goodbye!'))]).validate(); + + var process = await pubRun(args: ['foo:hello']); + expect(process.stdout, emits("Goodbye!")); + await process.shouldExit(); + }); + + test("the SDK is out of date", () async { + await servePackages((builder) { + builder.serve("foo", "5.6.7", contents: [ + d.dir("bin", + [d.file("hello.dart", "void main() => print('hello!');")]) + ]); + }); + + await d.appDir({"foo": "5.6.7"}).create(); + + await pubGet(output: contains("Precompiled foo:hello.")); + + await d.dir(p.join(appPath, '.pub', 'bin'), [ + d.dir('foo', [d.outOfDateSnapshot('hello.dart.snapshot')]) + ]).create(); + + var process = await pubRun(args: ['foo:hello']); + + // 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, emitsThrough("hello!")); + await process.shouldExit(); + + await d.dir(p.join(appPath, '.pub', 'bin'), [ + d.file('sdk-version', '0.1.2+3\n'), + d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) + ]).validate(); + }); + }); + }); + + // Regression test for #1127. + test("doesn't load irrelevant transformers", () async { + await servePackages((builder) { + builder.serveRealPackage('barback'); + + builder.serve("foo", "1.2.3", contents: [ + d.dir("bin", [d.file("hello.dart", "void main() => print('hello!');")]) + ]); + }); + + await d.dir(appPath, [ + d.pubspec({ + "name": "myapp", + "dependencies": {"foo": "1.2.3", "barback": "any"}, + "transformers": ["myapp"] + }), + d.dir("lib", [ + d.file("transformer.dart", """ + import 'dart:async'; + + import 'package:barback/barback.dart'; + + class BrokenTransformer extends Transformer { + BrokenTransformer.asPlugin(); + + // This file intentionally has a syntax error so that any attempt to load it + // will crash. + """) + ]) + ]).create(); + + await pubGet(output: contains("Precompiled foo:hello.")); + + await d.dir(p.join(appPath, '.pub', 'bin'), [ + d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) + ]).validate(); + + var process = await pubRun(args: ['foo:hello']); + expect(process.stdout, emits("hello!")); + await process.shouldExit(); + }); + + group("doesn't create a snapshot", () { + test("when no dependencies of a package have changed", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", deps: { + "bar": "any" + }, contents: [ + d.dir( + "bin", [d.file("hello.dart", "void main() => print('hello!');")]) + ]); + builder.serve("bar", "1.2.3"); + }); + + await d.appDir({"foo": "1.2.3"}).create(); + + await pubGet(output: contains("Precompiled foo:hello.")); + + await pubUpgrade(output: isNot(contains("Precompiled foo:hello."))); + + await d.dir(p.join(appPath, '.pub', 'bin'), [ + d.file('sdk-version', '0.1.2+3\n'), + d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) + ]).validate(); + }); + + test("for a package that depends on the entrypoint", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", deps: { + 'bar': '1.2.3' + }, contents: [ + d.dir( + "bin", [d.file("hello.dart", "void main() => print('hello!');")]) + ]); + builder.serve("bar", "1.2.3", deps: {'myapp': 'any'}); + }); + + await d.appDir({"foo": "1.2.3"}).create(); + + await pubGet(); + + // No local cache should be created, since all dependencies transitively + // depend on the entrypoint. + await d.nothing(p.join(appPath, '.pub', 'bin')).validate(); + }); + + test("for a path dependency", () async { + await d.dir("foo", [ + d.libPubspec("foo", "1.2.3"), + d.dir("bin", [ + d.dir( + "bin", [d.file("hello.dart", "void main() => print('hello!');")]) + ]) + ]).create(); + + await d.appDir({ + "foo": {"path": "../foo"} + }).create(); + + await pubGet(); + + await d.nothing(p.join(appPath, '.pub', 'bin')).validate(); + }); + + test("for a transitive dependency", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", deps: {'bar': '1.2.3'}); + builder.serve("bar", "1.2.3", contents: [ + d.dir( + "bin", [d.file("hello.dart", "void main() => print('hello!');")]) + ]); + }); + + await d.appDir({"foo": "1.2.3"}).create(); + + await pubGet(); + + await d.nothing(p.join(appPath, '.pub', 'bin', 'bar')).validate(); + }); + }); + + group("with --no-precompile,", () { + test("doesn't create a new snapshot", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", contents: [ + d.dir("bin", [ + d.file("hello.dart", "void main() => print('hello!');"), + d.file("goodbye.dart", "void main() => print('goodbye!');"), + d.file("shell.sh", "echo shell"), + d.dir( + "subdir", [d.file("sub.dart", "void main() => print('sub!');")]) + ]) + ]); + }); + + await d.appDir({"foo": "1.2.3"}).create(); + + await pubGet( + args: ["--no-precompile"], output: isNot(contains("Precompiled"))); + + await d.nothing(p.join(appPath, '.pub')).validate(); + + var process = await pubRun(args: ['foo:hello']); + expect(process.stdout, emits("hello!")); + await process.shouldExit(); + + process = await pubRun(args: ['foo:goodbye']); + expect(process.stdout, emits("goodbye!")); + await process.shouldExit(); + }); + + test("deletes a snapshot when its package is upgraded", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", contents: [ + d.dir( + "bin", [d.file("hello.dart", "void main() => print('hello!');")]) + ]); + }); + + await d.appDir({"foo": "any"}).create(); + + await pubGet(output: contains("Precompiled foo:hello.")); + + await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + [d.file('hello.dart.snapshot', contains('hello!'))]).validate(); + + await globalPackageServer.add((builder) { + builder.serve("foo", "1.2.4", contents: [ + d.dir("bin", + [d.file("hello.dart", "void main() => print('hello 2!');")]) + ]); + }); + + await pubUpgrade( + args: ["--no-precompile"], output: isNot(contains("Precompiled"))); + + await d.nothing(p.join(appPath, '.pub', 'bin', 'foo')).validate(); + + var process = await pubRun(args: ['foo:hello']); + expect(process.stdout, emits("hello 2!")); + await process.shouldExit(); + }); + + test( + "doesn't delete a snapshot when no dependencies of a package " + "have changed", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", deps: { + "bar": "any" + }, contents: [ + d.dir( + "bin", [d.file("hello.dart", "void main() => print('hello!');")]) + ]); + builder.serve("bar", "1.2.3"); + }); + + await d.appDir({"foo": "1.2.3"}).create(); + + await pubGet(output: contains("Precompiled foo:hello.")); + + await pubUpgrade( + args: ["--no-precompile"], output: isNot(contains("Precompiled"))); + + await d.dir(p.join(appPath, '.pub', 'bin'), [ + d.file('sdk-version', '0.1.2+3\n'), + d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) + ]).validate(); + }); + }); + + test("prints errors for broken snapshot compilation", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", contents: [ + d.dir("bin", [ + d.file("hello.dart", "void main() { no closing brace"), + d.file("goodbye.dart", "void main() { no closing brace"), + ]) + ]); + builder.serve("bar", "1.2.3", contents: [ + d.dir("bin", [ + d.file("hello.dart", "void main() { no closing brace"), + d.file("goodbye.dart", "void main() { no closing brace"), + ]) + ]); + }); + + await d.appDir({"foo": "1.2.3", "bar": "1.2.3"}).create(); + + // This should still have a 0 exit code, since installation succeeded even + // if precompilation didn't. + await pubGet( + error: allOf([ + contains("Failed to precompile foo:hello"), + contains("Failed to precompile foo:goodbye"), + contains("Failed to precompile bar:hello"), + contains("Failed to precompile bar:goodbye") + ]), + exitCode: 0); + + await d.dir(p.join(appPath, '.pub', 'bin'), [ + d.file('sdk-version', '0.1.2+3\n'), + d.dir('foo', [ + d.nothing('hello.dart.snapshot'), + d.nothing('goodbye.dart.snapshot') + ]), + d.dir('bar', [ + d.nothing('hello.dart.snapshot'), + d.nothing('goodbye.dart.snapshot') + ]) + ]).validate(); + }); +} From 68a6c12602d564316bc9aa0f115ad625d825effe Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 1 Feb 2018 16:09:02 -0800 Subject: [PATCH 2/2] Use .dart_tool/pub as the cache directory Pub will continue to read cached files from .pub if it exists. Any time it modifies the cache, it will migrate .pub to .dart_tool/pub. Closes #1795 --- .gitignore | 2 +- lib/src/barback/asset_environment.dart | 3 +- lib/src/barback/transformer_cache.dart | 6 +- lib/src/entrypoint.dart | 33 ++++- lib/src/executable.dart | 4 +- lib/src/io.dart | 4 +- lib/src/package.dart | 2 +- .../cache_transformed_dependency_test.dart | 117 +++++++++++++++--- test/snapshot_test.dart | 112 +++++++++++++---- test/transformer/cache_test.dart | 43 +++++-- 10 files changed, 270 insertions(+), 56 deletions(-) diff --git a/.gitignore b/.gitignore index 35f7bb930..89fbed2b8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ .buildlog .DS_Store .idea -.pub/ +.dart_tool/ .settings/ /build/ packages diff --git a/lib/src/barback/asset_environment.dart b/lib/src/barback/asset_environment.dart index 0953df245..c64ddd3a8 100644 --- a/lib/src/barback/asset_environment.dart +++ b/lib/src/barback/asset_environment.dart @@ -127,7 +127,8 @@ class AssetEnvironment { new Map.fromIterable(packages, value: (packageName) { var package = graph.packages[packageName]; if (mode != BarbackMode.DEBUG) return package; - var cache = path.join('.pub/deps/debug', packageName); + var cache = + path.join(graph.entrypoint.cachePath, 'deps/debug', packageName); if (!dirExists(cache)) return package; return new CachedPackage(package, cache); })); diff --git a/lib/src/barback/transformer_cache.dart b/lib/src/barback/transformer_cache.dart index 17f6d05ba..30cdf6d96 100644 --- a/lib/src/barback/transformer_cache.dart +++ b/lib/src/barback/transformer_cache.dart @@ -45,9 +45,9 @@ class TransformerCache { /// Loads the transformer cache for [environment]. /// /// This may modify the cache. - TransformerCache.load(PackageGraph graph) - : _graph = graph, - _dir = graph.entrypoint.root.path(".pub/transformers") { + TransformerCache.load(PackageGraph graph) : _graph = graph { + graph.entrypoint.migrateCache(); + _dir = p.join(graph.entrypoint.cachePath, "transformers"); _oldTransformers = _parseManifest(); } diff --git a/lib/src/entrypoint.dart b/lib/src/entrypoint.dart index 55885082a..86717b63d 100644 --- a/lib/src/entrypoint.dart +++ b/lib/src/entrypoint.dart @@ -133,15 +133,26 @@ class Entrypoint { /// The path to the entrypoint package's lockfile. String get lockFilePath => root.path('pubspec.lock'); + /// The path to the entrypoint package's `.dart_tool/pub` cache directory. + /// + /// If the old-style `.pub` directory is being used, this returns that + /// instead. + String get cachePath { + var newPath = root.path('.dart_tool/pub'); + var oldPath = root.path('.pub'); + if (!dirExists(newPath) && dirExists(oldPath)) return oldPath; + return newPath; + } + /// The path to the directory containing precompiled dependencies. /// /// We just precompile the debug version of a package. We're mostly interested /// in improving speed for development iteration loops, which usually use /// debug mode. - String get _precompiledDepsPath => root.path('.pub', 'deps', 'debug'); + String get _precompiledDepsPath => p.join(cachePath, 'deps', 'debug'); /// The path to the directory containing dependency executable snapshots. - String get _snapshotPath => root.path('.pub', 'bin'); + String get _snapshotPath => p.join(cachePath, 'bin'); /// Loads the entrypoint from a package at [rootDir]. Entrypoint(String rootDir, SystemCache cache, {this.isGlobal: false}) @@ -370,6 +381,7 @@ class Entrypoint { /// Precompiles all executables from dependencies that don't transitively /// depend on [this] or on a path dependency. Future precompileExecutables({Iterable changed}) async { + migrateCache(); _deleteExecutableSnapshots(changed: changed); var executables = new Map>.fromIterable( @@ -785,4 +797,21 @@ class Entrypoint { if (entryExists(symlink)) deleteEntry(symlink); if (packagesDir) createSymlink(packagesPath, symlink, relative: true); } + + /// If the entrypoint uses the old-style `.pub` cache directory, migrates it + /// to the new-style `.dart_tool/pub` directory. + void migrateCache() { + var oldPath = root.path('.pub'); + if (!dirExists(oldPath)) return; + + var newPath = root.path('.dart_tool/pub'); + + // If both the old and new directories exist, something weird is going on. + // Do nothing to avoid making things worse. Pub will prefer the new + // directory anyway. + if (dirExists(newPath)) return; + + ensureDir(p.dirname(newPath)); + renameDir(oldPath, newPath); + } } diff --git a/lib/src/executable.dart b/lib/src/executable.dart index a51543992..66ec40ec6 100644 --- a/lib/src/executable.dart +++ b/lib/src/executable.dart @@ -50,6 +50,8 @@ Future runExecutable(Entrypoint entrypoint, String package, } } + entrypoint.migrateCache(); + // Unless the user overrides the verbosity, we want to filter out the // normal pub output shown while loading the environment. if (log.verbosity == log.Verbosity.NORMAL) { @@ -60,7 +62,7 @@ Future runExecutable(Entrypoint entrypoint, String package, if (p.extension(executable) != ".dart") executable += ".dart"; var localSnapshotPath = - p.join(".pub", "bin", package, "$executable.snapshot"); + p.join(entrypoint.cachePath, "bin", package, "$executable.snapshot"); if (!isGlobal && fileExists(localSnapshotPath) && // Dependencies are only snapshotted in release mode, since that's the diff --git a/lib/src/io.dart b/lib/src/io.dart index 2dc61ad32..c633547d6 100644 --- a/lib/src/io.dart +++ b/lib/src/io.dart @@ -526,8 +526,6 @@ final bool runningFromSdk = final _dartRepoRegExp = new RegExp(r"/third_party/pkg/pub/(" r"bin/pub\.dart" r"|" - r"\.pub/pub\.test\.snapshot" - r"|" r"test/.*_test\.dart" r")$"); @@ -584,7 +582,7 @@ final String pubRoot = (() { return path.joinAll(components.take(testIndex)); } - // Pub is either run from ".pub/pub.test.snapshot" or "bin/pub.dart". + // Pub is run from "bin/pub.dart". return path.dirname(path.dirname(script)); })(); diff --git a/lib/src/package.dart b/lib/src/package.dart index d18ff1c37..e059f90db 100644 --- a/lib/src/package.dart +++ b/lib/src/package.dart @@ -152,7 +152,7 @@ class Package { /// This is similar to `p.join(dir, part1, ...)`, except that subclasses may /// override it to report that certain paths exist elsewhere than within /// [dir]. For example, a [CachedPackage]'s `lib` directory is in the - /// `.pub/deps` directory. + /// `.dart_tool/pub/deps` directory. String path(String part1, [String part2, String part3, diff --git a/test/get/cache_transformed_dependency_test.dart b/test/get/cache_transformed_dependency_test.dart index 7f7f84b64..de42d8901 100644 --- a/test/get/cache_transformed_dependency_test.dart +++ b/test/get/cache_transformed_dependency_test.dart @@ -5,6 +5,8 @@ import 'package:path/path.dart' as p; import 'package:test/test.dart'; +import 'package:pub/src/io.dart'; + import '../descriptor.dart' as d; import '../serve/utils.dart'; import '../test_pub.dart'; @@ -115,7 +117,7 @@ main() { await pubGet(output: contains("Precompiled foo.")); await d.dir(appPath, [ - d.dir(".pub/deps/debug/foo/lib", + d.dir(".dart_tool/pub/deps/debug/foo/lib", [d.file("foo.dart", "final message = 'Goodbye!';")]) ]).validate(); }); @@ -146,7 +148,7 @@ main() { await pubGet(output: contains("Precompiled foo.")); await d.dir(appPath, [ - d.dir(".pub/deps/debug/foo/lib", + d.dir(".dart_tool/pub/deps/debug/foo/lib", [d.file("foo.dart", "final message = 'Goodbye!';")]) ]).validate(); }); @@ -164,7 +166,7 @@ main() { await pubGet(output: isNot(contains("Precompiled foo."))); - await d.dir(appPath, [d.nothing(".pub/deps")]).validate(); + await d.dir(appPath, [d.nothing(".dart_tool/pub/deps")]).validate(); }); test("recaches when the dependency is updated", () async { @@ -199,7 +201,7 @@ main() { await pubGet(output: contains("Precompiled foo.")); await d.dir(appPath, [ - d.dir(".pub/deps/debug/foo/lib", + d.dir(".dart_tool/pub/deps/debug/foo/lib", [d.file("foo.dart", "final message = 'Goodbye!';")]) ]).validate(); @@ -209,7 +211,7 @@ main() { await pubGet(output: contains("Precompiled foo.")); await d.dir(appPath, [ - d.dir(".pub/deps/debug/foo/lib", + d.dir(".dart_tool/pub/deps/debug/foo/lib", [d.file("foo.dart", "final message = 'See ya!';")]) ]).validate(); }); @@ -286,7 +288,7 @@ main() { await pubGet(output: contains("Precompiled foo.")); await d.dir(appPath, [ - d.dir(".pub/deps/debug/foo/lib", + d.dir(".dart_tool/pub/deps/debug/foo/lib", [d.file("foo.dart", "final mode = 'debug';")]) ]).validate(); }); @@ -320,7 +322,7 @@ main() { await pubGet(output: contains("Precompiled foo.")); await d.dir(appPath, [ - d.dir(".pub/deps/debug/foo/lib", + d.dir(".dart_tool/pub/deps/debug/foo/lib", [d.file("foo.dart", "final message = 'Modified!';")]) ]).create(); @@ -357,6 +359,51 @@ main() { await pubGet(output: contains("Precompiled foo.")); + // Manually reset the cache to its original state to prove that the + // transformer won't be run again on it. + await d.dir(appPath, [ + d.dir(".dart_tool/pub/deps/debug/foo/lib", + [d.file("foo.dart", "final message = 'Hello!';")]) + ]).create(); + + var pub = await pubRun(args: ["bin/script"]); + expect(pub.stdout, emits("Hello!")); + await pub.shouldExit(); + }); + + test("reads cached packages from the old-style cache", () async { + await servePackages((builder) { + builder.serveRealPackage('barback'); + + builder.serve("foo", "1.2.3", deps: { + 'barback': 'any' + }, pubspec: { + 'transformers': ['foo'] + }, contents: [ + d.dir("lib", [ + d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")), + d.file("foo.dart", "final message = 'Hello!';") + ]) + ]); + }); + + await d.dir(appPath, [ + d.appPubspec({"foo": "1.2.3"}), + d.dir('bin', [ + d.file('script.dart', """ + import 'package:foo/foo.dart'; + + void main() => print(message);""") + ]) + ]).create(); + + await pubGet(output: contains("Precompiled foo.")); + + // Move the directory to the old location to simulate it being created by an + // older version of pub. + renameDir(p.join(d.sandbox, appPath, '.dart_tool', 'pub'), + p.join(d.sandbox, appPath, '.pub')); + // Manually reset the cache to its original state to prove that the // transformer won't be run again on it. await d.dir(appPath, [ @@ -369,6 +416,42 @@ main() { await pub.shouldExit(); }); + test("migrates the old-style cache", () async { + await servePackages((builder) { + builder.serveRealPackage('barback'); + + builder.serve("foo", "1.2.3", deps: { + 'barback': 'any' + }, pubspec: { + 'transformers': ['foo'] + }, contents: [ + d.dir("lib", [ + d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")), + d.file("foo.dart", "final message = 'Hello!';") + ]) + ]); + }); + + await d.dir(appPath, [ + d.appPubspec({"foo": "1.2.3"}), + + // Simulate an old-style cache directory. + d.dir(".pub", [d.file("junk", "junk")]) + ]).create(); + + await pubGet(output: contains("Precompiled foo.")); + + await d.dir(appPath, [d.nothing(".pub")]).validate(); + + await d.dir(appPath, [ + d.dir(".dart_tool/pub", [ + d.file("junk", "junk"), + d.dir("deps/debug/foo/lib", + [d.file("foo.dart", "final message = 'Goodbye!';")]) + ]) + ]).validate(); + }); + // Regression test for issue 21087. test("hasInput works for static packages", () async { await servePackages((builder) { @@ -436,7 +519,7 @@ main() { await pubGet(output: contains("Precompiled foo.")); await d.dir(appPath, [ - d.dir(".pub/deps/debug/foo/lib", + d.dir(".dart_tool/pub/deps/debug/foo/lib", [d.file("foo.dart", "final message = 'Goodbye!';")]) ]).validate(); @@ -445,7 +528,8 @@ main() { await pubGet(output: isNot(contains("Precompiled foo."))); - await d.dir(appPath, [d.nothing(".pub/deps/debug/foo")]).validate(); + await d + .dir(appPath, [d.nothing(".dart_tool/pub/deps/debug/foo")]).validate(); }); // Regression test for https://github.com/dart-lang/pub/issues/1586. @@ -472,7 +556,8 @@ main() { await pubGet(output: contains("Precompiled foo")); await d.dir(appPath, [ - d.file(".pub/deps/debug/foo/lib/inputs.txt", contains('hello.dart.copy')) + d.file(".dart_tool/pub/deps/debug/foo/lib/inputs.txt", + contains('hello.dart.copy')) ]).validate(); await pubServe(); @@ -508,7 +593,7 @@ foo|lib/list_transformer.dart.copy"""); await pubGet( args: ["--no-precompile"], output: isNot(contains("Precompiled"))); - await d.nothing(p.join(appPath, ".pub")).validate(); + await d.nothing(p.join(appPath, ".dart_tool/pub")).validate(); }); test("deletes the cache when the dependency is updated", () async { @@ -543,7 +628,7 @@ foo|lib/list_transformer.dart.copy"""); await pubGet(output: contains("Precompiled foo.")); await d.dir(appPath, [ - d.dir(".pub/deps/debug/foo/lib", + d.dir(".dart_tool/pub/deps/debug/foo/lib", [d.file("foo.dart", "final message = 'Goodbye!';")]) ]).validate(); @@ -553,7 +638,9 @@ foo|lib/list_transformer.dart.copy"""); await pubGet( args: ["--no-precompile"], output: isNot(contains("Precompiled"))); - await d.nothing(p.join(appPath, ".pub/deps/debug/foo")).validate(); + await d + .nothing(p.join(appPath, ".dart_tool/pub/deps/debug/foo")) + .validate(); }); test( @@ -580,7 +667,7 @@ foo|lib/list_transformer.dart.copy"""); await pubGet(output: contains("Precompiled foo.")); await d.dir(appPath, [ - d.dir(".pub/deps/debug/foo/lib", + d.dir(".dart_tool/pub/deps/debug/foo/lib", [d.file("foo.dart", "final message = 'Goodbye!';")]) ]).validate(); @@ -589,7 +676,7 @@ foo|lib/list_transformer.dart.copy"""); args: ["--no-precompile"], output: isNot(contains("Precompiled"))); await d.dir(appPath, [ - d.dir(".pub/deps/debug/foo/lib", + d.dir(".dart_tool/pub/deps/debug/foo/lib", [d.file("foo.dart", "final message = 'Goodbye!';")]) ]).validate(); }); diff --git a/test/snapshot_test.dart b/test/snapshot_test.dart index 5093aa3b6..4045de405 100644 --- a/test/snapshot_test.dart +++ b/test/snapshot_test.dart @@ -5,6 +5,8 @@ import 'package:path/path.dart' as p; import 'package:test/test.dart'; +import 'package:pub/src/io.dart'; + import 'descriptor.dart' as d; import 'test_pub.dart'; @@ -31,7 +33,7 @@ main() { contains("Precompiled foo:goodbye.") ])); - await d.dir(p.join(appPath, '.pub', 'bin'), [ + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin'), [ d.file('sdk-version', '0.1.2+3\n'), d.dir('foo', [ d.file('hello.dart.snapshot', contains('hello!')), @@ -72,7 +74,7 @@ main() { contains("Precompiled foo:goodbye.") ])); - await d.dir(p.join(appPath, '.pub', 'bin'), [ + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin'), [ d.file('sdk-version', '0.1.2+3\n'), d.dir('foo', [ d.file('hello.dart.snapshot', contains('hello!')), @@ -134,7 +136,7 @@ main() { await pubGet(output: contains("Precompiled foo:hello.")); - await d.dir(p.join(appPath, '.pub', 'bin'), [ + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin'), [ d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) ]).validate(); @@ -156,7 +158,7 @@ main() { await pubGet(output: contains("Precompiled foo:hello.")); - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [d.file('hello.dart.snapshot', contains('hello!'))]).validate(); await globalPackageServer.add((builder) { @@ -168,7 +170,7 @@ main() { await pubUpgrade(output: contains("Precompiled foo:hello.")); - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [d.file('hello.dart.snapshot', contains('hello 2!'))]).validate(); var process = await pubRun(args: ['foo:hello']); @@ -198,7 +200,7 @@ main() { await pubGet(output: contains("Precompiled foo:hello.")); - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [d.file('hello.dart.snapshot', contains('hello!'))]).validate(); await globalPackageServer.add((builder) { @@ -209,7 +211,7 @@ main() { await pubUpgrade(output: contains("Precompiled foo:hello.")); - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [d.file('hello.dart.snapshot', contains('hello 2!'))]).validate(); var process = await pubRun(args: ['foo:hello']); @@ -232,7 +234,7 @@ main() { await pubGet(output: contains("Precompiled foo:hello.")); - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [d.file('hello.dart.snapshot', contains('Hello!'))]).validate(); await d.git('foo.git', [ @@ -242,7 +244,7 @@ main() { await pubUpgrade(output: contains("Precompiled foo:hello.")); - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [d.file('hello.dart.snapshot', contains('Goodbye!'))]).validate(); var process = await pubRun(args: ['foo:hello']); @@ -262,7 +264,7 @@ main() { await pubGet(output: contains("Precompiled foo:hello.")); - await d.dir(p.join(appPath, '.pub', 'bin'), [ + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin'), [ d.dir('foo', [d.outOfDateSnapshot('hello.dart.snapshot')]) ]).create(); @@ -274,7 +276,7 @@ main() { expect(process.stdout, emitsThrough("hello!")); await process.shouldExit(); - await d.dir(p.join(appPath, '.pub', 'bin'), [ + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin'), [ d.file('sdk-version', '0.1.2+3\n'), d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) ]).validate(); @@ -315,7 +317,7 @@ main() { await pubGet(output: contains("Precompiled foo:hello.")); - await d.dir(p.join(appPath, '.pub', 'bin'), [ + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin'), [ d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) ]).validate(); @@ -342,7 +344,7 @@ main() { await pubUpgrade(output: isNot(contains("Precompiled foo:hello."))); - await d.dir(p.join(appPath, '.pub', 'bin'), [ + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin'), [ d.file('sdk-version', '0.1.2+3\n'), d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) ]).validate(); @@ -365,7 +367,7 @@ main() { // No local cache should be created, since all dependencies transitively // depend on the entrypoint. - await d.nothing(p.join(appPath, '.pub', 'bin')).validate(); + await d.nothing(p.join(appPath, '.dart_tool', 'pub', 'bin')).validate(); }); test("for a path dependency", () async { @@ -383,7 +385,7 @@ main() { await pubGet(); - await d.nothing(p.join(appPath, '.pub', 'bin')).validate(); + await d.nothing(p.join(appPath, '.dart_tool', 'pub', 'bin')).validate(); }); test("for a transitive dependency", () async { @@ -399,7 +401,9 @@ main() { await pubGet(); - await d.nothing(p.join(appPath, '.pub', 'bin', 'bar')).validate(); + await d + .nothing(p.join(appPath, '.dart_tool', 'pub', 'bin', 'bar')) + .validate(); }); }); @@ -422,7 +426,7 @@ main() { await pubGet( args: ["--no-precompile"], output: isNot(contains("Precompiled"))); - await d.nothing(p.join(appPath, '.pub')).validate(); + await d.nothing(p.join(appPath, '.dart_tool', 'pub')).validate(); var process = await pubRun(args: ['foo:hello']); expect(process.stdout, emits("hello!")); @@ -445,7 +449,7 @@ main() { await pubGet(output: contains("Precompiled foo:hello.")); - await d.dir(p.join(appPath, '.pub', 'bin', 'foo'), + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo'), [d.file('hello.dart.snapshot', contains('hello!'))]).validate(); await globalPackageServer.add((builder) { @@ -458,7 +462,9 @@ main() { await pubUpgrade( args: ["--no-precompile"], output: isNot(contains("Precompiled"))); - await d.nothing(p.join(appPath, '.pub', 'bin', 'foo')).validate(); + await d + .nothing(p.join(appPath, '.dart_tool', 'pub', 'bin', 'foo')) + .validate(); var process = await pubRun(args: ['foo:hello']); expect(process.stdout, emits("hello 2!")); @@ -485,7 +491,7 @@ main() { await pubUpgrade( args: ["--no-precompile"], output: isNot(contains("Precompiled"))); - await d.dir(p.join(appPath, '.pub', 'bin'), [ + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin'), [ d.file('sdk-version', '0.1.2+3\n'), d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) ]).validate(); @@ -521,7 +527,7 @@ main() { ]), exitCode: 0); - await d.dir(p.join(appPath, '.pub', 'bin'), [ + await d.dir(p.join(appPath, '.dart_tool', 'pub', 'bin'), [ d.file('sdk-version', '0.1.2+3\n'), d.dir('foo', [ d.nothing('hello.dart.snapshot'), @@ -533,4 +539,68 @@ main() { ]) ]).validate(); }); + + group("migrates the old-style cache", () { + test("when installing packages", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", contents: [ + d.dir( + "bin", [d.file("hello.dart", "void main() => print('hello!');")]) + ]); + }); + + await d.dir(appPath, [ + d.appPubspec({"foo": "1.2.3"}), + + // Simulate an old-style cache directory. + d.dir(".pub", [d.file("junk", "junk")]) + ]).create(); + + await pubGet(output: contains("Precompiled foo:hello.")); + + await d.dir(appPath, [d.nothing(".pub")]).validate(); + + await d.dir(p.join(appPath, '.dart_tool', 'pub'), [ + d.file('junk', 'junk'), + d.dir('bin', [ + d.file('sdk-version', '0.1.2+3\n'), + d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) + ]) + ]).validate(); + }); + + test("when running executables", () async { + await servePackages((builder) { + builder.serve("foo", "1.2.3", contents: [ + d.dir( + "bin", [d.file("hello.dart", "void main() => print('hello!');")]) + ]); + }); + + await d.appDir({"foo": "1.2.3"}).create(); + + await pubGet(output: contains("Precompiled foo:hello.")); + + // Move the directory to the old location to simulate it being created by an + // older version of pub. + renameDir(p.join(d.sandbox, appPath, '.dart_tool', 'pub'), + p.join(d.sandbox, appPath, '.pub')); + + await d.dir(appPath, [ + d.dir(".pub", [d.file("junk", "junk")]) + ]).create(); + + var process = await pubRun(args: ['foo:hello']); + expect(process.stdout, emits("hello!")); + await process.shouldExit(); + + await d.dir(p.join(appPath, '.dart_tool', 'pub'), [ + d.file('junk', 'junk'), + d.dir('bin', [ + d.file('sdk-version', '0.1.2+3\n'), + d.dir('foo', [d.file('hello.dart.snapshot', contains('hello!'))]) + ]) + ]).validate(); + }); + }); } diff --git a/test/transformer/cache_test.dart b/test/transformer/cache_test.dart index 5b06a3fdc..ec8d49372 100644 --- a/test/transformer/cache_test.dart +++ b/test/transformer/cache_test.dart @@ -70,7 +70,7 @@ main() { await process.shouldExit(); await d.dir(appPath, [ - d.dir(".pub/transformers", [ + d.dir(".dart_tool/pub/transformers", [ d.file("manifest.txt", "0.1.2+3\nfoo"), d.file("transformers.snapshot", isNot(isEmpty)) ]) @@ -85,7 +85,7 @@ main() { test("recaches if the SDK version is out-of-date", () async { await d.dir(appPath, [ - d.dir(".pub/transformers", [ + d.dir(".dart_tool/pub/transformers", [ // The version 0.0.1 is different than the test version 0.1.2+3. d.file("manifest.txt", "0.0.1\nfoo"), d.file("transformers.snapshot", "junk") @@ -97,7 +97,7 @@ main() { await process.shouldExit(); await d.dir(appPath, [ - d.dir(".pub/transformers", [ + d.dir(".dart_tool/pub/transformers", [ d.file("manifest.txt", "0.1.2+3\nfoo"), d.file("transformers.snapshot", isNot(isEmpty)) ]) @@ -110,7 +110,7 @@ main() { await process.shouldExit(); await d.dir(appPath, [ - d.dir(".pub/transformers", [ + d.dir(".dart_tool/pub/transformers", [ d.file("manifest.txt", "0.1.2+3\nfoo"), d.file("transformers.snapshot", isNot(isEmpty)) ]) @@ -131,7 +131,7 @@ main() { await process.shouldExit(); await d.dir(appPath, [ - d.dir(".pub/transformers", [ + d.dir(".dart_tool/pub/transformers", [ d.file("manifest.txt", "0.1.2+3\nbar,foo"), d.file("transformers.snapshot", isNot(isEmpty)) ]) @@ -144,7 +144,7 @@ main() { await process.shouldExit(); await d.dir(appPath, [ - d.dir(".pub/transformers", [ + d.dir(".dart_tool/pub/transformers", [ d.file("manifest.txt", "0.1.2+3\nfoo"), d.file("transformers.snapshot", isNot(isEmpty)) ]) @@ -174,7 +174,7 @@ main() { await process.shouldExit(); await d.dir(appPath, [ - d.dir(".pub/transformers", [ + d.dir(".dart_tool/pub/transformers", [ d.file("manifest.txt", "0.1.2+3\nfoo"), d.file("transformers.snapshot", isNot(isEmpty)) ]) @@ -234,6 +234,33 @@ main() { await process.shouldExit(); }); + test("migrates an old-style cache", () async { + // Simulate an old-style cache directory. + await d.dir(appPath, [ + d.dir(".pub", [d.file("junk", "junk")]) + ]).create(); + + var process = await pubRun(args: ['myapp']); + expect(process.stdout, emits("Goodbye!")); + await process.shouldExit(); + + await d.dir(appPath, [ + d.dir(".dart_tool/pub", [ + d.file("junk", "junk"), + d.dir("transformers", [ + d.file("manifest.txt", "0.1.2+3\nfoo"), + d.file("transformers.snapshot", isNot(isEmpty)) + ]) + ]) + ]).validate(); + + // Run the executable again to make sure loading the transformer from the + // cache works. + process = await pubRun(args: ['myapp']); + expect(process.stdout, emits("Goodbye!")); + await process.shouldExit(); + }); + // Issue 21298. test("doesn't recache when a transformer is removed", () async { await d.dir(appPath, [ @@ -271,7 +298,7 @@ main() { // "bar" should still be in the manifest, since there's no reason to // recompile the cache. await d.dir(appPath, [ - d.dir(".pub/transformers", [ + d.dir(".dart_tool/pub/transformers", [ d.file("manifest.txt", "0.1.2+3\nbar,foo"), d.file("transformers.snapshot", isNot(isEmpty)) ])