serveAvailableExtensions method
Serves any available DevTools extensions for the given rootPathFileUri
,
where rootPathFileUri
is the root for a Dart or Flutter project
containing the .dart_tool/
directory.
rootPathFileUri
is expected to be a file uri (e.g. starting with
'file://').
This method first looks up the available extensions using
package:extension_discovery, and the available extension's
assets will be copied to the build/devtools_extensions
directory that
DevTools server is serving.
Implementation
Future<void> serveAvailableExtensions(
String? rootPathFileUri,
List<String> logs,
) async {
if (rootPathFileUri != null && !rootPathFileUri.startsWith('file://')) {
throw ArgumentError.value(
rootPathFileUri,
'rootPathFileUri',
'must be a file:// URI String',
);
}
logs.add(
'ExtensionsManager.serveAvailableExtensions: '
'rootPathFileUri: $rootPathFileUri',
);
devtoolsExtensions.clear();
final parsingErrors = StringBuffer();
if (rootPathFileUri != null) {
late final List<Extension> extensions;
try {
extensions = await findExtensions(
'devtools',
packageConfig: Uri.parse(
path.posix.join(
rootPathFileUri,
'.dart_tool',
'package_config.json',
),
),
);
logs.add(
'ExtensionsManager.serveAvailableExtensions: findExtensionsResult - '
'${extensions.map((e) => e.package).toList()}',
);
} catch (e) {
extensions = <Extension>[];
rethrow;
}
for (final extension in extensions) {
final config = extension.config;
// TODO(https://github.com/dart-lang/pub/issues/4042): make this check
// more robust.
final isPubliclyHosted = (extension.rootUri.path.contains('pub.dev') ||
extension.rootUri.path.contains('pub.flutter-io.cn'))
.toString();
// This should be relative to the 'extension/devtools/' directory and
// defaults to 'build';
final relativeExtensionLocation =
config['buildLocation'] as String? ?? 'build';
final location = path.join(
extension.rootUri.toFilePath(),
'extension',
'devtools',
relativeExtensionLocation,
);
try {
final extensionConfig = DevToolsExtensionConfig.parse({
...config,
DevToolsExtensionConfig.pathKey: location,
DevToolsExtensionConfig.isPubliclyHostedKey: isPubliclyHosted,
});
devtoolsExtensions.add(extensionConfig);
} on StateError catch (e) {
parsingErrors.writeln(e.message);
continue;
}
}
}
_resetServedPluginsDir();
await Future.wait([
for (final extension in devtoolsExtensions)
_moveToServedExtensionsDir(extension.name, extension.path, logs: logs),
]);
if (parsingErrors.isNotEmpty) {
throw ExtensionParsingException(
'Encountered errors while parsing extension config.yaml '
'files:\n$parsingErrors',
);
}
}