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 |