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 import 'dart:async'; | 5 import 'dart:async'; |
6 | 6 |
7 import 'package:path/path.dart' as p; | 7 import 'package:path/path.dart' as p; |
8 import 'package:pub_semver/pub_semver.dart'; | 8 import 'package:pub_semver/pub_semver.dart'; |
9 | 9 |
10 import '../exceptions.dart'; | 10 import '../exceptions.dart'; |
11 import '../io.dart'; | 11 import '../io.dart'; |
12 import '../package.dart'; | 12 import '../package.dart'; |
13 import '../pubspec.dart'; | 13 import '../pubspec.dart'; |
14 import '../source.dart'; | 14 import '../source.dart'; |
| 15 import '../system_cache.dart'; |
15 import '../utils.dart'; | 16 import '../utils.dart'; |
16 | 17 |
17 /// A package [Source] that gets packages from a given local file path. | 18 /// A package [Source] that gets packages from a given local file path. |
18 class PathSource extends Source { | 19 class PathSource extends Source { |
| 20 final name = 'path'; |
| 21 |
| 22 BoundSource bind(SystemCache systemCache) => |
| 23 new BoundPathSource(this, systemCache); |
| 24 |
| 25 /// Given a valid path reference description, returns the file path it |
| 26 /// describes. |
| 27 /// |
| 28 /// This returned path may be relative or absolute and it is up to the caller |
| 29 /// to know how to interpret a relative path. |
| 30 String pathFromDescription(description) => description["path"]; |
| 31 |
19 /// Returns a reference to a path package named [name] at [path]. | 32 /// Returns a reference to a path package named [name] at [path]. |
20 static PackageRef refFor(String name, String path) { | 33 PackageRef refFor(String name, String path) { |
21 return new PackageRef(name, 'path', { | 34 return new PackageRef(name, 'path', { |
22 "path": path, | 35 "path": path, |
23 "relative": p.isRelative(path) | 36 "relative": p.isRelative(path) |
24 }); | 37 }); |
25 } | 38 } |
26 | 39 |
27 /// Returns an ID for a path package with the given [name] and [version] at | 40 /// Returns an ID for a path package with the given [name] and [version] at |
28 /// [path]. | 41 /// [path]. |
29 static PackageId idFor(String name, Version version, String path) { | 42 PackageId idFor(String name, Version version, String path) { |
30 return new PackageId(name, 'path', version, { | 43 return new PackageId(name, 'path', version, { |
31 "path": path, | 44 "path": path, |
32 "relative": p.isRelative(path) | 45 "relative": p.isRelative(path) |
33 }); | 46 }); |
34 } | 47 } |
35 | 48 |
36 /// Given a valid path reference description, returns the file path it | |
37 /// describes. | |
38 /// | |
39 /// This returned path may be relative or absolute and it is up to the caller | |
40 /// to know how to interpret a relative path. | |
41 static String pathFromDescription(description) => description["path"]; | |
42 | |
43 final name = 'path'; | |
44 | |
45 Future<List<PackageId>> doGetVersions(PackageRef ref) async { | |
46 // There's only one package ID for a given path. We just need to find the | |
47 // version. | |
48 var pubspec = _loadPubspec(ref); | |
49 var id = new PackageId(ref.name, name, pubspec.version, ref.description); | |
50 memoizePubspec(id, pubspec); | |
51 return [id]; | |
52 } | |
53 | |
54 Future<Pubspec> doDescribe(PackageId id) async => _loadPubspec(id.toRef()); | |
55 | |
56 Pubspec _loadPubspec(PackageRef ref) { | |
57 var dir = _validatePath(ref.name, ref.description); | |
58 return new Pubspec.load(dir, systemCache.sources, | |
59 expectedName: ref.name); | |
60 } | |
61 | |
62 bool descriptionsEqual(description1, description2) { | 49 bool descriptionsEqual(description1, description2) { |
63 // Compare real paths after normalizing and resolving symlinks. | 50 // Compare real paths after normalizing and resolving symlinks. |
64 var path1 = canonicalize(description1["path"]); | 51 var path1 = canonicalize(description1["path"]); |
65 var path2 = canonicalize(description2["path"]); | 52 var path2 = canonicalize(description2["path"]); |
66 return path1 == path2; | 53 return path1 == path2; |
67 } | 54 } |
68 | 55 |
69 Future get(PackageId id, String symlink) { | |
70 return new Future.sync(() { | |
71 var dir = _validatePath(id.name, id.description); | |
72 createPackageSymlink(id.name, dir, symlink, | |
73 relative: id.description["relative"]); | |
74 }); | |
75 } | |
76 | |
77 String getDirectory(PackageId id) => id.description["path"]; | |
78 | |
79 /// Parses a path dependency. | 56 /// Parses a path dependency. |
80 /// | 57 /// |
81 /// This takes in a path string and returns a map. The "path" key will be the | 58 /// This takes in a path string and returns a map. The "path" key will be the |
82 /// original path but resolved relative to the containing path. The | 59 /// original path but resolved relative to the containing path. The |
83 /// "relative" key will be `true` if the original path was relative. | 60 /// "relative" key will be `true` if the original path was relative. |
84 PackageRef parseRef(String name, description, {String containingPath}) { | 61 PackageRef parseRef(String name, description, {String containingPath}) { |
85 if (description is! String) { | 62 if (description is! String) { |
86 throw new FormatException("The description must be a path string."); | 63 throw new FormatException("The description must be a path string."); |
87 } | 64 } |
88 | 65 |
(...skipping 53 matching lines...) Loading... |
142 | 119 |
143 /// Converts a parsed relative path to its original relative form. | 120 /// Converts a parsed relative path to its original relative form. |
144 String formatDescription(String containingPath, description) { | 121 String formatDescription(String containingPath, description) { |
145 var sourcePath = description["path"]; | 122 var sourcePath = description["path"]; |
146 if (description["relative"]) { | 123 if (description["relative"]) { |
147 sourcePath = p.relative(description['path'], from: containingPath); | 124 sourcePath = p.relative(description['path'], from: containingPath); |
148 } | 125 } |
149 | 126 |
150 return sourcePath; | 127 return sourcePath; |
151 } | 128 } |
| 129 } |
| 130 |
| 131 /// The [BoundSource] for [PathSource]. |
| 132 class BoundPathSource extends BoundSource { |
| 133 final PathSource source; |
| 134 |
| 135 final SystemCache systemCache; |
| 136 |
| 137 BoundPathSource(this.source, this.systemCache); |
| 138 |
| 139 Future<List<PackageId>> doGetVersions(PackageRef ref) async { |
| 140 // There's only one package ID for a given path. We just need to find the |
| 141 // version. |
| 142 var pubspec = _loadPubspec(ref); |
| 143 var id = new PackageId( |
| 144 ref.name, source.name, pubspec.version, ref.description); |
| 145 memoizePubspec(id, pubspec); |
| 146 return [id]; |
| 147 } |
| 148 |
| 149 Future<Pubspec> doDescribe(PackageId id) async => _loadPubspec(id.toRef()); |
| 150 |
| 151 Pubspec _loadPubspec(PackageRef ref) { |
| 152 var dir = _validatePath(ref.name, ref.description); |
| 153 return new Pubspec.load(dir, systemCache.sources, expectedName: ref.name); |
| 154 } |
| 155 |
| 156 Future get(PackageId id, String symlink) { |
| 157 return new Future.sync(() { |
| 158 var dir = _validatePath(id.name, id.description); |
| 159 createPackageSymlink(id.name, dir, symlink, |
| 160 relative: id.description["relative"]); |
| 161 }); |
| 162 } |
| 163 |
| 164 String getDirectory(PackageId id) => id.description["path"]; |
152 | 165 |
153 /// Ensures that [description] is a valid path description and returns a | 166 /// Ensures that [description] is a valid path description and returns a |
154 /// normalized path to the package. | 167 /// normalized path to the package. |
155 /// | 168 /// |
156 /// It must be a map, with a "path" key containing a path that points to an | 169 /// It must be a map, with a "path" key containing a path that points to an |
157 /// existing directory. Throws an [ApplicationException] if the path is | 170 /// existing directory. Throws an [ApplicationException] if the path is |
158 /// invalid. | 171 /// invalid. |
159 String _validatePath(String name, description) { | 172 String _validatePath(String name, description) { |
160 var dir = description["path"]; | 173 var dir = description["path"]; |
161 | 174 |
162 if (dirExists(dir)) return dir; | 175 if (dirExists(dir)) return dir; |
163 | 176 |
164 if (fileExists(dir)) { | 177 if (fileExists(dir)) { |
165 fail('Path dependency for package $name must refer to a directory, ' | 178 fail('Path dependency for package $name must refer to a directory, ' |
166 'not a file. Was "$dir".'); | 179 'not a file. Was "$dir".'); |
167 } | 180 } |
168 | 181 |
169 throw new PackageNotFoundException( | 182 throw new PackageNotFoundException( |
170 'Could not find package $name at "$dir".'); | 183 'Could not find package $name at "$dir".'); |
171 } | 184 } |
172 } | 185 } |
OLD | NEW |