blob: 51f2460120e1b766b75c73bc0a4647da6cb86955 [file] [log] [blame]
// Copyright (c) 2019, 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.
/// This library defines how to read module dependencies from a Yaml
/// specification. We expect to find specifications written in this format:
///
/// dependencies:
/// b: a
/// main: [b, expect]
///
/// Where:
/// - Each name corresponds to a module.
/// - Module names correlate to either a file, a folder, or a package.
/// - A map entry contains all the dependencies of a module, if any.
/// - If a module has a single dependency, it can be written as a single
/// value.
///
/// The logic in this library mostly treats these names as strings, separately
/// `loader.dart` is responsible for validating and attaching this dependency
/// information to a set of module definitions.
import 'package:yaml/yaml.dart';
/// Parses [contents] containing a module dependencies specification written in
/// yaml, and returns a normalized dependency map.
///
/// Note: some values in the map may not have a corresponding key. That may be
/// the case for modules that have no dependencies and modules that are not
/// specified in [contents] (e.g. modules that are supported by default).
Map<String, List<String>> parseDependencyMap(String contents) {
var spec = loadYaml(contents);
if (spec is! YamlMap) {
return _invalidSpecification("spec is not a map");
}
var dependencies = spec['dependencies'];
if (dependencies == null) {
return _invalidSpecification("no dependencies section");
}
if (dependencies is! YamlMap) {
return _invalidSpecification("dependencies is not a map");
}
Map<String, List<String>> normalizedMap = {};
dependencies.forEach((key, value) {
if (key is! String) {
_invalidSpecification("key: '$key' is not a string");
}
normalizedMap[key] = [];
if (value is String) {
normalizedMap[key].add(value);
} else if (value is List) {
value.forEach((entry) {
if (entry is! String) {
_invalidSpecification("entry: '$entry' is not a string");
}
normalizedMap[key].add(entry);
});
} else {
_invalidSpecification(
"entry: '$value' is not a string or a list of strings");
}
});
return normalizedMap;
}
_invalidSpecification(String message) {
throw new InvalidSpecificationError(message);
}
class InvalidSpecificationError extends Error {
final String message;
InvalidSpecificationError(this.message);
String toString() => "Invalid specification: $message";
}