Index: utils/pub/pubspec.dart |
diff --git a/utils/pub/pubspec.dart b/utils/pub/pubspec.dart |
deleted file mode 100644 |
index a5c67acc645900cb4055ac33ee32a6455917c312..0000000000000000000000000000000000000000 |
--- a/utils/pub/pubspec.dart |
+++ /dev/null |
@@ -1,302 +0,0 @@ |
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-library pubspec; |
- |
-import 'package:yaml/yaml.dart'; |
-import 'package:pathos/path.dart' as path; |
- |
-import 'io.dart'; |
-import 'package.dart'; |
-import 'source.dart'; |
-import 'source_registry.dart'; |
-import 'utils.dart'; |
-import 'version.dart'; |
- |
-/// The parsed and validated contents of a pubspec file. |
-class Pubspec { |
- /// This package's name. |
- final String name; |
- |
- /// This package's version. |
- final Version version; |
- |
- /// The packages this package depends on. |
- final List<PackageRef> dependencies; |
- |
- /// The packages this package depends on when it is the root package. |
- final List<PackageRef> devDependencies; |
- |
- /// The environment-related metadata. |
- final PubspecEnvironment environment; |
- |
- /// All pubspec fields. This includes the fields from which other properties |
- /// are derived. |
- final Map<String, Object> fields; |
- |
- /// Loads the pubspec for a package [name] located in [packageDir]. |
- factory Pubspec.load(String name, String packageDir, SourceRegistry sources) { |
- var pubspecPath = path.join(packageDir, 'pubspec.yaml'); |
- if (!fileExists(pubspecPath)) throw new PubspecNotFoundException(name); |
- |
- try { |
- var pubspec = new Pubspec.parse(pubspecPath, readTextFile(pubspecPath), |
- sources); |
- |
- if (pubspec.name == null) { |
- throw new PubspecHasNoNameException(name); |
- } |
- |
- if (name != null && pubspec.name != name) { |
- throw new PubspecNameMismatchException(name, pubspec.name); |
- } |
- |
- return pubspec; |
- } on FormatException catch (ex) { |
- fail('Could not parse $pubspecPath:\n${ex.message}'); |
- } |
- } |
- |
- Pubspec(this.name, this.version, this.dependencies, this.devDependencies, |
- this.environment, [Map<String, Object> fields]) |
- : this.fields = fields == null ? {} : fields; |
- |
- Pubspec.empty() |
- : name = null, |
- version = Version.none, |
- dependencies = <PackageRef>[], |
- devDependencies = <PackageRef>[], |
- environment = new PubspecEnvironment(), |
- fields = {}; |
- |
- /// Whether or not the pubspec has no contents. |
- bool get isEmpty => |
- name == null && version == Version.none && dependencies.isEmpty; |
- |
- // TODO(rnystrom): Instead of allowing a null argument here, split this up |
- // into load(), parse(), and _parse() like LockFile does. |
- /// Parses the pubspec stored at [filePath] whose text is [contents]. If the |
- /// pubspec doesn't define version for itself, it defaults to [Version.none]. |
- /// [filePath] may be `null` if the pubspec is not on the user's local |
- /// file system. |
- factory Pubspec.parse(String filePath, String contents, |
- SourceRegistry sources) { |
- var name = null; |
- var version = Version.none; |
- |
- if (contents.trim() == '') return new Pubspec.empty(); |
- |
- var parsedPubspec = loadYaml(contents); |
- if (parsedPubspec == null) return new Pubspec.empty(); |
- |
- if (parsedPubspec is! Map) { |
- throw new FormatException('The pubspec must be a YAML mapping.'); |
- } |
- |
- if (parsedPubspec.containsKey('name')) { |
- name = parsedPubspec['name']; |
- if (name is! String) { |
- throw new FormatException( |
- 'The pubspec "name" field should be a string, but was "$name".'); |
- } |
- } |
- |
- if (parsedPubspec.containsKey('version')) { |
- version = new Version.parse(parsedPubspec['version']); |
- } |
- |
- var dependencies = _parseDependencies(filePath, sources, |
- parsedPubspec['dependencies']); |
- |
- var devDependencies = _parseDependencies(filePath, sources, |
- parsedPubspec['dev_dependencies']); |
- |
- // Make sure the same package doesn't appear as both a regular and dev |
- // dependency. |
- var dependencyNames = dependencies.map((dep) => dep.name).toSet(); |
- var collisions = dependencyNames.intersection( |
- devDependencies.map((dep) => dep.name).toSet()); |
- |
- if (!collisions.isEmpty) { |
- var packageNames; |
- if (collisions.length == 1) { |
- packageNames = 'Package "${collisions.first}"'; |
- } else { |
- var names = collisions.toList(); |
- names.sort(); |
- var buffer = new StringBuffer(); |
- buffer.write("Packages "); |
- for (var i = 0; i < names.length; i++) { |
- buffer.write('"'); |
- buffer.write(names[i]); |
- buffer.write('"'); |
- if (i == names.length - 2) { |
- buffer.write(", "); |
- } else if (i == names.length - 1) { |
- buffer.write(", and "); |
- } |
- } |
- |
- packageNames = buffer.toString(); |
- } |
- throw new FormatException( |
- '$packageNames cannot appear in both "dependencies" and ' |
- '"dev_dependencies".'); |
- } |
- |
- var environmentYaml = parsedPubspec['environment']; |
- var sdkConstraint = VersionConstraint.any; |
- if (environmentYaml != null) { |
- if (environmentYaml is! Map) { |
- throw new FormatException( |
- 'The pubspec "environment" field should be a map, but was ' |
- '"$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); |
- } |
- var environment = new PubspecEnvironment(sdkConstraint); |
- |
- // Even though the pub app itself doesn't use these fields, we validate |
- // them here so that users find errors early before they try to upload to |
- // the server: |
- // TODO(rnystrom): We should split this validation into separate layers: |
- // 1. Stuff that is required in any pubspec to perform any command. Things |
- // like "must have a name". That should go here. |
- // 2. Stuff that is required to upload a package. Things like "homepage |
- // must use a valid scheme". That should go elsewhere. pub upload should |
- // call it, and we should provide a separate command to show the user, |
- // and also expose it to the editor in some way. |
- |
- if (parsedPubspec.containsKey('homepage')) { |
- _validateFieldUrl(parsedPubspec['homepage'], 'homepage'); |
- } |
- if (parsedPubspec.containsKey('documentation')) { |
- _validateFieldUrl(parsedPubspec['documentation'], 'documentation'); |
- } |
- |
- if (parsedPubspec.containsKey('author') && |
- parsedPubspec['author'] is! String) { |
- throw new FormatException( |
- 'The "author" field should be a string, but was ' |
- '${parsedPubspec["author"]}.'); |
- } |
- |
- if (parsedPubspec.containsKey('authors')) { |
- var authors = parsedPubspec['authors']; |
- if (authors is List) { |
- // All of the elements must be strings. |
- if (!authors.every((author) => author is String)) { |
- throw new FormatException('The "authors" field should be a string ' |
- 'or a list of strings, but was "$authors".'); |
- } |
- } else if (authors is! String) { |
- throw new FormatException('The pubspec "authors" field should be a ' |
- 'string or a list of strings, but was "$authors".'); |
- } |
- |
- if (parsedPubspec.containsKey('author')) { |
- throw new FormatException('A pubspec should not have both an "author" ' |
- 'and an "authors" field.'); |
- } |
- } |
- |
- return new Pubspec(name, version, dependencies, devDependencies, |
- environment, parsedPubspec); |
- } |
-} |
- |
-/** |
- * Evaluates whether the given [url] for [field] is valid. |
- * |
- * Throws [FormatException] on an invalid url. |
- */ |
-void _validateFieldUrl(url, String field) { |
- if (url is! String) { |
- throw new FormatException( |
- 'The "$field" field should be a string, but was "$url".'); |
- } |
- |
- var goodScheme = new RegExp(r'^https?:'); |
- if (!goodScheme.hasMatch(url)) { |
- throw new FormatException( |
- 'The "$field" field should be an "http:" or "https:" URL, but ' |
- 'was "$url".'); |
- } |
-} |
- |
-List<PackageRef> _parseDependencies(String pubspecPath, SourceRegistry sources, |
- yaml) { |
- var dependencies = <PackageRef>[]; |
- |
- // Allow an empty dependencies key. |
- if (yaml == null) return dependencies; |
- |
- if (yaml is! Map || yaml.keys.any((e) => e is! String)) { |
- throw new FormatException( |
- 'The pubspec dependencies should be a map of package names, but ' |
- 'was ${yaml}.'); |
- } |
- |
- yaml.forEach((name, spec) { |
- var description, source; |
- var versionConstraint = new VersionRange(); |
- if (spec == null) { |
- description = name; |
- source = sources.defaultSource; |
- } else if (spec is String) { |
- description = name; |
- source = sources.defaultSource; |
- versionConstraint = new VersionConstraint.parse(spec); |
- } else if (spec is Map) { |
- if (spec.containsKey('version')) { |
- versionConstraint = new VersionConstraint.parse(spec.remove('version')); |
- } |
- |
- var sourceNames = spec.keys.toList(); |
- if (sourceNames.length > 1) { |
- throw new FormatException( |
- 'Dependency $name may only have one source: $sourceNames.'); |
- } |
- |
- var sourceName = only(sourceNames); |
- if (sourceName is! String) { |
- throw new FormatException( |
- 'Source name $sourceName should be a string.'); |
- } |
- |
- source = sources[sourceName]; |
- description = spec[sourceName]; |
- } else { |
- throw new FormatException( |
- 'Dependency specification $spec should be a string or a mapping.'); |
- } |
- |
- description = source.parseDescription(pubspecPath, description, |
- fromLockFile: false); |
- |
- dependencies.add(new PackageRef( |
- name, source, versionConstraint, description)); |
- }); |
- |
- return dependencies; |
-} |
- |
-/// The environment-related metadata in the pubspec. Corresponds to the data |
-/// under the "environment:" key in the pubspec. |
-class PubspecEnvironment { |
- /// The version constraint specifying which SDK versions this package works |
- /// with. |
- final VersionConstraint sdkVersion; |
- |
- PubspecEnvironment([VersionConstraint sdk]) |
- : sdkVersion = sdk != null ? sdk : VersionConstraint.any; |
-} |