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

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

Issue 10874051: Support self-referential package: imports with Pub. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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/git_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('entrypoint'); 5 #library('entrypoint');
6 6
7 #import('io.dart'); 7 #import('io.dart');
8 #import('lock_file.dart'); 8 #import('lock_file.dart');
9 #import('package.dart'); 9 #import('package.dart');
10 #import('root_source.dart'); 10 #import('root_source.dart');
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 99
100 return future; 100 return future;
101 } 101 }
102 102
103 /** 103 /**
104 * Installs all dependencies of the [root] package to its "packages" 104 * Installs all dependencies of the [root] package to its "packages"
105 * directory, respecting the [LockFile] if present. Returns a [Future] that 105 * directory, respecting the [LockFile] if present. Returns a [Future] that
106 * completes when all dependencies are installed. 106 * completes when all dependencies are installed.
107 */ 107 */
108 Future installDependencies() { 108 Future installDependencies() {
109 return _loadLockFile() 109 return _validatePubspec()
110 .chain((_) => _loadLockFile())
110 .chain((lockFile) => resolveVersions(cache.sources, root, lockFile)) 111 .chain((lockFile) => resolveVersions(cache.sources, root, lockFile))
111 .chain(_installDependencies); 112 .chain(_installDependencies);
112 } 113 }
113 114
114 /** 115 /**
115 * Installs the latest available versions of all dependencies of the [root] 116 * Installs the latest available versions of all dependencies of the [root]
116 * package to its "package" directory, writing a new [LockFile]. Returns a 117 * package to its "package" directory, writing a new [LockFile]. Returns a
117 * [Future] that completes when all dependencies are installed. 118 * [Future] that completes when all dependencies are installed.
118 */ 119 */
119 Future updateAllDependencies() { 120 Future updateAllDependencies() {
120 return resolveVersions(cache.sources, root, new LockFile.empty()). 121 return _validatePubspec()
121 chain(_installDependencies); 122 .chain((_) => resolveVersions(cache.sources, root, new LockFile.empty()))
123 .chain(_installDependencies);
122 } 124 }
123 125
124 /** 126 /**
125 * Installs the latest available versions of [dependencies], while leaving 127 * Installs the latest available versions of [dependencies], while leaving
126 * other dependencies as specified by the [LockFile] if possible. Returns a 128 * other dependencies as specified by the [LockFile] if possible. Returns a
127 * [Future] that completes when all dependencies are installed. 129 * [Future] that completes when all dependencies are installed.
128 */ 130 */
129 Future updateDependencies(List<String> dependencies) { 131 Future updateDependencies(List<String> dependencies) {
130 return _loadLockFile().chain((lockFile) { 132 return _validatePubspec().chain((_) => _loadLockFile()).chain((lockFile) {
131 var versionSolver = new VersionSolver(cache.sources, root, lockFile); 133 var versionSolver = new VersionSolver(cache.sources, root, lockFile);
132 for (var dependency in dependencies) { 134 for (var dependency in dependencies) {
133 versionSolver.useLatestVersion(dependency); 135 versionSolver.useLatestVersion(dependency);
134 } 136 }
135 return versionSolver.solve(); 137 return versionSolver.solve();
136 }).chain(_installDependencies); 138 }).chain(_installDependencies);
137 } 139 }
138 140
139 /** 141 /**
140 * Installs all dependencies listed in [packageVersions] and writes a 142 * Installs all dependencies listed in [packageVersions] and writes a
141 * [LockFile]. 143 * [LockFile].
142 */ 144 */
143 Future _installDependencies(List<PackageId> packageVersions) { 145 Future _installDependencies(List<PackageId> packageVersions) {
144 return Futures.wait(packageVersions.map((id) { 146 return Futures.wait(packageVersions.map((id) {
145 if (id.source is RootSource) return new Future.immediate(id); 147 if (id.source is RootSource) return new Future.immediate(id);
146 return install(id); 148 return install(id);
147 })).chain(_saveLockFile); 149 })).chain(_saveLockFile).chain(_installSelfReference);
148 } 150 }
149 151
150 /** 152 /**
151 * Loads the list of concrete package versions from the `pubspec.lock`, if it 153 * Loads the list of concrete package versions from the `pubspec.lock`, if it
152 * exists. If it doesn't, this completes to an empty [LockFile]. 154 * exists. If it doesn't, this completes to an empty [LockFile].
153 * 155 *
154 * If there's an error reading the `pubspec.lock` file, this will print a 156 * If there's an error reading the `pubspec.lock` file, this will print a
155 * warning message and act as though the file doesn't exist. 157 * warning message and act as though the file doesn't exist.
156 */ 158 */
157 Future<LockFile> _loadLockFile() { 159 Future<LockFile> _loadLockFile() {
158 var completer = new Completer<LockFile>(); 160 var completer = new Completer<LockFile>();
159 var lockFilePath = join(root.dir, 'pubspec.lock'); 161 var lockFilePath = join(root.dir, 'pubspec.lock');
160 var future = readTextFile(lockFilePath); 162 var future = readTextFile(lockFilePath);
161 163
162 future.handleException((_) { 164 future.handleException((_) {
163 completer.complete(new LockFile.empty());
164
165 // If we failed to load the lockfile but it does exist, something's 165 // If we failed to load the lockfile but it does exist, something's
166 // probably wrong and we should notify the user. 166 // probably wrong and we should notify the user.
167 fileExists(lockFilePath).then((exists) { 167 fileExists(lockFilePath).transform((exists) {
168 if (!exists) return; 168 if (!exists) return;
169 printError("Error reading pubspec.lock: ${future.exception}"); 169 printError("Error reading pubspec.lock: ${future.exception}");
170 }).then((_) {
171 completer.complete(new LockFile.empty());
170 }); 172 });
171 173
172 return true; 174 return true;
173 }); 175 });
174 176
175 future.then((text) => 177 future.then((text) =>
176 completer.complete(new LockFile.parse(text, cache.sources))); 178 completer.complete(new LockFile.parse(text, cache.sources)));
177 return completer.future; 179 return completer.future;
178 } 180 }
179 181
180 /** 182 /**
181 * Saves a list of concrete package versions to the `pubspec.lock` file. 183 * Saves a list of concrete package versions to the `pubspec.lock` file.
182 */ 184 */
183 Future _saveLockFile(List<PackageId> packageIds) { 185 Future _saveLockFile(List<PackageId> packageIds) {
184 var lockFile = new LockFile.empty(); 186 var lockFile = new LockFile.empty();
185 for (var id in packageIds) { 187 for (var id in packageIds) {
186 if (id.source is! RootSource) lockFile.packages[id.name] = id; 188 if (id.source is! RootSource) lockFile.packages[id.name] = id;
187 } 189 }
188 190
189 return writeTextFile(join(root.dir, 'pubspec.lock'), lockFile.serialize()); 191 return writeTextFile(join(root.dir, 'pubspec.lock'), lockFile.serialize());
190 } 192 }
193
194 /**
195 * Installs a self-referential symlink in the `packages` directory that will
196 * allow a package to import its own files using `package:`.
197 */
198 Future _installSelfReference(_) {
199 var linkPath = join(path, root.name);
200 return exists(linkPath).chain((exists) {
201 if (exists) return new Future.immediate(null);
202 return ensureDir(path).chain((_) => createSymlink(root.dir, linkPath));
203 });
204 }
205
206 /**
207 * Validate that the pubspec for the entrypoint exists and specifies the name
208 * of the root package.
209 */
210 Future _validatePubspec() {
211 var future = new Future.immediate(null);;
212 if (root.pubspec.isEmpty) {
213 future = exists(join(path, "pubspec.yaml")).transform((exists) {
214 if (exists) return;
215 throw '"pubspec.yaml" not found.';
Bob Nystrom 2012/08/24 00:58:49 We should do friendly error messages here. Somethi
nweiz 2012/08/24 01:12:12 Done.
216 });
217 }
218
219 return future.transform((_) {
220 if (root.pubspec.name != null) return;
221 throw '"pubspec.yaml" must contain a "name" key.';
Bob Nystrom 2012/08/24 00:58:49 Make this a friendly complete sentence, please.
nweiz 2012/08/24 01:12:12 This one is a complete sentence. I'd be happy to r
222 });
223 }
191 } 224 }
OLDNEW
« no previous file with comments | « no previous file | utils/pub/git_source.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698