OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 import 'dart:collection'; |
| 6 |
| 7 import 'package:collection/collection.dart'; |
| 8 import 'package:package_config/packages_file.dart' as packages_file; |
| 9 import 'package:path/path.dart' as p; |
| 10 |
| 11 import 'async_package_resolver.dart'; |
| 12 import 'package_resolver.dart'; |
| 13 import 'sync_package_resolver.dart'; |
| 14 import 'utils.dart'; |
| 15 |
| 16 /// A package resolution strategy based on a package config map. |
| 17 class PackageConfigResolver implements SyncPackageResolver { |
| 18 final packageRoot = null; |
| 19 |
| 20 final Map<String, Uri> packageConfigMap; |
| 21 |
| 22 Uri get packageConfigUri { |
| 23 if (_uri != null) return _uri; |
| 24 |
| 25 var buffer = new StringBuffer(); |
| 26 packages_file.write(buffer, packageConfigMap, comment: ""); |
| 27 _uri = new UriData.fromString(buffer.toString(), |
| 28 parameters: {"charset": "utf-8"}) |
| 29 .uri; |
| 30 return _uri; |
| 31 } |
| 32 Uri _uri; |
| 33 |
| 34 PackageResolver get asAsync => new AsyncPackageResolver(this); |
| 35 |
| 36 String get processArgument => "--packages=$packageConfigUri"; |
| 37 |
| 38 PackageConfigResolver(Map<String, Uri> packageConfigMap, {uri}) |
| 39 : packageConfigMap = _normalizeMap(packageConfigMap), |
| 40 _uri = uri == null ? null : asUri(uri, "uri"); |
| 41 |
| 42 /// Normalizes the URIs in [map] to ensure that they all end in a trailing |
| 43 /// slash. |
| 44 static Map<String, Uri> _normalizeMap(Map<String, Uri> map) { |
| 45 return new UnmodifiableMapView(mapMap(map, value: (_, uri) { |
| 46 if (uri.pathSegments.last.isEmpty) return uri; |
| 47 return uri.replace(pathSegments: uri.pathSegments.toList()..add("")); |
| 48 })); |
| 49 } |
| 50 |
| 51 Uri resolveUri(packageUri) { |
| 52 var uri = asPackageUri(packageUri, "packageUri"); |
| 53 |
| 54 var baseUri = packageConfigMap[uri.pathSegments.first]; |
| 55 if (baseUri == null) return null; |
| 56 |
| 57 var segments = baseUri.pathSegments.toList() |
| 58 ..removeLast(); // Remove the trailing slash. |
| 59 |
| 60 // Following [Isolate.resolvePackageUri], "package:foo" resolves to null. |
| 61 if (uri.pathSegments.length == 1) return null; |
| 62 |
| 63 segments.addAll(uri.pathSegments.skip(1)); |
| 64 return baseUri.replace(pathSegments: segments); |
| 65 } |
| 66 |
| 67 Uri urlFor(String package, [String path]) { |
| 68 var baseUri = packageConfigMap[package]; |
| 69 if (baseUri == null) return null; |
| 70 if (path == null) return baseUri; |
| 71 return baseUri.resolve(path); |
| 72 } |
| 73 |
| 74 Uri packageUriFor(url) { |
| 75 url = asUri(url, "url").toString(); |
| 76 |
| 77 // Make sure isWithin works if [url] is exactly the base. |
| 78 var nested = p.url.join(url, "_"); |
| 79 for (var package in packageConfigMap.keys) { |
| 80 var base = packageConfigMap[package].toString(); |
| 81 if (!p.url.isWithin(base, nested)) continue; |
| 82 |
| 83 var relative = p.url.relative(url, from: base); |
| 84 if (relative == '.') relative = ''; |
| 85 return Uri.parse("package:$package/$relative"); |
| 86 } |
| 87 |
| 88 return null; |
| 89 } |
| 90 |
| 91 String packagePath(String package) { |
| 92 var lib = packageConfigMap[package]; |
| 93 if (lib == null) return null; |
| 94 if (lib.scheme != 'file') return null; |
| 95 return p.dirname(p.fromUri(lib)); |
| 96 } |
| 97 } |
OLD | NEW |