Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1133)

Side by Side Diff: utils/pub/git_source.dart

Issue 10695132: Reverting 9527 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | utils/pub/source.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #library('git_source'); 5 #library('git_source');
6 6
7 #import('io.dart'); 7 #import('io.dart');
8 #import('package.dart'); 8 #import('package.dart');
9 #import('source.dart'); 9 #import('source.dart');
10 #import('source_registry.dart');
11 #import('utils.dart'); 10 #import('utils.dart');
12 11
13 /** 12 /**
14 * A package source that installs packages from Git repos. 13 * A package source that installs packages from Git repos.
15 */ 14 */
16 class GitSource extends Source { 15 class GitSource extends Source {
17 final String name = "git"; 16 final String name = "git";
18 17
19 final bool shouldCache = true; 18 // TODO(rnystrom): Git packages could in theory be cached, but that adds a
19 // lot of complexity. When you install a git package, you are installing
20 // and pinning to a specific commit. That means different installs of the
21 // same git path but at different commits need to be disambiguated in the
22 // system cache. It may also lead to a lot of garbage in the system cache.
23 // For now, we are punting and simply not caching them.
24 final bool shouldCache = false;
20 25
21 GitSource(); 26 GitSource();
22 27
23 /** 28 /**
24 * Clones a Git repo to the local filesystem. 29 * Clones a Git repo to the local filesystem.
25 *
26 * The Git cache directory is a little idiosyncratic. At the top level, it
27 * contains a directory for each commit of each repository, named `<package
28 * name>-<commit hash>`. These are the canonical package directories that are
29 * linked to from the `packages/` directory.
30 *
31 * In addition, the Git system cache contains a subdirectory named `cache/`
32 * which contains a directory for each separate repository URL, named
33 * `<package name>-<url hash>`. These are used to check out the repository
34 * itself; each of the commit-specific directories are clones of a directory
35 * in `cache/`.
36 */ 30 */
37 Future<Package> installToSystemCache(PackageId id) { 31 Future<bool> install(PackageId id, String destPath) {
38 var revisionCachePath;
39
40 return isGitInstalled.chain((installed) { 32 return isGitInstalled.chain((installed) {
41 if (!installed) { 33 if (installed) {
34 return runProcess("git",
35 ["clone", "--progress", id.description, destPath],
36 pipeStdout: true, pipeStderr: true).
37 transform((result) => result.success);
38 } else {
42 throw new Exception( 39 throw new Exception(
43 "Cannot install '${id.name}' from Git (${id.description}).\n" 40 "Cannot install '${id.name}' from Git (${id.description}).\n"
44 "Please ensure Git is correctly installed."); 41 "Please ensure Git is correctly installed.");
45 } 42 }
46 43 });
47 return ensureDir(join(systemCacheRoot, 'cache'));
48 }).chain((_) => _ensureRepoCache(id))
49 .chain((_) => _revisionCachePath(id, "HEAD"))
50 .chain((path) {
51 revisionCachePath = path;
52 return exists(revisionCachePath);
53 }).chain((exists) {
54 if (exists) return new Future.immediate(null);
55 return _clone(_repoCachePath(id), revisionCachePath);
56 }).chain((_) => Package.load(revisionCachePath, systemCache.sources));
57 } 44 }
58 45
59 /** 46 /**
60 * The package name of a Git repo is the name of the directory into which 47 * The package name of a Git repo is the name of the directory into which
61 * it'll be cloned. 48 * it'll be cloned.
62 */ 49 */
63 String packageName(description) => 50 String packageName(description) =>
64 basename(description).replaceFirst(const RegExp("\.git\$"), ""); 51 basename(description).replaceFirst(const RegExp("\.git\$"), "");
65 52
66 /** 53 /**
67 * Ensures [description] is a Git URL. 54 * Ensures [description] is a Git URL.
68 */ 55 */
69 void validateDescription(description) { 56 void validateDescription(description) {
70 if (description is! String) { 57 if (description is! String) {
71 throw new FormatException("The description must be a git URL."); 58 throw new FormatException("The description must be a git URL.");
72 } 59 }
73 } 60 }
74
75 /**
76 * Ensure that the canonical clone of the repository referred to by [id] (the
77 * one in `<system cache>/git/cache`) exists and is up-to-date. Returns a
78 * future that completes once this is finished and throws an exception if it
79 * fails.
80 */
81 Future _ensureRepoCache(PackageId id) {
82 var path = _repoCachePath(id);
83 return exists(path).chain((exists) {
84 if (!exists) return _clone(id.description, path);
85
86 return runProcess("git", ["pull", "--force", "--progress"],
87 workingDir: path, pipeStdout: true,
88 pipeStderr: true).transform((result) {
89 if (!result.success) throw 'Git failed.';
90 return null;
91 });
92 });
93 }
94
95 /**
96 * Returns a future that completes to the revision hash of the repository for
97 * [id] at [ref], which can be any Git ref.
98 */
99 Future<String> _revisionAt(PackageId id, String ref) {
100 return runProcess("git", ["rev-parse", ref],
101 workingDir: _repoCachePath(id), pipeStderr: true).transform((result) {
102 if (!result.success) throw 'Git failed.';
103 return result.stdout[0];
104 });
105 }
106
107 /**
108 * Returns the path to the revision-specific cache of [id] at [ref], which can
109 * be any Git ref.
110 */
111 Future<String> _revisionCachePath(PackageId id, String ref) {
112 return _revisionAt(id, ref).transform((rev) {
113 var revisionCacheName = '${id.name}-$rev';
114 return join(systemCacheRoot, revisionCacheName);
115 });
116 }
117
118 /**
119 * Clones the repo at the URI [from] to the path [to] on the local filesystem.
120 */
121 Future _clone(String from, String to) {
122 return runProcess("git", ["clone", "--progress", from, to],
123 pipeStdout: true, pipeStderr: true).transform((result) {
124 if (!result.success) throw 'Git failed.';
125 return null;
126 });
127 }
128
129 /**
130 * Returns the path to the canonical clone of the repository referred to by
131 * [id] (the one in `<system cache>/git/cache`).
132 */
133 String _repoCachePath(PackageId id) {
134 var repoCacheName = '${id.name}-${sha1(id.description)}';
135 return join(systemCacheRoot, 'cache', repoCacheName);
136 }
137 } 61 }
OLDNEW
« no previous file with comments | « no previous file | utils/pub/source.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698