OLD | NEW |
| (Empty) |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library path_source; | |
6 | |
7 import 'dart:async'; | |
8 import 'dart:io'; | |
9 | |
10 import 'package:pathos/path.dart' as path; | |
11 | |
12 import 'log.dart' as log; | |
13 | |
14 import 'io.dart'; | |
15 import 'package.dart'; | |
16 import 'pubspec.dart'; | |
17 import 'version.dart'; | |
18 import 'source.dart'; | |
19 import 'utils.dart'; | |
20 | |
21 // TODO(rnystrom): Support relative paths. (See comment in _validatePath().) | |
22 /// A package [Source] that installs packages from a given local file path. | |
23 class PathSource extends Source { | |
24 final name = 'path'; | |
25 final shouldCache = false; | |
26 | |
27 Future<Pubspec> describe(PackageId id) { | |
28 return new Future.sync(() { | |
29 _validatePath(id.name, id.description); | |
30 return new Pubspec.load(id.name, id.description["path"], | |
31 systemCache.sources); | |
32 }); | |
33 } | |
34 | |
35 bool descriptionsEqual(description1, description2) { | |
36 try { | |
37 // Compare real paths after normalizing and resolving symlinks. | |
38 var path1 = new File(description1["path"]).fullPathSync(); | |
39 var path2 = new File(description2["path"]).fullPathSync(); | |
40 return path1 == path2; | |
41 } on FileIOException catch (ex) { | |
42 // If either of the files couldn't be found, fall back to just comparing | |
43 // the normalized paths. | |
44 var path1 = path.normalize(path.absolute(description1["path"])); | |
45 var path2 = path.normalize(path.absolute(description2["path"])); | |
46 return path1 == path2; | |
47 } | |
48 } | |
49 | |
50 Future<bool> install(PackageId id, String destination) { | |
51 return new Future.sync(() { | |
52 try { | |
53 _validatePath(id.name, id.description); | |
54 } on FormatException catch(err) { | |
55 return false; | |
56 } | |
57 | |
58 createPackageSymlink(id.name, id.description["path"], destination, | |
59 relative: id.description["relative"]); | |
60 return true; | |
61 }); | |
62 } | |
63 | |
64 /// Parses a path dependency. This takes in a path string and returns a map. | |
65 /// The "path" key will be the original path but resolved relative to the | |
66 /// containing path. The "relative" key will be `true` if the original path | |
67 /// was relative. | |
68 /// | |
69 /// A path coming from a pubspec is a simple string. From a lock file, it's | |
70 /// an expanded {"path": ..., "relative": ...} map. | |
71 dynamic parseDescription(String containingPath, description, | |
72 {bool fromLockFile: false}) { | |
73 if (fromLockFile) { | |
74 if (description is! Map) { | |
75 throw new FormatException("The description must be a map."); | |
76 } | |
77 | |
78 if (description["path"] is! String) { | |
79 throw new FormatException("The 'path' field of the description must " | |
80 "be a string."); | |
81 } | |
82 | |
83 if (description["relative"] is! bool) { | |
84 throw new FormatException("The 'relative' field of the description " | |
85 "must be a boolean."); | |
86 } | |
87 | |
88 return description; | |
89 } | |
90 | |
91 if (description is! String) { | |
92 throw new FormatException("The description must be a path string."); | |
93 } | |
94 | |
95 // Resolve the path relative to the containing file path, and remember | |
96 // whether the original path was relative or absolute. | |
97 bool isRelative = path.isRelative(description); | |
98 if (path.isRelative(description)) { | |
99 // Can't handle relative paths coming from pubspecs that are not on the | |
100 // local file system. | |
101 assert(containingPath != null); | |
102 | |
103 description = path.join(path.dirname(containingPath), description); | |
104 } | |
105 | |
106 return { | |
107 "path": description, | |
108 "relative": isRelative | |
109 }; | |
110 } | |
111 | |
112 /// Ensures that [description] is a valid path description. It must be a map, | |
113 /// with a "path" key containing a path that points to an existing directory. | |
114 /// Throws a [FormatException] if the path is invalid. | |
115 void _validatePath(String name, description) { | |
116 var dir = description["path"]; | |
117 | |
118 if (dirExists(dir)) return; | |
119 | |
120 if (fileExists(dir)) { | |
121 throw new FormatException( | |
122 "Path dependency for package '$name' must refer to a " | |
123 "directory, not a file. Was '$dir'."); | |
124 } | |
125 | |
126 throw new FormatException("Could not find package '$name' at '$dir'."); | |
127 } | |
128 } | |
OLD | NEW |