Line data Source code
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 0 : if (_uri != null) return _uri;
24 :
25 0 : var buffer = new StringBuffer();
26 0 : packages_file.write(buffer, packageConfigMap, comment: "");
27 0 : _uri = new UriData.fromString(buffer.toString(),
28 0 : parameters: {"charset": "utf-8"})
29 0 : .uri;
30 0 : return _uri;
31 : }
32 : Uri _uri;
33 :
34 0 : PackageResolver get asAsync => new AsyncPackageResolver(this);
35 :
36 0 : String get processArgument => "--packages=$packageConfigUri";
37 :
38 : PackageConfigResolver(Map<String, Uri> packageConfigMap, {uri})
39 0 : : packageConfigMap = _normalizeMap(packageConfigMap),
40 0 : _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 0 : new UnmodifiableMapView(
46 0 : mapMap(map, value: (_, uri) => ensureTrailingSlash(uri)));
47 :
48 : Uri resolveUri(packageUri) {
49 0 : var uri = asPackageUri(packageUri, "packageUri");
50 :
51 0 : var baseUri = packageConfigMap[uri.pathSegments.first];
52 : if (baseUri == null) return null;
53 :
54 0 : var segments = baseUri.pathSegments.toList()
55 0 : ..removeLast(); // Remove the trailing slash.
56 :
57 : // Following [Isolate.resolvePackageUri], "package:foo" resolves to null.
58 0 : if (uri.pathSegments.length == 1) return null;
59 :
60 0 : segments.addAll(uri.pathSegments.skip(1));
61 0 : return baseUri.replace(pathSegments: segments);
62 : }
63 :
64 : Uri urlFor(String package, [String path]) {
65 0 : var baseUri = packageConfigMap[package];
66 : if (baseUri == null) return null;
67 : if (path == null) return baseUri;
68 0 : return baseUri.resolve(path);
69 : }
70 :
71 : Uri packageUriFor(url) {
72 0 : url = asUri(url, "url").toString();
73 :
74 : // Make sure isWithin works if [url] is exactly the base.
75 0 : var nested = p.url.join(url, "_");
76 0 : for (var package in packageConfigMap.keys) {
77 0 : var base = packageConfigMap[package].toString();
78 0 : if (!p.url.isWithin(base, nested)) continue;
79 :
80 0 : var relative = p.url.relative(url, from: base);
81 0 : if (relative == '.') relative = '';
82 0 : return Uri.parse("package:$package/$relative");
83 : }
84 :
85 : return null;
86 : }
87 :
88 : String packagePath(String package) {
89 0 : var lib = packageConfigMap[package];
90 : if (lib == null) return null;
91 0 : if (lib.scheme != 'file') return null;
92 0 : return p.dirname(p.fromUri(lib));
93 : }
94 : }
|