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

Side by Side Diff: lib/discovery.dart

Issue 1142363005: Added .packages, packages/ discovery. (Closed) Base URL: https://github.com/dart-lang/package_config.git@master
Patch Set: Addressed comments. Created 5 years, 7 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
« no previous file with comments | « no previous file | lib/packagemap.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, 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 library package_config.discovery;
6
7 import "dart:async";
8 import "dart:io" show Directory, File, FileSystemEntity;
9 import "package:path/path.dart" as path;
10 import "package:http/http.dart" as http;
11 import "packages.dart";
12 import "packages_file.dart" as pkgfile show parse;
13 import "src/packages_impl.dart";
14
15 /// Discover the package configuration for a Dart script.
16 ///
17 /// The [baseUri] points to either the Dart script or its directory.
18 /// A package resolution strategy is found by going through the following steps,
19 /// and stopping when something is found.
20 ///
21 /// * Check if a `.packages` file exists in the same directory.
22 /// * If `baseUri`'s scheme is not `file`, then assume a `packages` directory
23 /// in the same directory, and resolve packages relative to that.
24 /// * If `baseUri`'s scheme *is* `file`:
25 /// * Check if a `packages` directory exists.
26 /// * Otherwise check each successive parent directory of `baseUri` for a
27 /// `.packages` file.
28 ///
29 /// If any of these tests succeed, a `Packages` class is returned.
30 /// Returns the constant [noPackages] if no resolution strategy is found.
31 ///
32 /// This function currently only supports `file`, `http` and `https` URIs.
33 /// It needs to be able to load a `.packages` file from the URI, so only
34 /// recognized schemes are accepted.
35 ///
36 /// To support other schemes, an optional [loader] function can be supplied.
37 /// It's called to load the `.packages` file for any unsupported scheme.
38 /// It must return the *contents* of the file identified by the URI it's given,
39 /// which should be a UTF-8 encoded `.packages` file, and must return an
40 /// error future if loading fails for any reason.
41 Future<Packages> findPackages(
42 Uri baseUri,
43 {Future<List<int>> loader(Uri unsupportedUri)}) {
44 if (baseUri.scheme == "file") {
45 return new Future<Packages>.sync(() => findPackagesFromFile(baseUri));
46 } else if (baseUri.scheme == "http" || baseUri.scheme == "https") {
47 return findPackagesFromNonFile(baseUri, _httpGet);
48 } else if (loader != null) {
49 return findPackagesFromNonFile(baseUri, loader);
50 } else {
51 return new Future<Packages>.value(Packages.noPackages);
52 }
53 }
54
55 /// Find the location of the package resolution file/directory for a Dart file.
56 ///
57 /// Checks for a `.packages` file in the [workingDirectory].
58 /// If not found, checks for a `packages` directory in the same directory.
59 /// If still not found, starts checking parent directories for
60 /// `.packages` until reaching the root directory.
61 ///
62 /// Returns a [File] object of a `.packages` file if one is found, or a
63 /// [Directory] object for the `packages/` directory if that is found.
64 FileSystemEntity _findPackagesFile(String workingDirectory) {
65 var dir = new Directory(workingDirectory);
66 if (!dir.isAbsolute) dir = dir.absolute;
67 if (!dir.existsSync()) {
68 throw new ArgumentError.value(
69 workingDirectory, "workingDirectory", "Directory does not exist.");
70 }
71 File checkForConfigFile(Directory directory) {
72 assert(directory.isAbsolute);
73 var file = new File(path.join(directory.path, ".packages"));
74 if (file.existsSync()) return file;
75 return null;
76 }
77 // Check for $cwd/.packages
78 var packagesCfgFile = checkForConfigFile(dir);
79 if (packagesCfgFile != null) return packagesCfgFile;
80 // Check for $cwd/packages/
81 var packagesDir = new Directory(path.join(dir.path, "packages"));
82 if (packagesDir.existsSync()) return packagesDir;
83 // Check for cwd(/..)+/.packages
84 var parentDir = dir.parent;
85 while (parentDir.path != dir.path) {
86 packagesCfgFile = checkForConfigFile(parentDir);
87 if (packagesCfgFile != null) break;
88 dir = parentDir;
89 parentDir = dir.parent;
90 }
91 return packagesCfgFile;
92 }
93
94 /// Finds a package resolution strategy for a local Dart script.
95 ///
96 /// The [fileBaseUri] points to either a Dart script or the directory of the
97 /// script. The `fileBaseUri` must be a `file:` URI.
98 ///
99 /// This function first tries to locate a `.packages` file in the `fileBaseUri`
100 /// directory. If that is not found, it instead checks for the presence of
101 /// a `packages/` directory in the same place.
102 /// If that also fails, it starts checking parent directories for a `.packages`
103 /// file, and stops if it finds it.
104 /// Otherwise it gives up and returns [Pacakges.noPackages].
105 Packages findPackagesFromFile(Uri fileBaseUri) {
106 Uri baseDirectoryUri = fileBaseUri;
107 if (!fileBaseUri.path.endsWith('/')) {
108 baseDirectoryUri = baseDirectoryUri.resolve(".");
109 }
110 String baseDirectoryPath = baseDirectoryUri.toFilePath();
111 FileSystemEntity location = _findPackagesFile(baseDirectoryPath);
112 if (location == null) return Packages.noPackages;
113 if (location is File) {
114 List<int> fileBytes = location.readAsBytesSync();
115 Map<String, Uri> map = pkgfile.parse(fileBytes,
116 new Uri.file(location.path));
117 return new MapPackages(map);
118 }
119 assert(location is Directory);
120 return new FilePackagesDirectoryPackages(location);
121 }
122
123 /// Finds a package resolution strategy for a Dart script.
124 ///
125 /// The [nonFileUri] points to either a Dart script or the directory of the
126 /// script.
127 /// The [nonFileUri] should not be a `file:` URI since the algorithm for
128 /// finding a package resolution strategy is more elaborate for `file:` URIs.
129 /// In that case, use [findPackagesFile].
130 ///
131 /// This function first tries to locate a `.packages` file in the [nonFileUri]
132 /// directory. If that is not found, it instead assumes a `packages/` directory
133 /// in the same place.
134 ///
135 /// By default, this function only works for `http:` and `https:` URIs.
136 /// To support other schemes, a loader must be provided, which is used to
137 /// try to load the `.packages` file. The loader should return the contents
138 /// of the requestsed `.packages` file as bytes, which will be assumed to be
139 /// UTF-8 encoded.
140 Future<Packages> findPackagesFromNonFile(Uri nonFileUri,
141 [Future<List<int>> loader(Uri name)]) {
142 if (loader == null) loader = _httpGet;
143 Uri packagesFileUri = nonFileUri.resolve(".packages");
144 return loader(packagesFileUri).then((List<int> fileBytes) {
145 Map<String, Uri> map = pkgfile.parse(fileBytes, packagesFileUri);
146 return new MapPackages(map);
147 }, onError: (_) {
148 // Didn't manage to load ".packages". Assume a "packages/" directory.
149 Uri packagesDirectoryUri = nonFileUri.resolve("packages/");
150 return new NonFilePackagesDirectoryPackages(packagesDirectoryUri);
151 });
152 }
153
154 /// Fetches a file using the http library.
155 Future<List<int>> _httpGet(Uri uri) {
156 return http.get(uri).then((http.Response response) {
157 if (response.statusCode == 200) return response.bodyBytes;
158 throw 0; // The error message isn't being used for anything.
159 });
160 }
OLDNEW
« no previous file with comments | « no previous file | lib/packagemap.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698