Index: pkg/analyzer_cli/lib/src/plugin/plugin_manager.dart |
diff --git a/pkg/analyzer_cli/lib/src/plugin/plugin_manager.dart b/pkg/analyzer_cli/lib/src/plugin/plugin_manager.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..13a820282af125a3086125529340321f779fe7e0 |
--- /dev/null |
+++ b/pkg/analyzer_cli/lib/src/plugin/plugin_manager.dart |
@@ -0,0 +1,110 @@ |
+// Copyright (c) 2015, 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 analyzer_cli.src.plugin.plugin_manager; |
+ |
+import 'dart:io'; |
+ |
+import 'package:analyzer/src/plugin/plugin_configuration.dart'; |
+import 'package:path/path.dart' as path; |
+ |
+const _manifestFileName = 'plugins.yaml'; |
+ |
+/// Given a local configuration (as defined in `.analysis_options`) |
+/// and information from a plugin manifest, return plugin info |
+/// appropriate for configuring this plugin. |
+PluginInfo combine(PluginInfo localConfig, PluginInfo manifestInfo) { |
+ return new PluginInfo( |
+ name: localConfig.name, |
+ version: manifestInfo.version, |
+ className: manifestInfo.className, |
+ libraryUri: manifestInfo.libraryUri); |
+} |
+ |
+/// Call-back to allow for the injection of manifest readers that do not need |
+/// to go to disk (for testing purposes). |
+typedef String ManifestReader(Uri uri); |
+ |
+/// Wraps a [plugin] info object elaborated with any configuration information |
+/// extracted from an associated manifest and [status]. |
+class PluginDetails { |
+ /// Plugin status. |
+ final PluginStatus status; |
+ |
+ /// Plugin info. |
+ final PluginInfo plugin; |
+ |
+ /// Wrap a [plugin] with [status] info. |
+ PluginDetails(this.plugin) : status = PluginStatus.Applicable; |
+ PluginDetails.notApplicable(this.plugin) |
+ : status = PluginStatus.NotApplicable; |
+ PluginDetails.notFound(this.plugin) : status = PluginStatus.NotFound; |
+} |
+ |
+/// Manages plugin information derived from plugin manifests. |
+class PluginManager { |
+ /// Mapping from package name to package location. |
+ final Map<String, Uri> _packageMap; |
+ |
+ /// The package naming the app to host plugins. |
+ final String hostPackage; |
+ |
+ /// Function to perform the reading of manifest URIs. (For testing.) |
+ ManifestReader _manifestReader; |
+ |
+ /// Create a plugin manager with backing package map information. |
+ PluginManager(this._packageMap, this.hostPackage, |
+ [ManifestReader manifestReader]) { |
+ _manifestReader = |
+ manifestReader != null ? manifestReader : _findAndReadManifestAtUri; |
+ } |
+ |
+ /// Find a plugin manifest describing the given [pluginPackage]. |
+ PluginManifest findManifest(String pluginPackage) { |
+ Uri uri = _packageMap[pluginPackage]; |
+ String contents = _manifestReader(uri); |
+ if (contents == null) { |
+ return null; |
+ } |
+ return parsePluginManifestString(contents); |
+ } |
+ |
+ /// Return [PluginDetails] derived from associated plugin manifests |
+ /// corresponding to plugins specified in the given [config]. |
+ Iterable<PluginDetails> getPluginDetails(PluginConfig config) => |
+ config.plugins.map((PluginInfo localConfig) { |
+ PluginManifest manifest = findManifest(localConfig.name); |
+ return _getDetails(localConfig, manifest); |
+ }); |
+ |
+ String _findAndReadManifestAtUri(Uri uri) { |
+ File manifestFile = _findManifest(uri); |
+ return manifestFile?.readAsStringSync(); |
+ } |
+ |
+ File _findManifest(Uri uri) { |
+ if (uri == null) { |
+ return null; |
+ } |
+ |
+ Directory directory = new Directory.fromUri(uri); |
+ File file = new File(path.join(directory.path, _manifestFileName)); |
+ |
+ return file.existsSync() ? file : null; |
+ } |
+ |
+ PluginDetails _getDetails(PluginInfo localConfig, PluginManifest manifest) { |
+ if (manifest == null) { |
+ return new PluginDetails.notFound(localConfig); |
+ } |
+ if (!manifest.contributesTo.contains(hostPackage)) { |
+ return new PluginDetails.notApplicable(localConfig); |
+ } |
+ |
+ return new PluginDetails(combine(localConfig, manifest.plugin)); |
+ } |
+} |
+ |
+/// Describes plugin status. |
+enum PluginStatus { Applicable, NotApplicable, NotFound } |