flutter / devtools

Performance tools for Flutter
https://flutter.dev/docs/development/tools/devtools/
BSD 3-Clause "New" or "Revised" License
1.58k stars 324 forks source link

Support extensions from globally activated pub packages #7594

Open kenzieschmoll opened 5 months ago

kenzieschmoll commented 5 months ago

An example of an extension that fits this use case would be an arbitrary development tool package (like an AI-assisted development experience extension or a tool that interacts with the Dart analysis server). These extensions may be runtime or static extensions.

It would be a bit awkward to require a user to add a dev_dependency to every Dart project where they want to use this DevTools extension, since tools like these are not specific to a Dart / Flutter project, but rather to the general Dart / Flutter development experience. The workflow for an end user would be:

  1. dart pub global activate some_pkg
  2. If some_pkg provides a DevTools extension, we should be able to load this in DevTools (and also embedded in the IDE).

@jonasfj @sigmundch is there a way to tell from the pub cache what the globally activated pub packages are?

sigmundch commented 5 months ago

@sigurdm :smile:

sigurdm commented 5 months ago

We have dart pub global list, however I'm not sure it gives you enough to go on.

You probably want a way to find the .dart_tool/package_config.json for each of these to detect extensions - right?

@jonasfj should we extend the list command with more info? Any other ideas?

jonasfj commented 5 months ago

I'm not sure globally activated packages should be used for this.

Global package activation is a mechanism for installing a package onto your system. I'm not sure we should use it to configure extensions for devtools.

That said, a somewhat ludicrous idea would be for devtools to discover system-level extensions by searching PATH.

Imagine that devtools discovers system-level extensions by:

If you are authoring a global devtools extension, you don't have to ship it as a pub package to be globally activate. You can ship as a globally activated package, because you can use the executables section in pubspec.yaml to specify executables to be installed on PATH. Provided that the user added $PUB_CACHE/bin to $PATH.

I suppose it would also be possible for devtools to try and guess the location of the global PUB_CACHE, and then also search PUB_CACHE/bin for executables prefixed _dart_devtools_extensions_.

With this approach system-level devtools extensions could also be installed using system package manager like apt-get, or just extracted from a zip to /opt and manually added to PATH. Or it could be installed with a different package manager like homebrew, npm or pypi. Because devtools is just searching for executables on PATH prefixed by _dart_devtools_extensions_ (or whatever string you want).

Maybe, it's a bit crazy, but:

It might just work :D

kenzieschmoll commented 5 months ago

You probably want a way to find the .dart_tool/package_config.json for each of these to detect extensions - right?

@sigurdm package:extension_discovery's findExtensions method expects a package_config.json location so that it can:

  1. Look for any pub package that contains an extension/devtools/ directory
  2. Return a list of Extension objects that describe the extension and provide a location for the extension's assets.

For a globally activated package, we would really just need to look at its contents for the extension/devtools directory. Maybe package:extension_discovery could be extended to support this use case as well, if it is non-trivial to find a package_config.json file for globally activated packages.

Global package activation is a mechanism for installing a package onto your system. I'm not sure we should use it to configure extensions for devtools.

@jonasfj Since DevTools extensions are shipped as part of the pub ecosystem, I actually think this is a reason we need to support this use case. As a user, I would expect that if I install a package onto my system, that I can use anything that package provides, including executables, extensions, etc.

if each extension is supposed to provide a Flutter Web application or something like that, you simply run _dart_devtools_extensions_myglobaldevtoolsextension --print-extension-location and have it print where the resources are located.

While this could work, my concern is that this is one more thing that extension authors have to manually set up, and they have to know when they need this and when they do not. I don't expect extension authors to have as much familiarity with what it means to be a "static" extension vs. a "runtime" extension and "global" vs "non-global". We want to make it as simple as possible for authors to build a tool, and know that no matter how users install their package (as a global or as a project dependency), that their users will be able to discover the tool they have built and use it.

With this approach system-level devtools extensions could also be installed using system package manager like apt-get, or just extracted from a zip to /opt and manually added to PATH. Or it could be installed with a different package manager like homebrew, npm or pypi. Because devtools is just searching for executables on PATH prefixed by _dart_devtoolsextensions (or whatever string you want).

I don't think we want to diverge the extension distribution (and enablement) mechanism, since this will be less discoverable for users and will make the development process more difficult for extension authors. Having one way to ship and install an extension (via pub) is ideal. Shipping / installing with pub is straight forward and keeps DevTools extensions in alignment with the Dart ecosystem standards.