diff --git a/lib/src/pubspec.dart b/lib/src/pubspec.dart index 6da96ba621cc6f2456a9a5bc41e00cc99bd0ac71..df7ebd93a349fe20ea8f8f4e84f4af605e59b990 100644 --- a/lib/src/pubspec.dart +++ b/lib/src/pubspec.dart @@ -121,7 +121,6 @@ void _validateFieldUrl(url, String field) { Pubspec _parseMap(String filePath, Map map, SourceRegistry sources) { var name = null; - var version = Version.none; if (map.containsKey('name')) { name = map['name']; @@ -131,9 +130,9 @@ Pubspec _parseMap(String filePath, Map map, SourceRegistry sources) { } } - if (map.containsKey('version')) { - version = new Version.parse(map['version']); - } + var version = _parseVersion(map['version'], (v) => + 'The pubspec "version" field should be a semantic version number, ' + 'but was "$v".'); var dependencies = _parseDependencies(filePath, sources, map['dependencies']); @@ -183,14 +182,9 @@ Pubspec _parseMap(String filePath, Map map, SourceRegistry sources) { '"$environmentYaml".'); } - var sdkYaml = environmentYaml['sdk']; - if (sdkYaml is! String) { - throw new FormatException( - 'The "sdk" field of "environment" should be a string, but was ' - '"$sdkYaml".'); - } - - sdkConstraint = new VersionConstraint.parse(sdkYaml); + sdkConstraint = _parseVersionConstraint(environmentYaml['sdk'], (v) => + 'The "sdk" field of "environment" should be a semantic version ' + 'constraint, but was "$v".'); } var environment = new PubspecEnvironment(sdkConstraint); @@ -241,6 +235,36 @@ Pubspec _parseMap(String filePath, Map map, SourceRegistry sources) { environment, map); } +/// Parses [yaml] to a [Version] or throws a [FormatException] with the result +/// of calling [message] if it isn't valid. +/// +/// If [yaml] is `null`, returns [Version.none]. +Version _parseVersion(yaml, String message(yaml)) { + if (yaml == null) return Version.none; + if (yaml is! String) throw new FormatException(message(yaml)); + + try { + return new Version.parse(yaml); + } on FormatException catch(_) { + throw new FormatException(message(yaml)); + } +} + +/// Parses [yaml] to a [VersionConstraint] or throws a [FormatException] with +/// the result of calling [message] if it isn't valid. +/// +/// If [yaml] is `null`, returns [VersionConstraint.any]. +VersionConstraint _parseVersionConstraint(yaml, String getMessage(yaml)) { + if (yaml == null) return VersionConstraint.any; + if (yaml is! String) throw new FormatException(getMessage(yaml)); + + try { + return new VersionConstraint.parse(yaml); + } on FormatException catch(_) { + throw new FormatException(getMessage(yaml)); + } +} + List<PackageDep> _parseDependencies(String pubspecPath, SourceRegistry sources, yaml) { var dependencies = <PackageDep>[]; @@ -268,7 +292,9 @@ List<PackageDep> _parseDependencies(String pubspecPath, SourceRegistry sources, versionConstraint = new VersionConstraint.parse(spec); } else if (spec is Map) { if (spec.containsKey('version')) { - versionConstraint = new VersionConstraint.parse(spec.remove('version')); + versionConstraint = _parseVersionConstraint(spec.remove('version'), + (v) => 'The "version" field for $name should be a semantic ' + 'version constraint, but was "$v".'); } var sourceNames = spec.keys.toList(); diff --git a/test/pubspec_test.dart b/test/pubspec_test.dart index 47f838a0a7f2fb895a1e9e4f8ac3ce7e6c6748bf..e7608b4cfc375908fd99a6d71b58439d4ac6c997 100644 --- a/test/pubspec_test.dart +++ b/test/pubspec_test.dart @@ -111,10 +111,40 @@ dependencies: '''); }); + test("throws if dependency version is not a string", () { + expectFormatError(''' +dependencies: + foo: + mock: ok + version: 1.2 +'''); + }); + + test("throws if version is not a version constraint", () { + expectFormatError(''' +dependencies: + foo: + mock: ok + version: not constraint +'''); + }); + test("throws if 'name' is not a string", () { expectFormatError('name: [not, a, string]'); }); + test("throws if version is not a string", () { + expectFormatError(''' +version: 1.0 +'''); + }); + + test("throws if version is not a version", () { + expectFormatError(''' +version: not version +'''); + }); + test("throws if 'homepage' is not a string", () { expectFormatError('homepage:'); expectFormatError('homepage: [not, a, string]'); @@ -212,6 +242,13 @@ environment: '''); }); + test("throws if the sdk is not a string", () { + expectFormatError(''' +environment: + sdk: 1.0 +'''); + }); + test("throws if the sdk isn't a valid version constraint", () { expectFormatError(''' environment: