| # Package Structure | |
| Plugins are used by tools that want to allow external contributions to the | |
| results being produced by that tool. At the moment, the analysis server is the | |
| only tool that supports plugins, but we intend to add plugin support to the | |
| command-line analyzer and possibly other tools as well. For that reason, | |
| throughout this document we will generically refer to the tool running the | |
| plugins as simply the _tool_. | |
| In order to describe the way tools use plugins, we need to refer to four | |
| different packages. In order to keep the discussion clear, we will refer to | |
| those packages as the target package, the host package, the bootstrap package, | |
| and the plugin package. (If you're not familiar with packages, you should read | |
| about the Dart [package manager][pub].) | |
| The _target package_ is the package for which the tool is producing analysis | |
| results. If the tool is the analysis server, this is a package that the user has | |
| opened in the client and is actively developing. | |
| The _host package_ is a package that contains the information necessary to find | |
| and run the plugin. Specifically, the host package contains the bootstrap | |
| package. In order for the tool to find and use the host package, the target | |
| package must have a dependency on the host package. This can be either a normal | |
| dependency or a dev dependency. | |
| The _bootstrap package_ is a small package embedded within the host package that | |
| is used to load the plugin package. | |
| The _plugin package_ is the package that contains the actual implementation of | |
| the plugin. | |
| While you could technically merge the bootstrap and plugin packages, we | |
| recommend this structure because it minimizes the number of additional files | |
| that need to be downloaded by users who do not choose to enable the hosted | |
| plugin. | |
| As a concrete example, the angular package has a plugin associated with it. In | |
| order to implement this, the angular package has a bootstrap package embedded | |
| within it. When a target package (a package implementing a web app) has a | |
| dependency on the angular package, it can list 'angular' as an approved host | |
| package and the angular plugin will be run. | |
| ## Plugin Discovery | |
| Plugins are used by a tool to analyze the target package only if the tool is | |
| explicitly told to run them. Tools look for a list of approved host packages in | |
| the analysis options file (`analysis_options.yaml`) associated with the target | |
| package. The list has the form: | |
| ```yaml | |
| analyzer: | |
| plugins: | |
| - host_package_1 | |
| - host_package_2 | |
| ``` | |
| If a listed host package can be found (via the `.packages` file associated with | |
| the target package), then the tool looks in the host package for the folder | |
| `<host_package>/tools/analyzer_plugin`. If that directory exists and contains a | |
| valid bootstrap package, then the bootstrap package is run as a plugin. | |
| ## Bootstrap Package Structure | |
| The other packages described above can have any valid package structure, but the | |
| bootstrap package is required to have two specific files. | |
| First, it must have a file named `tools/analyzer_plugin/pubspec.yaml` that can | |
| be used by the [`pub`][pub] command to produce a `.packages` file describing how | |
| to resolve the `package:` URIs found in it. Typically, the only dependency that | |
| needs to be included is a dependency on the plugin package. | |
| Second, it must have a file named `tools/analyzer_plugin/bin/plugin.dart` that | |
| contains the entry point for the plugin. Every plugin will be run in a separate | |
| isolate. As a result, the entry point must have the following signature: | |
| ```dart | |
| void main(List<String> args, SendPort sendPort) { | |
| // Invoke the real main method in the plugin package. | |
| } | |
| ``` | |
| The body of `main` should typically be a single line that invokes a method or | |
| function within the plugin package that will create and start the plugin. | |
| ## Plugin Execution | |
| When a bootstrap package is to be run, the contents of the directory containing | |
| the bootstrap package are copied to a temporary directory, the [`pub`][pub] | |
| command is run in that directory to produce a `.packages` file for the bootstrap | |
| package, and the file `tools/analyzer_plugin/bin/plugin.dart` is run in its own | |
| isolate. | |
| [pub]: https://dart.dev/guides/packages |