Chromium Code Reviews| Index: sdk/lib/_internal/pub/lib/src/source/git.dart |
| diff --git a/sdk/lib/_internal/pub/lib/src/source/git.dart b/sdk/lib/_internal/pub/lib/src/source/git.dart |
| index 3b47cb4ede745a5240adbc17048e1114eebcf24e..4023822a96b03f6c54abc152db0025a6d57dd7f6 100644 |
| --- a/sdk/lib/_internal/pub/lib/src/source/git.dart |
| +++ b/sdk/lib/_internal/pub/lib/src/source/git.dart |
| @@ -10,6 +10,7 @@ import 'package:path/path.dart' as path; |
| import '../git.dart' as git; |
| import '../io.dart'; |
| +import '../log.dart' as log; |
| import '../package.dart'; |
| import '../source.dart'; |
| import '../utils.dart'; |
| @@ -38,7 +39,11 @@ class GitSource extends Source { |
| /// `<package name>-<url hash>`. These are used to check out the repository |
| /// itself; each of the commit-specific directories are clones of a directory |
| /// in `cache/`. |
| - Future<Package> downloadToSystemCache(PackageId id) { |
| + Future<Package> downloadToSystemCache(PackageId id, {bool force}) { |
| + // Force is not supported because the cache repair command doesn't need it. |
| + // Instead, it uses [resetCachedPackages]. |
| + assert(force != true); |
| + |
| var revisionCachePath; |
| return git.isInstalled.then((installed) { |
| @@ -118,6 +123,45 @@ class GitSource extends Source { |
| }); |
| } |
| + /// Resets all cached packages back to the pristine state of the Git |
| + /// repository at the revision they are pinned to. |
| + Future<Pair<int, int>> repairCachedPackages() { |
| + if (!dirExists(systemCacheRoot)) return new Future.value(new Pair(0, 0)); |
| + |
| + var successes = 0; |
| + var failures = 0; |
| + |
| + var packages = listDir(systemCacheRoot) |
| + .where((entry) => dirExists(path.join(entry, ".git"))) |
| + .map((packageDir) => new Package.load(null, packageDir, |
| + systemCache.sources)) |
| + .toList(); |
| + |
| + // Note that there may be multiple packages with the same name and version |
| + // (pinned to different commits). The sort order of those is unspecified. |
| + packages.sort(Package.orderByNameAndVersion); |
| + |
| + return Future.wait(packages.map((package) { |
| + log.message("Resetting Git repository for " |
| + "${log.bold(package.name)} ${package.version}..."); |
| + |
| + // Remove all untracked files. |
| + return git.run(["clean", "-d", "--force", "-x"], |
| + workingDir: package.dir).then((_) { |
| + // Discard all changes to tracked files. |
| + return git.run(["reset", "--hard", "HEAD"], workingDir: package.dir); |
| + }).then((_) { |
| + successes++; |
| + }).catchError((error, stackTrace) { |
| + failures++; |
| + log.error("Failed to reset ${log.bold(package.name)} " |
|
nweiz
2014/04/15 00:59:26
We should probably only have this nice handling fo
Bob Nystrom
2014/04/16 17:07:44
Done.
|
| + "${package.version}. Error:\n$error"); |
| + log.fine(stackTrace); |
| + failures++; |
| + }); |
| + })).then((_) => new Pair(successes, failures)); |
| + } |
| + |
| // TODO(keertip): Implement getCachedPackages(). |
| /// Ensure that the canonical clone of the repository referred to by [id] (the |