findExtensions function
Find extensions for targetPackage
provided by packages in
.dart_tool/package_config.json
.
Locating .dart_tool/package_config.json
This method requires the location of the packageConfig
, unless the current
isolate has been setup for package resolution.
Notably, Dart programs compiled for AOT cannot find their own
package_config.json
.
If operating on a project that isn't the current project, for example, if
you are developing a tool that users are globally activating and then
running against their own projects, and you wish to detect extensions within
their projects, then you must specify the path the
.dart_tool/package_config.json
for the users project as packageConfig
.
The packageConfig
parameter must reference a file, absolute or
relative-path, may use the file://
scheme. This method throws, if
packageConfig
is not a valid Uri for a file-path.
Detection of extensions
An extension for targetPackage
is detected in package:foo
if foo
contains extension/<targetPackage>/config.yaml
, and the contents of this
file is valid YAML, that can be represented as JSON.
Caching results
When useCache
is true
then the detected extensions will be cached
in .dart_tool/extension_discovery/<targetPackage>.yaml
.
This function will compare modification timestamps of
.dart_tool/package_config.json
with the cache file, before reusing cached
results.
This function will also treat relative path-dependencies as mutable
packages, and check such packages for extensions every time findExtensions
is called. Notably, it'll compare the modification time of the
extension/<targetPackage>/config.yaml
file, to ensure that it's older than
the extension cache file. Otherwise, it'll reload the extension
configuration.
Exceptions
This method will throw PackageConfigException, if the
.dart_tool/package_config.json
file specified in packageConfig
could not
be loaded or is invalid. This usually happens if dependencies are not
resolved, and users can probably address it by running dart pub get
.
But, do consider catch PackageConfigException and handling the failure to load extensions appropriately.
This method will throw an Error if packageConfig
is not specified, and
the current isolate isn't configured for package resolution.
Implementation
Future<List<Extension>> findExtensions(
String targetPackage, {
bool useCache = true,
Uri? packageConfig,
}) async {
packageConfig ??= await Isolate.packageConfig;
if (packageConfig == null) {
throw UnsupportedError(
'packageConfigUri must be provided, if not running in JIT mode',
);
}
if ((packageConfig.hasScheme && !packageConfig.isScheme('file')) ||
packageConfig.hasEmptyPath ||
packageConfig.hasFragment ||
packageConfig.hasPort ||
packageConfig.hasQuery) {
throw ArgumentError.value(
packageConfig,
'packageConfig',
'must be a file:// URI',
);
}
// Always normalize to an absolute URI
final packageConfigUri = File.fromUri(packageConfig).absolute.uri;
return await _findExtensions(
targetPackage: targetPackage,
useCache: useCache,
packageConfigUri: packageConfigUri,
);
}