7b72bd1b8d
This fixes a race condition in r9767 caused by issue 4155. Review URL: https://chromiumcodereview.appspot.com//10790079 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@9824 260f80e4-7a28-3924-810f-c04153c831b5
108 lines
3.2 KiB
Dart
108 lines
3.2 KiB
Dart
// 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.dart');
|
|
#import('source.dart');
|
|
#import('source_registry.dart');
|
|
#import('utils.dart');
|
|
#import('version.dart');
|
|
#import('yaml/yaml.dart');
|
|
|
|
/**
|
|
* The parsed and validated contents of a pubspec file.
|
|
*/
|
|
class Pubspec {
|
|
/**
|
|
* This package's version.
|
|
*/
|
|
final Version version;
|
|
|
|
/**
|
|
* The packages this package depends on.
|
|
*/
|
|
List<PackageRef> dependencies;
|
|
|
|
Pubspec(this.version, this.dependencies);
|
|
|
|
Pubspec.empty()
|
|
: version = Version.none,
|
|
dependencies = <PackageRef>[];
|
|
|
|
/**
|
|
* Parses the pubspec whose text is [contents]. If the pubspec doesn't define
|
|
* version for itself, it defaults to [Version.none].
|
|
*/
|
|
factory Pubspec.parse(String contents, SourceRegistry sources) {
|
|
var version = Version.none;
|
|
var dependencies = <PackageRef>[];
|
|
|
|
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('version')) {
|
|
version = new Version.parse(parsedPubspec['version']);
|
|
}
|
|
|
|
if (parsedPubspec.containsKey('dependencies')) {
|
|
var dependencyEntries = parsedPubspec['dependencies'];
|
|
if (dependencyEntries is! Map ||
|
|
dependencyEntries.getKeys().some((e) => e is! String)) {
|
|
throw new FormatException(
|
|
'The pubspec dependencies must be a map of package names.');
|
|
}
|
|
|
|
dependencyEntries.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.getKeys();
|
|
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 must be a string.');
|
|
}
|
|
|
|
source = sources[sourceName];
|
|
description = spec[sourceName];
|
|
} else {
|
|
throw new FormatException(
|
|
'Dependency specification $spec must be a string or a mapping.');
|
|
}
|
|
|
|
source.validateDescription(description, fromLockFile: false);
|
|
|
|
dependencies.add(new PackageRef(
|
|
source, versionConstraint, description));
|
|
});
|
|
}
|
|
|
|
return new Pubspec(version, dependencies);
|
|
}
|
|
}
|