What's the spec on when PluginManager picks up pubspec changes to an analyzer_plugin?

45 views
Skip to first unread message

Patt O'Brien

unread,
Aug 31, 2022, 5:46:58 PM8/31/22
to Dart Analyzer Discussion
Hi all,

I'm working on an analyzer plugin, and I've been having trouble figuring out any reproducible steps to get the files in the following path to update:

~/.dartServer/.plugin_manager/<some-string>/analyzer_plugin/

This is making a part of my analyzer plugin's development difficult, and I'm uncertain if this would be an issue if this plugin would be used in others' projects. TLDR: the architecture of my plugin involves programatically modifying the pubspec file of the plugin loader any time my plugin is added to a user's project, so if there's no reliable way of knowing when the plugin loader files are updated in the above path, then this may be a blocker.

FWIW, I deleted one of the folders in the .plugin_manager file, and then tried to get it to reappear by cleaning files, removing pubspec.lock files, removing the plugin from pubspec and re-adding it... Nothing has triggered the plugin loader package to reappear in .plugin_manager.

Any help would be greatly appreciated; thanks!

Patt


Brian Wilkerson

unread,
Sep 1, 2022, 1:02:28 PM9/1/22
to Dart Analyzer Discussion
Thanks for the question; I wish I had a better answer for you.

The plugin support is currently an unsupported experiment. It has been useful for a few intrepid developers, but it definitely isn't a polished product.

As currently designed, it is expected that a given version of a plugin won't change. As a result, after it's been downloaded to `.plugin_manager` it won't be downloaded or updated again.

It sounds like the current proof-of-concept prototype of plugin support doesn't support your use case.

I don't know what you're trying to achieve by modifying the pubspec, so I can't offer any suggestions for a possible alternate approach.

--
You received this message because you are subscribed to the Google Groups "Dart Analyzer Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to analyzer-discu...@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/analyzer-discuss/c61cf8d6-77cb-41b4-ad42-c08ca6a22065n%40dartlang.org.

Patt O'Brien

unread,
Sep 6, 2022, 10:59:52 AM9/6/22
to Dart Analyzer Discussion, brianwilkerson
Thanks a lot for that reply, Brian!

| I don't know what you're trying to achieve by modifying the pubspec, so I can't offer any suggestions for a possible alternate approach.

The initialization of the plugin includes copying the source code of the analyzer plugin package (package: 'sidecar_analyzer_plugin') into a subdirectory of the project ("<root>/.sidecar/sidecar_analyzer_plugin/"). In the project's pubspec, "sidecar_analyzer_plugin" is then added as a dev dependency from path ("path: .sidecar/sidecar_analyzer_plugin/"), and "sidecar_analyzer_plugin" is added to the list of analyzer plugins in analysis_options.yaml. Once this step is done, a plugin bootstrap function is dynamically loaded with a list of "LintError" subclasses that were specified in the project's analysis_options.yaml file, and the plugin applies the list of LintErrors on the project's source code. This architecture allows individual subclasses to be added/removed throughout the lifecycle of project development.

FWIW I have all of this working very reliably besides sporadically running into the issues mentioned above, where occasionally I cannot get the plugin to update, usually after I update the "sidecar"-based packages to a next "0.1.0-dev.X" version. For the life of me, I have not been able to reproducibly get the PluginManager updates figured out, even when manually trying to update files simply for development. To reiterate: the above architecture works, including dynamically adding/removing lints via the analysis_options.yaml file; just occasionally I find that updates to the LintErrors or sidecar packages don't take effect, which is slowing down development.

This architecture is no different than if you were to manually create a from-path analyzer_plugin package and modify it throughout the lifecycle of a project. TBH I'm a little doubtful of your comments that a given plugin version cannot change, because in my experience, changes to my plugin source code can be observed in the same version, at least somewhat. 

Brian Wilkerson

unread,
Sep 6, 2022, 11:54:24 AM9/6/22
to Patt O'Brien, Dart Analyzer Discussion
This architecture allows individual subclasses to be added/removed throughout the lifecycle of project development.

While the `linter` package isn't a plugin, we have a similar goal to be able to dynamically change which lints are run based on the analysis options file. I don't know whether the approach we used would work for you, but it sounds simpler to me. We load all of the `LintRule` subclasses all the time, and then choose which instances to run dynamically. That means that we don't need to restart the server every time the list of enabled rules is edited.

TBH I'm a little doubtful of your comments that a given plugin version cannot change, because in my experience, changes to my plugin source code can be observed in the same version, at least somewhat.

That's fair. I was less trying to claim that it doesn't work (though I didn't realize that it did) than that it wasn't designed to work that way. If it works at all it's an accident, not an intentional feature.

Konstantin Shcheglov

unread,
Sep 6, 2022, 12:05:29 PM9/6/22
to analyzer...@dartlang.org

  When I was working on making changes to the base for plugins - `ServerPlugin`, I was able to have something working relatively well. But I  don't remember exactly what I did :-)

  I might have used dependency override in the package that I wanted to be analyzed with a plugin (to point at the host plugin), and I was manually removing the "downloaded" plugin in `.plugin_manager` - most probably just removing the whole directory. And I think I was restarting the whole analysis server in my IntelliJ.
image.png

  So, when DAS will restart, it will re-copy the plugin into `.plugin_manager` from the local location, which we can update in the same IDE, then remove, restart, and try again.

On Wed, Aug 31, 2022 at 2:47 PM Patt O'Brien <patt....@finedesigns.io> wrote:
--
You received this message because you are subscribed to the Google Groups "Dart Analyzer Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to analyzer-discu...@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/analyzer-discuss/c61cf8d6-77cb-41b4-ad42-c08ca6a22065n%40dartlang.org.


--
Konstantin Scheglov
Software Engineer
Google, Inc.

Patt O'Brien

unread,
Sep 7, 2022, 11:55:56 AM9/7/22
to Dart Analyzer Discussion, sche...@google.com
|  I don't know whether the approach we used would work for you, but it sounds simpler to me. 
I wouldn't be surprised if your architecture was much simpler. Though the use case that I'm unsure if your solution solves (which is my primary objective) is allowing any author to publish a single LintError subclass or create one within a project directory, and allow it to be bootstrapped to the same, single plugin/server instance as the rest of the lints (declared by simply naming the lint in analysis_options). The issue with architecting this via multiple plugins is of course that resources cannot be shared, and so for the average sized project, most devs would be limited to ~ 1 or 2 plugins. The solution I'm attempting to build would allow a melting pot of different global and/or project-specific rules to exist within 1 plugin with (theoretical) 1x resources, which would be more open-ecosystem like. Am I correct in assuming your solution would not allow for various non-Linter lints to work within the same resources?

I won't trivialize the complexities of this solution, incl:

- preventing/reporting poor-performing lints which affect the entire plugin
- standardizing packages that subclass LintError
- conflicting error code definitions (e.g. "avoid_string_literal" from l10n package vs "avoid_string_literal" from some other translations package)

However, for each complexity, I've been able to implement working solutions, or have plans to do so, and the upside is (IMO) Dart-tier devX and greatly reduced barrier to entry for developers to further customize their own IDE experience, which I believe has a lot of very interesting applications.

| If it works at all it's an accident, not an intentional feature.
| I was able to have something working relatively well. But I  don't remember exactly what I did 
| most probably just removing the whole directory. And I think I was restarting the whole analysis server

I'm glad to know I'm not going crazy by also not being able to pin point the solution :)

Deleting the PluginManager folder, restarting the server, and changing overrides... some combination of those seem to sporadically work for me as well. I'm about 60% sure this is only a development problem, as things seem to work fine when pulling all packages from pub instead of from-path overrides. If thats not the case then we can cross that bridge after the proposal is out there (~ 1 week out from publishing something).

dark...@gmail.com

unread,
Sep 7, 2022, 12:34:51 PM9/7/22
to Dart Analyzer Discussion, patt....@finedesigns.io, sche...@google.com
Hello!

About sharing the resources between plugins, I plan on updating custom_lint to do exactly that. For now plugins are spawned in different isolates, but custom_lint would be able to fuse them.
Same goes for pubspec changes. custom_lint already supports reloading the plugin when its source-code changes. 

If you are interested, we could sync and work on implementing this "fusing all plugins into a single one" together. 

Patt O'Brien

unread,
Sep 7, 2022, 3:34:12 PM9/7/22
to Dart Analyzer Discussion, dark...@gmail.com, Patt O'Brien, sche...@google.com
| I plan on updating custom_lint to do exactly that.

Ah, I had no idea this was in the pipeline! That's awesome, as I was already planning to contribute my work to custom_lint... I felt it was worthy to construct a prototype on my own to nail down an architecture proposal.

Just DM'd you on Discord.

Brian Wilkerson

unread,
Sep 7, 2022, 5:31:50 PM9/7/22
to Dart Analyzer Discussion, dark...@gmail.com, Patt O'Brien, sche...@google.com
Am I correct in assuming your solution would not allow for various non-Linter lints to work within the same resources?

Yes, that's correct.

Reply all
Reply to author
Forward
0 new messages