fromYamlMap static method
ToolConfiguration
fromYamlMap(
- YamlMap yamlMap,
- String canonicalYamlPath,
- ResourceProvider resourceProvider
Implementation
static ToolConfiguration fromYamlMap(YamlMap yamlMap,
String canonicalYamlPath, ResourceProvider resourceProvider) {
var newToolDefinitions = <String, ToolDefinition>{};
var pathContext = resourceProvider.pathContext;
for (var MapEntry(:key, value: toolMap) in yamlMap.entries) {
var name = key.toString();
if (toolMap is! Map) {
throw DartdocOptionError(
'Tools must be defined as a map of tool names to definitions. Tool '
'$name is not a map.');
}
var description = toolMap['description'].toString();
List<String>? findCommand([String prefix = '']) {
// If the command key is given, then it applies to all platforms.
var commandFromKey = toolMap.containsKey('${prefix}command')
? '${prefix}command'
: '$prefix${Platform.operatingSystem}';
if (!toolMap.containsKey(commandFromKey)) {
return null;
}
var commandFrom = toolMap[commandFromKey] as YamlNode;
List<String> command;
if (commandFrom.value is String) {
command = [commandFrom.toString()];
} else if (commandFrom is YamlList) {
command = commandFrom.map((node) => node.toString()).toList();
} else {
throw DartdocOptionError(
'Tool commands must be a path to an executable, or a list of '
'strings that starts with a path to an executable. The tool '
"'$name' has a '$commandFromKey' entry that is a "
'${commandFrom.runtimeType}');
}
if (command.isEmpty || command[0].isEmpty) {
throw DartdocOptionError(
'Tool commands must not be empty. Tool $name command entry '
'"$commandFromKey" must contain at least one path.');
}
return command;
}
var command = findCommand();
if (command == null) {
throw DartdocOptionError(
'At least one of "command" or "${Platform.operatingSystem}" must '
'be defined for the tool $name.');
}
var setupCommand = findCommand('setup_');
var rawCompileArgs = toolMap[compileArgsTagName];
var compileArgs = switch (rawCompileArgs) {
null => const <String>[],
String() => [toolMap[compileArgsTagName].toString()],
YamlList() =>
rawCompileArgs.map((node) => node.toString()).toList(growable: false),
_ => throw DartdocOptionError(
'Tool compile arguments must be a list of strings. The tool '
"'$name' has a '$compileArgsTagName' entry that is a "
'${rawCompileArgs.runtimeType}',
),
};
/// Validates [executable] and returns whether it is a Dart script.
bool isDartScript(String executable) {
var executableFile = resourceProvider.getFile(executable);
if (resourceProvider.isNotFound(executableFile)) {
throw DartdocOptionError('Command executables must exist. '
'The file "$executable" does not exist for tool $name.');
}
var isDartCommand = ToolDefinition.isDartExecutable(executable);
// Dart scripts don't need to be executable, because they'll be
// executed with the Dart binary.
if (!isDartCommand && !resourceProvider.isExecutable(executableFile)) {
throw DartdocOptionError('Non-Dart commands must be '
'executable. The file "$executable" for tool $name does not have '
'execute permission.');
}
return isDartCommand;
}
var executableRelativePath = command.removeAt(0);
var executable = pathContext.canonicalize(
pathContext.join(canonicalYamlPath, executableRelativePath));
var isDartSetupScript = isDartScript(executable);
if (setupCommand != null) {
var setupExecutableRelativePath = setupCommand.removeAt(0);
var setupExecutable = pathContext.canonicalize(
pathContext.join(canonicalYamlPath, setupExecutableRelativePath));
// Setup commands aren't snapshotted, since they're only run once.
setupCommand = [
if (isDartSetupScript) Platform.resolvedExecutable,
setupExecutable,
...setupCommand,
];
}
newToolDefinitions[name] = ToolDefinition.fromCommand(
[executable, ...command],
setupCommand ?? const [],
description,
resourceProvider,
compileArgs: compileArgs);
}
return ToolConfiguration._(newToolDefinitions, resourceProvider);
}