OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 pub.barback; | 5 library pub.barback; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:barback/barback.dart'; | 9 import 'package:barback/barback.dart'; |
10 import 'package:path/path.dart' as path; | 10 import 'package:collection/collection.dart'; |
| 11 import 'package:path/path.dart' as p; |
11 | 12 |
| 13 import 'io.dart'; |
12 import 'utils.dart'; | 14 import 'utils.dart'; |
13 import 'version.dart'; | 15 import 'version.dart'; |
14 | 16 |
15 /// The currently supported versions of the Barback package that this version of | 17 /// The currently supported versions of the Barback package that this version of |
16 /// pub works with. | 18 /// pub works with. |
17 /// | 19 /// |
18 /// Pub implicitly constrains barback to these versions. | 20 /// Pub implicitly constrains barback to these versions. |
19 /// | 21 /// |
20 /// Barback is in a unique position. Pub imports it, so a copy of Barback is | 22 /// Barback is in a unique position. Pub imports it, so a copy of Barback is |
21 /// physically included in the SDK. Packages also depend on Barback (from | 23 /// physically included in the SDK. Packages also depend on Barback (from |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 includes, excludes); | 168 includes, excludes); |
167 } | 169 } |
168 | 170 |
169 TransformerId._(this.package, this.path, this.configuration, | 171 TransformerId._(this.package, this.path, this.configuration, |
170 this.includes, this.excludes) { | 172 this.includes, this.excludes) { |
171 if (!package.startsWith('\$')) return; | 173 if (!package.startsWith('\$')) return; |
172 if (_BUILT_IN_TRANSFORMERS.contains(package)) return; | 174 if (_BUILT_IN_TRANSFORMERS.contains(package)) return; |
173 throw new FormatException('Unsupported built-in transformer $package.'); | 175 throw new FormatException('Unsupported built-in transformer $package.'); |
174 } | 176 } |
175 | 177 |
176 // TODO(nweiz): support deep equality on [configuration] as well. | |
177 bool operator==(other) => other is TransformerId && | 178 bool operator==(other) => other is TransformerId && |
178 other.package == package && | 179 other.package == package && |
179 other.path == path && | 180 other.path == path && |
180 other.configuration == configuration; | 181 const DeepCollectionEquality().equals(other.configuration, configuration); |
181 | 182 |
182 int get hashCode => package.hashCode ^ path.hashCode ^ configuration.hashCode; | 183 int get hashCode => package.hashCode ^ path.hashCode ^ |
| 184 const DeepCollectionEquality().hash(configuration); |
183 | 185 |
184 String toString() => path == null ? package : '$package/$path'; | 186 String toString() => path == null ? package : '$package/$path'; |
185 | 187 |
186 /// Returns the asset id for the library identified by this transformer id. | 188 /// Returns the asset id for the library identified by this transformer id. |
187 /// | 189 /// |
188 /// If `path` is null, this will determine which library to load. | 190 /// If `path` is null, this will determine which library to load. |
189 Future<AssetId> getAssetId(Barback barback) { | 191 Future<AssetId> getAssetId(Barback barback) { |
190 if (path != null) { | 192 if (path != null) { |
191 return new Future.value(new AssetId(package, 'lib/$path.dart')); | 193 return new Future.value(new AssetId(package, 'lib/$path.dart')); |
192 } | 194 } |
193 | 195 |
194 var transformerAsset = new AssetId(package, 'lib/transformer.dart'); | 196 var transformerAsset = new AssetId(package, 'lib/transformer.dart'); |
195 return barback.getAssetById(transformerAsset).then((_) => transformerAsset) | 197 return barback.getAssetById(transformerAsset).then((_) => transformerAsset) |
196 .catchError((e) => new AssetId(package, 'lib/$package.dart'), | 198 .catchError((e) => new AssetId(package, 'lib/$package.dart'), |
197 test: (e) => e is AssetNotFoundException); | 199 test: (e) => e is AssetNotFoundException); |
198 } | 200 } |
199 | 201 |
| 202 /// Returns the path to the library identified by this transformer within |
| 203 /// [packageDir], which should be the directory of [package]. |
| 204 /// |
| 205 /// If `path` is null, this will determine which library to load. Unlike |
| 206 /// [getAssetId], this doesn't take generated assets into account; it's used |
| 207 /// to determine transformers' dependencies, which requires looking at files |
| 208 /// on disk. |
| 209 String getFullPath(String packageDir) { |
| 210 if (path != null) return p.join(packageDir, 'lib', p.fromUri('$path.dart')); |
| 211 |
| 212 var transformerPath = p.join(packageDir, 'lib', 'transformer.dart'); |
| 213 if (fileExists(transformerPath)) return transformerPath; |
| 214 return p.join(packageDir, 'lib', '$package.dart'); |
| 215 } |
| 216 |
200 /// Returns whether the include/exclude rules allow the transformer to run on | 217 /// Returns whether the include/exclude rules allow the transformer to run on |
201 /// [pathWithinPackage]. | 218 /// [pathWithinPackage]. |
202 /// | 219 /// |
203 /// [pathWithinPackage] must be a path relative to the containing package's | 220 /// [pathWithinPackage] must be a URL-style path relative to the containing |
204 /// root directory. | 221 /// package's root directory. |
205 bool canTransform(String pathWithinPackage) { | 222 bool canTransform(String pathWithinPackage) { |
206 // TODO(rnystrom): Support globs in addition to paths. See #17093. | 223 // TODO(rnystrom): Support globs in addition to paths. See #17093. |
207 if (excludes != null) { | 224 if (excludes != null) { |
208 // If there are any excludes, it must not match any of them. | 225 // If there are any excludes, it must not match any of them. |
209 if (excludes.contains(pathWithinPackage)) return false; | 226 if (excludes.contains(pathWithinPackage)) return false; |
210 } | 227 } |
211 | 228 |
212 // If there are any includes, it must match one of them. | 229 // If there are any includes, it must match one of them. |
213 return includes == null || includes.contains(pathWithinPackage); | 230 return includes == null || includes.contains(pathWithinPackage); |
214 } | 231 } |
215 } | 232 } |
216 | 233 |
217 /// Converts [id] to a "package:" URI. | 234 /// Converts [id] to a "package:" URI. |
218 /// | 235 /// |
219 /// This will throw an [ArgumentError] if [id] doesn't represent a library in | 236 /// This will throw an [ArgumentError] if [id] doesn't represent a library in |
220 /// `lib/`. | 237 /// `lib/`. |
221 Uri idToPackageUri(AssetId id) { | 238 Uri idToPackageUri(AssetId id) { |
222 if (!id.path.startsWith('lib/')) { | 239 if (!id.path.startsWith('lib/')) { |
223 throw new ArgumentError("Asset id $id doesn't identify a library."); | 240 throw new ArgumentError("Asset id $id doesn't identify a library."); |
224 } | 241 } |
225 | 242 |
226 return new Uri(scheme: 'package', | 243 return new Uri(scheme: 'package', |
227 path: path.url.join(id.package, id.path.replaceFirst('lib/', ''))); | 244 path: p.url.join(id.package, id.path.replaceFirst('lib/', ''))); |
228 } | 245 } |
229 | 246 |
230 /// Converts [uri] into an [AssetId] if its path is within "packages". | 247 /// Converts [uri] into an [AssetId] if its path is within "packages". |
231 /// | 248 /// |
232 /// If the URL contains a special directory, but lacks a following package name, | 249 /// If the URL contains a special directory, but lacks a following package name, |
233 /// throws a [FormatException]. | 250 /// throws a [FormatException]. |
234 /// | 251 /// |
235 /// If the URI doesn't contain one of those special directories, returns null. | 252 /// If the URI doesn't contain one of those special directories, returns null. |
236 AssetId packagesUrlToId(Uri url) { | 253 AssetId packagesUrlToId(Uri url) { |
237 var parts = path.url.split(url.path); | 254 var parts = p.url.split(url.path); |
238 | 255 |
239 // Strip the leading "/" from the URL. | 256 // Strip the leading "/" from the URL. |
240 if (parts.isNotEmpty && parts.first == "/") parts = parts.skip(1).toList(); | 257 if (parts.isNotEmpty && parts.first == "/") parts = parts.skip(1).toList(); |
241 | 258 |
242 if (parts.isEmpty) return null; | 259 if (parts.isEmpty) return null; |
243 | 260 |
244 // Check for "packages" in the URL. | 261 // Check for "packages" in the URL. |
245 // TODO(rnystrom): If we rewrite "package:" imports to relative imports that | 262 // TODO(rnystrom): If we rewrite "package:" imports to relative imports that |
246 // point to a canonical "packages" directory, we can limit "packages" to the | 263 // point to a canonical "packages" directory, we can limit "packages" to the |
247 // root of the URL as well. See: #16649. | 264 // root of the URL as well. See: #16649. |
248 var index = parts.indexOf("packages"); | 265 var index = parts.indexOf("packages"); |
249 if (index == -1) return null; | 266 if (index == -1) return null; |
250 | 267 |
251 // There should be a package name after "packages". | 268 // There should be a package name after "packages". |
252 if (parts.length <= index + 1) { | 269 if (parts.length <= index + 1) { |
253 throw new FormatException( | 270 throw new FormatException( |
254 'Invalid URL path "${url.path}". Expected package name ' | 271 'Invalid URL path "${url.path}". Expected package name ' |
255 'after "packages".'); | 272 'after "packages".'); |
256 } | 273 } |
257 | 274 |
258 var package = parts[index + 1]; | 275 var package = parts[index + 1]; |
259 var assetPath = path.url.join("lib", path.url.joinAll(parts.skip(index + 2))); | 276 var assetPath = p.url.join("lib", p.url.joinAll(parts.skip(index + 2))); |
260 return new AssetId(package, assetPath); | 277 return new AssetId(package, assetPath); |
261 } | 278 } |
OLD | NEW |