Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Unified Diff: sdk/lib/_internal/pub/lib/src/pubspec.dart

Issue 1165473002: Start pulling pub from its own repo. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Code review changes Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/_internal/pub/lib/src/progress.dart ('k') | sdk/lib/_internal/pub/lib/src/sdk.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/pub/lib/src/pubspec.dart
diff --git a/sdk/lib/_internal/pub/lib/src/pubspec.dart b/sdk/lib/_internal/pub/lib/src/pubspec.dart
deleted file mode 100644
index 13cce16e8583318ce3f61ca8121b01cc9d44a891..0000000000000000000000000000000000000000
--- a/sdk/lib/_internal/pub/lib/src/pubspec.dart
+++ /dev/null
@@ -1,583 +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 pub.pubspec;
-
-import 'package:path/path.dart' as path;
-import 'package:pub_semver/pub_semver.dart';
-import 'package:source_span/source_span.dart';
-import 'package:yaml/yaml.dart';
-
-import 'barback/transformer_config.dart';
-import 'exceptions.dart';
-import 'io.dart';
-import 'package.dart';
-import 'source_registry.dart';
-import 'utils.dart';
-
-/// The parsed contents of a pubspec file.
-///
-/// The fields of a pubspec are, for the most part, validated when they're first
-/// accessed. This allows a partially-invalid pubspec to be used if only the
-/// valid portions are relevant. To get a list of all errors in the pubspec, use
-/// [allErrors].
-class Pubspec {
- // If a new lazily-initialized field is added to this class and the
- // initialization can throw a [PubspecException], that error should also be
- // exposed through [allErrors].
-
- /// The registry of sources to use when parsing [dependencies] and
- /// [devDependencies].
- ///
- /// This will be null if this was created using [new Pubspec] or [new
- /// Pubspec.empty].
- final SourceRegistry _sources;
-
- /// The location from which the pubspec was loaded.
- ///
- /// This can be null if the pubspec was created in-memory or if its location
- /// is unknown.
- Uri get _location => fields.span.sourceUrl;
-
- /// All pubspec fields.
- ///
- /// This includes the fields from which other properties are derived.
- final YamlMap fields;
-
- /// The package's name.
- String get name {
- if (_name != null) return _name;
-
- var name = fields['name'];
- if (name == null) {
- throw new PubspecException(
- 'Missing the required "name" field.', fields.span);
- } else if (name is! String) {
- throw new PubspecException(
- '"name" field must be a string.', fields.nodes['name'].span);
- }
-
- _name = name;
- return _name;
- }
- String _name;
-
- /// The package's version.
- Version get version {
- if (_version != null) return _version;
-
- var version = fields['version'];
- if (version == null) {
- _version = Version.none;
- return _version;
- }
-
- var span = fields.nodes['version'].span;
- if (version is num) {
- var fixed = '$version.0';
- if (version is int) {
- fixed = '$fixed.0';
- }
- _error('"version" field must have three numeric components: major, '
- 'minor, and patch. Instead of "$version", consider "$fixed".', span);
- }
- if (version is! String) {
- _error('"version" field must be a string.', span);
- }
-
- _version = _wrapFormatException('version number', span,
- () => new Version.parse(version));
- return _version;
- }
- Version _version;
-
- /// The additional packages this package depends on.
- List<PackageDep> get dependencies {
- if (_dependencies != null) return _dependencies;
- _dependencies = _parseDependencies('dependencies');
- _checkDependencyOverlap(_dependencies, _devDependencies);
- return _dependencies;
- }
- List<PackageDep> _dependencies;
-
- /// The packages this package depends on when it is the root package.
- List<PackageDep> get devDependencies {
- if (_devDependencies != null) return _devDependencies;
- _devDependencies = _parseDependencies('dev_dependencies');
- _checkDependencyOverlap(_dependencies, _devDependencies);
- return _devDependencies;
- }
- List<PackageDep> _devDependencies;
-
- /// The dependency constraints that this package overrides when it is the
- /// root package.
- ///
- /// Dependencies here will replace any dependency on a package with the same
- /// name anywhere in the dependency graph.
- List<PackageDep> get dependencyOverrides {
- if (_dependencyOverrides != null) return _dependencyOverrides;
- _dependencyOverrides = _parseDependencies('dependency_overrides');
- return _dependencyOverrides;
- }
- List<PackageDep> _dependencyOverrides;
-
- /// The configurations of the transformers to use for this package.
- List<Set<TransformerConfig>> get transformers {
- if (_transformers != null) return _transformers;
-
- var transformers = fields['transformers'];
- if (transformers == null) {
- _transformers = [];
- return _transformers;
- }
-
- if (transformers is! List) {
- _error('"transformers" field must be a list.',
- fields.nodes['transformers'].span);
- }
-
- _transformers = transformers.nodes.map((phase) {
- var phaseNodes = phase is YamlList ? phase.nodes : [phase];
- return phaseNodes.map((transformerNode) {
- var transformer = transformerNode.value;
- if (transformer is! String && transformer is! Map) {
- _error('A transformer must be a string or map.',
- transformerNode.span);
- }
-
- var libraryNode;
- var configurationNode;
- if (transformer is String) {
- libraryNode = transformerNode;
- } else {
- if (transformer.length != 1) {
- _error('A transformer map must have a single key: the transformer '
- 'identifier.', transformerNode.span);
- } else if (transformer.keys.single is! String) {
- _error('A transformer identifier must be a string.',
- transformer.nodes.keys.single.span);
- }
-
- libraryNode = transformer.nodes.keys.single;
- configurationNode = transformer.nodes.values.single;
- if (configurationNode is! YamlMap) {
- _error("A transformer's configuration must be a map.",
- configurationNode.span);
- }
- }
-
- var config = _wrapSpanFormatException('transformer config', () {
- return new TransformerConfig.parse(
- libraryNode.value, libraryNode.span,
- configurationNode);
- });
-
- var package = config.id.package;
- if (package != name &&
- !config.id.isBuiltInTransformer &&
- !dependencies.any((ref) => ref.name == package) &&
- !devDependencies.any((ref) => ref.name == package) &&
- !dependencyOverrides.any((ref) => ref.name == package)) {
- _error('"$package" is not a dependency.',
- libraryNode.span);
- }
-
- return config;
- }).toSet();
- }).toList();
-
- return _transformers;
- }
- List<Set<TransformerConfig>> _transformers;
-
- /// The environment-related metadata.
- PubspecEnvironment get environment {
- if (_environment != null) return _environment;
-
- var yaml = fields['environment'];
- if (yaml == null) {
- _environment = new PubspecEnvironment(VersionConstraint.any);
- return _environment;
- }
-
- if (yaml is! Map) {
- _error('"environment" field must be a map.',
- fields.nodes['environment'].span);
- }
-
- _environment = new PubspecEnvironment(
- _parseVersionConstraint(yaml.nodes['sdk']));
- return _environment;
- }
- PubspecEnvironment _environment;
-
- /// The URL of the server that the package should default to being published
- /// to, "none" if the package should not be published, or `null` if it should
- /// be published to the default server.
- ///
- /// If this does return a URL string, it will be a valid parseable URL.
- String get publishTo {
- if (_parsedPublishTo) return _publishTo;
-
- var publishTo = fields['publish_to'];
- if (publishTo != null) {
- var span = fields.nodes['publish_to'].span;
-
- if (publishTo is! String) {
- _error('"publish_to" field must be a string.', span);
- }
-
- // It must be "none" or a valid URL.
- if (publishTo != "none") {
- _wrapFormatException('"publish_to" field', span,
- () => Uri.parse(publishTo));
- }
- }
-
- _parsedPublishTo = true;
- _publishTo = publishTo;
- return _publishTo;
- }
- bool _parsedPublishTo = false;
- String _publishTo;
-
- /// The executables that should be placed on the user's PATH when this
- /// package is globally activated.
- ///
- /// It is a map of strings to string. Each key is the name of the command
- /// that will be placed on the user's PATH. The value is the name of the
- /// .dart script (without extension) in the package's `bin` directory that
- /// should be run for that command. Both key and value must be "simple"
- /// strings: alphanumerics, underscores and hypens only. If a value is
- /// omitted, it is inferred to use the same name as the key.
- Map<String, String> get executables {
- if (_executables != null) return _executables;
-
- _executables = {};
- var yaml = fields['executables'];
- if (yaml == null) return _executables;
-
- if (yaml is! Map) {
- _error('"executables" field must be a map.',
- fields.nodes['executables'].span);
- }
-
- yaml.nodes.forEach((key, value) {
- if (key.value is! String) {
- _error('"executables" keys must be strings.', key.span);
- }
-
- final keyPattern = new RegExp(r"^[a-zA-Z0-9_-]+$");
- if (!keyPattern.hasMatch(key.value)) {
- _error('"executables" keys may only contain letters, '
- 'numbers, hyphens and underscores.', key.span);
- }
-
- if (value.value == null) {
- value = key;
- } else if (value.value is! String) {
- _error('"executables" values must be strings or null.', value.span);
- }
-
- final valuePattern = new RegExp(r"[/\\]");
- if (valuePattern.hasMatch(value.value)) {
- _error('"executables" values may not contain path separators.',
- value.span);
- }
-
- _executables[key.value] = value.value;
- });
-
- return _executables;
- }
- Map<String, String> _executables;
-
- /// Whether the package is private and cannot be published.
- ///
- /// This is specified in the pubspec by setting "publish_to" to "none".
- bool get isPrivate => publishTo == "none";
-
- /// Whether or not the pubspec has no contents.
- bool get isEmpty =>
- name == null && version == Version.none && dependencies.isEmpty;
-
- /// Loads the pubspec for a package located in [packageDir].
- ///
- /// If [expectedName] is passed and the pubspec doesn't have a matching name
- /// field, this will throw a [PubspecError].
- factory Pubspec.load(String packageDir, SourceRegistry sources,
- {String expectedName}) {
- var pubspecPath = path.join(packageDir, 'pubspec.yaml');
- var pubspecUri = path.toUri(pubspecPath);
- if (!fileExists(pubspecPath)) {
- throw new FileException(
- 'Could not find a file named "pubspec.yaml" in "$packageDir".',
- pubspecPath);
- }
-
- return new Pubspec.parse(readTextFile(pubspecPath), sources,
- expectedName: expectedName, location: pubspecUri);
- }
-
- Pubspec(this._name, {Version version, Iterable<PackageDep> dependencies,
- Iterable<PackageDep> devDependencies,
- Iterable<PackageDep> dependencyOverrides,
- VersionConstraint sdkConstraint,
- Iterable<Iterable<TransformerConfig>> transformers,
- Map fields, SourceRegistry sources})
- : _version = version,
- _dependencies = dependencies == null ? null : dependencies.toList(),
- _devDependencies = devDependencies == null ? null :
- devDependencies.toList(),
- _dependencyOverrides = dependencyOverrides == null ? null :
- dependencyOverrides.toList(),
- _environment = new PubspecEnvironment(sdkConstraint),
- _transformers = transformers == null ? [] :
- transformers.map((phase) => phase.toSet()).toList(),
- fields = fields == null ? new YamlMap() : new YamlMap.wrap(fields),
- _sources = sources;
-
- Pubspec.empty()
- : _sources = null,
- _name = null,
- _version = Version.none,
- _dependencies = <PackageDep>[],
- _devDependencies = <PackageDep>[],
- _environment = new PubspecEnvironment(),
- _transformers = <Set<TransformerConfig>>[],
- fields = new YamlMap();
-
- /// Returns a Pubspec object for an already-parsed map representing its
- /// contents.
- ///
- /// If [expectedName] is passed and the pubspec doesn't have a matching name
- /// field, this will throw a [PubspecError].
- ///
- /// [location] is the location from which this pubspec was loaded.
- Pubspec.fromMap(Map fields, this._sources, {String expectedName,
- Uri location})
- : fields = fields is YamlMap ? fields :
- new YamlMap.wrap(fields, sourceUrl: location) {
- // If [expectedName] is passed, ensure that the actual 'name' field exists
- // and matches the expectation.
- if (expectedName == null) return;
- if (name == expectedName) return;
-
- throw new PubspecException('"name" field doesn\'t match expected name '
- '"$expectedName".', this.fields.nodes["name"].span);
- }
-
- /// Parses the pubspec stored at [filePath] whose text is [contents].
- ///
- /// If the pubspec doesn't define a version for itself, it defaults to
- /// [Version.none].
- factory Pubspec.parse(String contents, SourceRegistry sources,
- {String expectedName, Uri location}) {
- var pubspecNode = loadYamlNode(contents, sourceUrl: location);
- if (pubspecNode is YamlScalar && pubspecNode.value == null) {
- pubspecNode = new YamlMap(sourceUrl: location);
- } else if (pubspecNode is! YamlMap) {
- throw new PubspecException(
- 'The pubspec must be a YAML mapping.', pubspecNode.span);
- }
-
- return new Pubspec.fromMap(pubspecNode, sources,
- expectedName: expectedName, location: location);
- }
-
- /// Returns a list of most errors in this pubspec.
- ///
- /// This will return at most one error for each field.
- List<PubspecException> get allErrors {
- var errors = <PubspecException>[];
- _getError(fn()) {
- try {
- fn();
- } on PubspecException catch (e) {
- errors.add(e);
- }
- }
-
- _getError(() => this.name);
- _getError(() => this.version);
- _getError(() => this.dependencies);
- _getError(() => this.devDependencies);
- _getError(() => this.transformers);
- _getError(() => this.environment);
- _getError(() => this.publishTo);
- return errors;
- }
-
- /// Parses the dependency field named [field], and returns the corresponding
- /// list of dependencies.
- List<PackageDep> _parseDependencies(String field) {
- var dependencies = <PackageDep>[];
-
- var yaml = fields[field];
- // Allow an empty dependencies key.
- if (yaml == null) return dependencies;
-
- if (yaml is! Map) {
- _error('"$field" field must be a map.', fields.nodes[field].span);
- }
-
- var nonStringNode = yaml.nodes.keys.firstWhere((e) => e.value is! String,
- orElse: () => null);
- if (nonStringNode != null) {
- _error('A dependency name must be a string.', nonStringNode.span);
- }
-
- yaml.nodes.forEach((nameNode, specNode) {
- var name = nameNode.value;
- var spec = specNode.value;
- if (fields['name'] != null && name == this.name) {
- _error('A package may not list itself as a dependency.',
- nameNode.span);
- }
-
- var descriptionNode;
- var sourceName;
-
- var versionConstraint = new VersionRange();
- if (spec == null) {
- descriptionNode = nameNode;
- sourceName = _sources.defaultSource.name;
- } else if (spec is String) {
- descriptionNode = nameNode;
- sourceName = _sources.defaultSource.name;
- versionConstraint = _parseVersionConstraint(specNode);
- } else if (spec is Map) {
- // Don't write to the immutable YAML map.
- spec = new Map.from(spec);
-
- if (spec.containsKey('version')) {
- spec.remove('version');
- versionConstraint = _parseVersionConstraint(
- specNode.nodes['version']);
- }
-
- var sourceNames = spec.keys.toList();
- if (sourceNames.length > 1) {
- _error('A dependency may only have one source.', specNode.span);
- }
-
- sourceName = sourceNames.single;
- if (sourceName is! String) {
- _error('A source name must be a string.',
- specNode.nodes.keys.single.span);
- }
-
- descriptionNode = specNode.nodes[sourceName];
- } else {
- _error('A dependency specification must be a string or a mapping.',
- specNode.span);
- }
-
- // Let the source validate the description.
- var description = _wrapFormatException('description',
- descriptionNode.span, () {
- var pubspecPath;
- if (_location != null && _isFileUri(_location)) {
- pubspecPath = path.fromUri(_location);
- }
-
- return _sources[sourceName].parseDescription(
- pubspecPath, descriptionNode.value, fromLockFile: false);
- });
-
- dependencies.add(new PackageDep(
- name, sourceName, versionConstraint, description));
- });
-
- return dependencies;
- }
-
- /// Parses [node] to a [VersionConstraint].
- VersionConstraint _parseVersionConstraint(YamlNode node) {
- if (node.value == null) return VersionConstraint.any;
- if (node.value is! String) {
- _error('A version constraint must be a string.', node.span);
- }
-
- return _wrapFormatException('version constraint', node.span,
- () => new VersionConstraint.parse(node.value));
- }
-
- /// Makes sure the same package doesn't appear as both a regular and dev
- /// dependency.
- void _checkDependencyOverlap(List<PackageDep> dependencies,
- List<PackageDep> devDependencies) {
- if (dependencies == null) return;
- if (devDependencies == null) return;
-
- var dependencyNames = dependencies.map((dep) => dep.name).toSet();
- var collisions = dependencyNames.intersection(
- devDependencies.map((dep) => dep.name).toSet());
- if (collisions.isEmpty) return;
-
- var span = fields["dependencies"].nodes.keys
- .firstWhere((key) => collisions.contains(key.value)).span;
-
- // TODO(nweiz): associate source range info with PackageDeps and use it
- // here.
- _error('${pluralize('Package', collisions.length)} '
- '${toSentence(collisions.map((package) => '"$package"'))} cannot '
- 'appear in both "dependencies" and "dev_dependencies".',
- span);
- }
-
- /// Runs [fn] and wraps any [FormatException] it throws in a
- /// [PubspecException].
- ///
- /// [description] should be a noun phrase that describes whatever's being
- /// parsed or processed by [fn]. [span] should be the location of whatever's
- /// being processed within the pubspec.
- _wrapFormatException(String description, SourceSpan span, fn()) {
- try {
- return fn();
- } on FormatException catch (e) {
- _error('Invalid $description: ${e.message}', span);
- }
- }
-
- _wrapSpanFormatException(String description, fn()) {
- try {
- return fn();
- } on SourceSpanFormatException catch (e) {
- _error('Invalid $description: ${e.message}', e.span);
- }
- }
-
- /// Throws a [PubspecException] with the given message.
- void _error(String message, SourceSpan span) {
- throw new PubspecException(message, span);
- }
-}
-
-/// 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;
-}
-
-/// An exception thrown when parsing a pubspec.
-///
-/// These exceptions are often thrown lazily while accessing pubspec properties.
-class PubspecException extends SourceSpanFormatException
- implements ApplicationException {
- PubspecException(String message, SourceSpan span)
- : super(message, span);
-}
-
-/// Returns whether [uri] is a file URI.
-///
-/// This is slightly more complicated than just checking if the scheme is
-/// 'file', since relative URIs also refer to the filesystem on the VM.
-bool _isFileUri(Uri uri) => uri.scheme == 'file' || uri.scheme == '';
« no previous file with comments | « sdk/lib/_internal/pub/lib/src/progress.dart ('k') | sdk/lib/_internal/pub/lib/src/sdk.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698