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 : // TODO(nweiz): Avoid importing dart:io directly when cross-platform libraries
6 : // exist.
7 : import 'dart:io';
8 : import 'dart:isolate';
9 : import 'dart:async';
10 : import 'dart:convert';
11 :
12 : import 'package:http/http.dart' as http;
13 : import 'package:package_config/packages_file.dart' as packages_file;
14 :
15 : /// Loads the configuration map from [uri].
16 : ///
17 : /// This supports `http`, `file`, `data`, and `package` URIs. If [client] is
18 : /// passed and an HTTP request is needed, it's used to make that request;
19 : /// otherwise, a default client is used.
20 : Future<Map<String, Uri>> loadConfigMap(Uri uri, {http.Client client}) async {
21 0 : var resolved = Uri.base.resolveUri(uri);
22 :
23 : var text;
24 0 : if (resolved.scheme == 'http') {
25 0 : text = await (client == null
26 0 : ? http.read(resolved)
27 0 : : client.read(resolved));
28 0 : } else if (resolved.scheme == 'file') {
29 0 : var path = resolved.toFilePath(windows: Platform.isWindows);
30 0 : text = await new File(path).readAsString();
31 0 : } else if (resolved.scheme == 'data') {
32 0 : text = resolved.data.contentAsString();
33 0 : } else if (resolved.scheme == 'package') {
34 0 : return loadConfigMap(await Isolate.resolvePackageUri(uri),
35 : client: client);
36 : } else {
37 0 : throw new UnsupportedError(
38 0 : 'PackageInfo.loadConfig doesn\'t support URI scheme "${uri.scheme}:".');
39 : }
40 :
41 0 : return packages_file.parse(UTF8.encode(text), resolved);
42 0 : }
43 :
44 : /// Converts [uri] to a [Uri] and verifies that it's a valid `package:` URI.
45 : ///
46 : /// Throws an [ArgumentError] if [uri] isn't a [String] or a [Uri]. [name] is
47 : /// used as the argument name in that error.
48 : ///
49 : /// Throws a [FormatException] if [uri] isn't a `package:` URI or doesn't have
50 : /// at least one path segment.
51 : Uri asPackageUri(uri, String name) {
52 0 : uri = asUri(uri, name);
53 :
54 0 : if (uri.scheme != 'package') {
55 0 : throw new FormatException("Can only resolve a package: URI.",
56 0 : uri.toString(), 0);
57 0 : } else if (uri.pathSegments.isEmpty) {
58 0 : throw new FormatException("Expected package name.",
59 0 : uri.toString(), "package:".length);
60 : }
61 :
62 : return uri;
63 : }
64 :
65 : /// Converts [uri] to a [Uri].
66 : ///
67 : /// Throws an [ArgumentError] if [uri] isn't a [String] or a [Uri]. [name] is
68 : /// used as the argument name in that error.
69 : Uri asUri(uri, String name) {
70 0 : if (uri is Uri) return uri;
71 0 : if (uri is String) return Uri.parse(uri);
72 :
73 0 : throw new ArgumentError.value(uri, name, "Must be a String or a Uri.");
74 : }
75 :
76 : /// Returns a copy of [uri] with a trailing slash.
77 : ///
78 : /// If [uri] already ends in a slash, returns it as-is.
79 : Uri ensureTrailingSlash(Uri uri) {
80 0 : if (uri.pathSegments.isEmpty) return uri.replace(path: "/");
81 0 : if (uri.pathSegments.last.isEmpty) return uri;
82 0 : return uri.replace(pathSegments: uri.pathSegments.toList()..add(""));
83 : }
|