OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 library pubspec; | 5 library pubspec; |
6 | 6 |
7 import '../../pkg/yaml/lib/yaml.dart'; | 7 import '../../pkg/yaml/lib/yaml.dart'; |
8 import '../../pkg/path/lib/path.dart' as path; | 8 import '../../pkg/path/lib/path.dart' as path; |
9 | 9 |
10 import 'io.dart'; | 10 import 'io.dart'; |
(...skipping 20 matching lines...) Expand all Loading... |
31 /// All pubspec fields. This includes the fields from which other properties | 31 /// All pubspec fields. This includes the fields from which other properties |
32 /// are derived. | 32 /// are derived. |
33 final Map<String, Object> fields; | 33 final Map<String, Object> fields; |
34 | 34 |
35 /// Loads the pubspec for a package [name] located in [packageDir]. | 35 /// Loads the pubspec for a package [name] located in [packageDir]. |
36 factory Pubspec.load(String name, String packageDir, SourceRegistry sources) { | 36 factory Pubspec.load(String name, String packageDir, SourceRegistry sources) { |
37 var pubspecPath = path.join(packageDir, 'pubspec.yaml'); | 37 var pubspecPath = path.join(packageDir, 'pubspec.yaml'); |
38 if (!fileExists(pubspecPath)) throw new PubspecNotFoundException(name); | 38 if (!fileExists(pubspecPath)) throw new PubspecNotFoundException(name); |
39 | 39 |
40 try { | 40 try { |
41 var pubspec = new Pubspec.parse(readTextFile(pubspecPath), sources); | 41 var pubspec = new Pubspec.parse(pubspecPath, readTextFile(pubspecPath), |
| 42 sources); |
42 | 43 |
43 if (pubspec.name == null) { | 44 if (pubspec.name == null) { |
44 throw new PubspecHasNoNameException(name); | 45 throw new PubspecHasNoNameException(name); |
45 } | 46 } |
46 | 47 |
47 if (name != null && pubspec.name != name) { | 48 if (name != null && pubspec.name != name) { |
48 throw new PubspecNameMismatchException(name, pubspec.name); | 49 throw new PubspecNameMismatchException(name, pubspec.name); |
49 } | 50 } |
50 | 51 |
51 return pubspec; | 52 return pubspec; |
(...skipping 10 matching lines...) Expand all Loading... |
62 : name = null, | 63 : name = null, |
63 version = Version.none, | 64 version = Version.none, |
64 dependencies = <PackageRef>[], | 65 dependencies = <PackageRef>[], |
65 environment = new PubspecEnvironment(), | 66 environment = new PubspecEnvironment(), |
66 fields = {}; | 67 fields = {}; |
67 | 68 |
68 /// Whether or not the pubspec has no contents. | 69 /// Whether or not the pubspec has no contents. |
69 bool get isEmpty => | 70 bool get isEmpty => |
70 name == null && version == Version.none && dependencies.isEmpty; | 71 name == null && version == Version.none && dependencies.isEmpty; |
71 | 72 |
72 // TODO(rnystrom): Make this a static method to match corelib. | 73 // TODO(rnystrom): Instead of allowing a null argument here, split this up |
73 /// Parses the pubspec whose text is [contents]. If the pubspec doesn't define | 74 // into load(), parse(), and _parse() like LockFile does. |
74 /// version for itself, it defaults to [Version.none]. | 75 /// Parses the pubspec stored at [filePath] whose text is [contents]. If the |
75 factory Pubspec.parse(String contents, SourceRegistry sources) { | 76 /// pubspec doesn't define version for itself, it defaults to [Version.none]. |
| 77 /// [filePath] may be `null` if the pubspec is not on the user's local |
| 78 /// file system. |
| 79 factory Pubspec.parse(String filePath, String contents, |
| 80 SourceRegistry sources) { |
76 var name = null; | 81 var name = null; |
77 var version = Version.none; | 82 var version = Version.none; |
78 | 83 |
79 if (contents.trim() == '') return new Pubspec.empty(); | 84 if (contents.trim() == '') return new Pubspec.empty(); |
80 | 85 |
81 var parsedPubspec = loadYaml(contents); | 86 var parsedPubspec = loadYaml(contents); |
82 if (parsedPubspec == null) return new Pubspec.empty(); | 87 if (parsedPubspec == null) return new Pubspec.empty(); |
83 | 88 |
84 if (parsedPubspec is! Map) { | 89 if (parsedPubspec is! Map) { |
85 throw new FormatException('The pubspec must be a YAML mapping.'); | 90 throw new FormatException('The pubspec must be a YAML mapping.'); |
86 } | 91 } |
87 | 92 |
88 if (parsedPubspec.containsKey('name')) { | 93 if (parsedPubspec.containsKey('name')) { |
89 name = parsedPubspec['name']; | 94 name = parsedPubspec['name']; |
90 if (name is! String) { | 95 if (name is! String) { |
91 throw new FormatException( | 96 throw new FormatException( |
92 'The pubspec "name" field should be a string, but was "$name".'); | 97 'The pubspec "name" field should be a string, but was "$name".'); |
93 } | 98 } |
94 } | 99 } |
95 | 100 |
96 if (parsedPubspec.containsKey('version')) { | 101 if (parsedPubspec.containsKey('version')) { |
97 version = new Version.parse(parsedPubspec['version']); | 102 version = new Version.parse(parsedPubspec['version']); |
98 } | 103 } |
99 | 104 |
100 var dependencies = _parseDependencies(sources, | 105 var dependencies = _parseDependencies(filePath, sources, |
101 parsedPubspec['dependencies']); | 106 parsedPubspec['dependencies']); |
102 | 107 |
103 var environmentYaml = parsedPubspec['environment']; | 108 var environmentYaml = parsedPubspec['environment']; |
104 var sdkConstraint = VersionConstraint.any; | 109 var sdkConstraint = VersionConstraint.any; |
105 if (environmentYaml != null) { | 110 if (environmentYaml != null) { |
106 if (environmentYaml is! Map) { | 111 if (environmentYaml is! Map) { |
107 throw new FormatException( | 112 throw new FormatException( |
108 'The pubspec "environment" field should be a map, but was ' | 113 'The pubspec "environment" field should be a map, but was ' |
109 '"$environmentYaml".'); | 114 '"$environmentYaml".'); |
110 } | 115 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 } | 185 } |
181 | 186 |
182 var goodScheme = new RegExp(r'^https?:'); | 187 var goodScheme = new RegExp(r'^https?:'); |
183 if (!goodScheme.hasMatch(url)) { | 188 if (!goodScheme.hasMatch(url)) { |
184 throw new FormatException( | 189 throw new FormatException( |
185 'The "$field" field should be an "http:" or "https:" URL, but ' | 190 'The "$field" field should be an "http:" or "https:" URL, but ' |
186 'was "$url".'); | 191 'was "$url".'); |
187 } | 192 } |
188 } | 193 } |
189 | 194 |
190 List<PackageRef> _parseDependencies(SourceRegistry sources, yaml) { | 195 List<PackageRef> _parseDependencies(String pubspecPath, SourceRegistry sources, |
| 196 yaml) { |
191 var dependencies = <PackageRef>[]; | 197 var dependencies = <PackageRef>[]; |
192 | 198 |
193 // Allow an empty dependencies key. | 199 // Allow an empty dependencies key. |
194 if (yaml == null) return dependencies; | 200 if (yaml == null) return dependencies; |
195 | 201 |
196 if (yaml is! Map || yaml.keys.any((e) => e is! String)) { | 202 if (yaml is! Map || yaml.keys.any((e) => e is! String)) { |
197 throw new FormatException( | 203 throw new FormatException( |
198 'The pubspec dependencies should be a map of package names, but ' | 204 'The pubspec dependencies should be a map of package names, but ' |
199 'was ${yaml}.'); | 205 'was ${yaml}.'); |
200 } | 206 } |
(...skipping 25 matching lines...) Expand all Loading... |
226 'Source name $sourceName should be a string.'); | 232 'Source name $sourceName should be a string.'); |
227 } | 233 } |
228 | 234 |
229 source = sources[sourceName]; | 235 source = sources[sourceName]; |
230 description = spec[sourceName]; | 236 description = spec[sourceName]; |
231 } else { | 237 } else { |
232 throw new FormatException( | 238 throw new FormatException( |
233 'Dependency specification $spec should be a string or a mapping.'); | 239 'Dependency specification $spec should be a string or a mapping.'); |
234 } | 240 } |
235 | 241 |
236 source.validateDescription(description, fromLockFile: false); | 242 description = source.parseDescription(pubspecPath, description, |
| 243 fromLockFile: false); |
237 | 244 |
238 dependencies.add(new PackageRef( | 245 dependencies.add(new PackageRef( |
239 name, source, versionConstraint, description)); | 246 name, source, versionConstraint, description)); |
240 }); | 247 }); |
241 | 248 |
242 return dependencies; | 249 return dependencies; |
243 } | 250 } |
244 | 251 |
245 /// The environment-related metadata in the pubspec. Corresponds to the data | 252 /// The environment-related metadata in the pubspec. Corresponds to the data |
246 /// under the "environment:" key in the pubspec. | 253 /// under the "environment:" key in the pubspec. |
247 class PubspecEnvironment { | 254 class PubspecEnvironment { |
248 /// The version constraint specifying which SDK versions this package works | 255 /// The version constraint specifying which SDK versions this package works |
249 /// with. | 256 /// with. |
250 final VersionConstraint sdkVersion; | 257 final VersionConstraint sdkVersion; |
251 | 258 |
252 PubspecEnvironment([VersionConstraint sdk]) | 259 PubspecEnvironment([VersionConstraint sdk]) |
253 : sdkVersion = sdk != null ? sdk : VersionConstraint.any; | 260 : sdkVersion = sdk != null ? sdk : VersionConstraint.any; |
254 } | 261 } |
OLD | NEW |