| Index: test/test_pub.dart
|
| diff --git a/test/test_pub.dart b/test/test_pub.dart
|
| index b0ec23f6f0fddbe4eef162d867b89052d5dfcdba..fb7164a59f96ee41333d859f8dddcb4e21425069 100644
|
| --- a/test/test_pub.dart
|
| +++ b/test/test_pub.dart
|
| @@ -14,6 +14,7 @@ import 'dart:convert';
|
| import 'dart:io';
|
| import 'dart:math';
|
|
|
| +import 'package:crypto/crypto.dart';
|
| import 'package:http/testing.dart';
|
| import 'package:path/path.dart' as p;
|
| import 'package:pub_semver/pub_semver.dart';
|
| @@ -38,6 +39,7 @@ import '../lib/src/lock_file.dart';
|
| import '../lib/src/log.dart' as log;
|
| import '../lib/src/package.dart';
|
| import '../lib/src/pubspec.dart';
|
| +import '../lib/src/sdk.dart' as sdk;
|
| import '../lib/src/source/hosted.dart';
|
| import '../lib/src/source/path.dart';
|
| import '../lib/src/source_registry.dart';
|
| @@ -519,14 +521,9 @@ ScheduledProcess startPub({List args, Future<String> tokenEndpoint,
|
| dartBin = p.absolute(dartBin);
|
| }
|
|
|
| - // Always run pub from a snapshot. Since we require the SDK to be built, the
|
| - // snapshot should be there. Note that this *does* mean that the snapshot has
|
| - // to be manually updated when changing code before running the tests.
|
| - // Otherwise, you will test against stale data.
|
| - //
|
| - // Using the snapshot makes running the tests much faster, which is why we
|
| - // make this trade-off.
|
| - var pubPath = p.join(p.dirname(dartBin), 'snapshots/pub.dart.snapshot');
|
| + // Always run pub from a snapshot. Using the snapshot makes running the tests
|
| + // much faster, especially when multiple tests are run at once.
|
| + var pubPath = p.absolute(p.join(pubRoot, '.pub/pub.test.snapshot'));
|
| var dartArgs = [pubPath, '--verbose'];
|
| dartArgs.addAll(args);
|
|
|
| @@ -538,11 +535,67 @@ ScheduledProcess startPub({List args, Future<String> tokenEndpoint,
|
| return pubEnvironment;
|
| });
|
|
|
| + _ensureSnapshot();
|
| +
|
| return new PubProcess.start(dartBin, dartArgs, environment: environmentFuture,
|
| workingDirectory: _pathInSandbox(appPath),
|
| description: args.isEmpty ? 'pub' : 'pub ${args.first}');
|
| }
|
|
|
| +/// Ensure that a snapshot of the current pub source exists at
|
| +/// ".pub/pub.snapshot".
|
| +void _ensureSnapshot() {
|
| + ensureDir(p.join(pubRoot, '.pub'));
|
| +
|
| + var version = sdk.version.toString();
|
| + var hash = _hashChanges();
|
| +
|
| + var snapshotPath = p.join(pubRoot, '.pub', 'pub.test.snapshot');
|
| + var hashPath = p.join(pubRoot, '.pub', 'pub.hash');
|
| + var versionPath = p.join(pubRoot, '.pub', 'pub.version');
|
| + if (fileExists(hashPath) && fileExists(versionPath)) {
|
| + var oldHash = readTextFile(hashPath);
|
| + var oldVersion = readTextFile(versionPath);
|
| +
|
| + if (oldHash == hash && oldVersion == version && fileExists(snapshotPath)) {
|
| + return;
|
| + }
|
| + }
|
| +
|
| + var dartSnapshot = runProcessSync(Platform.executable, [
|
| + '--snapshot=$snapshotPath',
|
| + p.join(pubRoot, 'bin', 'pub.dart')
|
| + ]);
|
| + if (dartSnapshot.exitCode != 0) throw "Failed to run dart --snapshot.";
|
| +
|
| + writeTextFile(hashPath, hash);
|
| + writeTextFile(versionPath, version);
|
| +}
|
| +
|
| +/// Returns a hash that encapsulates the current state of the repo.
|
| +String _hashChanges() {
|
| + var hash = new SHA1();
|
| +
|
| + // Include the current Git commit.
|
| + hash.add(UTF8.encode(gitlib.runSync(['rev-parse', 'HEAD']).first));
|
| +
|
| + // Include the changes in lib and bin relative to the current Git commit.
|
| + var tracked = gitlib.runSync(['diff-index', '--patch', 'HEAD', 'lib', 'bin']);
|
| + for (var line in tracked) {
|
| + hash.add(UTF8.encode("$line\n"));
|
| + }
|
| +
|
| + // Include the full contents of non-ignored files in lib and bin that aren't
|
| + // tracked by Git.
|
| + var untracked = gitlib.runSync(
|
| + ['ls-files', '--others', '--exclude-standard', 'lib', 'bin']);
|
| + for (var path in untracked) {
|
| + hash.add(readBinaryFile(path));
|
| + }
|
| +
|
| + return CryptoUtils.bytesToHex(hash.close());
|
| +}
|
| +
|
| /// A subclass of [ScheduledProcess] that parses pub's verbose logging output
|
| /// and makes [stdout] and [stderr] work as though pub weren't running in
|
| /// verbose mode.
|
|
|