blob: 0ff02687f121394857c59fe521b02a9bd54a569c [file] [log] [blame]
// Copyright (c) 2017, 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.
import 'package:analyzer/file_system/file_system.dart';
/// An object used to locate a plugin within a package.
class PluginLocator {
/// The key used in the `pubspec.yaml` file to specify the location of the
/// analysis plugin.
static const String analyzerPluginKey = 'analyzer_plugin';
/// The name of the default plugin directory, located within the `tools`
/// directory.
static const String defaultPluginFolderName = 'analyzer_plugin';
/// The name of the `pubspec.yaml` file.
static const String pubspecFileName = 'pubspec.yaml';
/// The name of the `tools` directory, in which the default plugin directory
/// is located.
static const String toolsFolderName = 'tools';
/// The resource provider used to access the file system.
final ResourceProvider resourceProvider;
final Map<String, String> pluginMap = <String, String>{};
/// Initialize a newly created plugin locator to use the given
/// [resourceProvider] to access the file system.
PluginLocator(this.resourceProvider);
/// Given the root directory of a package (the [packageRoot]), return the path
/// to the plugin associated with the package, or `null` if there is no plugin
/// associated with the package.
///
/// This will look first in the `pubspec.yaml` file in the package root for a
/// top-level key (`analysis_plugin`) indicating where the plugin is located.
/// The value associated with the key is expected to be the path of the plugin
/// relative to the package root. If the directory exists, the it is returned.
///
/// If the key is not defined in the `pubspec.yaml` file, or if the directory
/// given does not exist, then this method will look for the directory
/// `tools/analysis_plugin` relative to the package root. If the directory
/// exists, then it is returned.
///
/// This method does not validate the content of the plugin directory before
/// returning it.
String findPlugin(String packageRoot) {
return pluginMap.putIfAbsent(packageRoot, () => _findPlugin(packageRoot));
}
/// The implementation of [findPlugin].
String _findPlugin(String packageRoot) {
var packageFolder = resourceProvider.getFolder(packageRoot);
// TODO(brianwilkerson) Re-enable this after deciding how we want to deal
// with discovery of plugins.
// import 'package:yaml/yaml.dart';
// File pubspecFile = packageFolder.getChildAssumingFile(pubspecFileName);
// if (pubspecFile.exists) {
// try {
// YamlDocument document = loadYamlDocument(pubspecFile.readAsStringSync(),
// sourceUrl: pubspecFile.toUri());
// YamlNode contents = document.contents;
// if (contents is YamlMap) {
// String pluginPath = contents[analyzerPluginKey];
// if (pluginPath != null) {
// Folder pluginFolder =
// packageFolder.getChildAssumingFolder(pluginPath);
// if (pluginFolder.exists) {
// return pluginFolder.path;
// }
// }
// }
// } catch (exception) {
// // If we can't read the file, or if it isn't valid YAML, then ignore it.
// }
// }
var pluginFolder = packageFolder
.getChildAssumingFolder(toolsFolderName)
.getChildAssumingFolder(defaultPluginFolderName);
if (pluginFolder.exists) {
return pluginFolder.path;
}
return null;
}
}