Index: sdk/lib/_internal/pub/lib/src/lock_file.dart |
diff --git a/sdk/lib/_internal/pub/lib/src/lock_file.dart b/sdk/lib/_internal/pub/lib/src/lock_file.dart |
index 95421a604fc372af3f170a0fc6c2f9142b51db7f..b8eff70a71b473b19446201d757fa9b03a107aad 100644 |
--- a/sdk/lib/_internal/pub/lib/src/lock_file.dart |
+++ b/sdk/lib/_internal/pub/lib/src/lock_file.dart |
@@ -4,6 +4,7 @@ |
library pub.lock_file; |
+import 'package:source_maps/source_maps.dart'; |
import 'package:yaml/yaml.dart'; |
import 'io.dart'; |
@@ -48,40 +49,44 @@ class LockFile { |
var packages = <String, PackageId>{}; |
if (contents.trim() == '') return new LockFile.empty(); |
- var parsed = loadYaml(contents); |
+ var parsed = loadYamlNode(contents, sourceName: filePath); |
+ |
+ _validate(parsed is Map, 'The lockfile must be a YAML mapping.', parsed); |
var packageEntries = parsed['packages']; |
if (packageEntries != null) { |
+ _validate(packageEntries is Map, 'The "packages" field must be a map.', |
+ parsed.nodes['packages']); |
+ |
packageEntries.forEach((name, spec) { |
// Parse the version. |
- if (!spec.containsKey('version')) { |
- throw new FormatException('Package $name is missing a version.'); |
- } |
+ _validate(spec.containsKey('version'), |
+ 'Package $name is missing a version.', spec); |
var version = new Version.parse(spec['version']); |
// Parse the source. |
- if (!spec.containsKey('source')) { |
- throw new FormatException('Package $name is missing a source.'); |
- } |
+ _validate(spec.containsKey('source'), |
+ 'Package $name is missing a source.', spec); |
var sourceName = spec['source']; |
- if (!spec.containsKey('description')) { |
- throw new FormatException('Package $name is missing a description.'); |
- } |
+ _validate(spec.containsKey('description'), |
+ 'Package $name is missing a description.', spec); |
var description = spec['description']; |
// Let the source parse the description. |
var source = sources[sourceName]; |
- description = source.parseDescription(filePath, description, |
- fromLockFile: true); |
+ try { |
+ description = source.parseDescription(filePath, description, |
+ fromLockFile: true); |
+ } on FormatException catch(ex) { |
nweiz
2014/07/17 07:11:19
Nit: space after "catch".
Bob Nystrom
2014/07/17 22:19:19
Done.
|
+ throw new SpanFormatException(ex.message, spec.nodes['source'].span); |
+ } |
var id = new PackageId(name, sourceName, version, description); |
// Validate the name. |
- if (name != id.name) { |
- throw new FormatException( |
- "Package name $name doesn't match ${id.name}."); |
- } |
+ _validate(name == id.name, |
+ "Package name $name doesn't match ${id.name}.", spec); |
packages[name] = id; |
}); |
@@ -90,6 +95,12 @@ class LockFile { |
return new LockFile._(packages); |
} |
+ /// If [condition] is `false` throws a format error with [message] for [node]. |
+ static void _validate(bool condition, String message, YamlNode node) { |
+ if (condition) return; |
+ throw new SpanFormatException(message, node.span); |
+ } |
+ |
/// Returns the serialized YAML text of the lock file. |
/// |
/// [packageDir] is the containing directory of the root package, used to |