uninstallPlugin method
Future<PluginOperationResult>
uninstallPlugin(
- String plugin, [
- PluginScope scope = PluginScope.user,
- bool deleteDataDirFlag = true
Uninstall a plugin.
Implementation
Future<PluginOperationResult> uninstallPlugin(
String plugin, [
PluginScope scope = PluginScope.user,
bool deleteDataDirFlag = true,
]) async {
assertInstallableScope(scope);
final allPlugins = await loadAllPlugins();
final foundPlugin = findPluginByIdentifier(plugin, allPlugins);
final settingSource = scopeToSettingSource(scope);
final settings = getSettingsEnabledPlugins(settingSource);
String pluginId;
String pluginName;
if (foundPlugin != null) {
pluginId =
settings?.keys.firstWhere(
(k) =>
k == plugin ||
k == foundPlugin.name ||
k.startsWith('${foundPlugin.name}@'),
orElse: () => plugin.contains('@') ? plugin : foundPlugin.name,
) ??
(plugin.contains('@') ? plugin : foundPlugin.name);
pluginName = foundPlugin.name;
} else {
return PluginOperationResult(
success: false,
message: 'Plugin "$plugin" not found in installed plugins',
);
}
// Check scope installation.
final projectPath = getProjectPathForScope(scope);
final installedData = loadInstalledPluginsV2();
final installations = installedData.plugins[pluginId];
final scopeInstallation = installations
?.cast<PluginInstallationRecord?>()
.firstWhere(
(i) => i!.scope == scope && i.projectPath == projectPath,
orElse: () => null,
);
if (scopeInstallation == null) {
final actual = getPluginInstallationFromV2(pluginId);
if (actual.scope != scope &&
installations != null &&
installations.isNotEmpty) {
if (actual.scope == PluginScope.project) {
return PluginOperationResult(
success: false,
message:
'Plugin "$plugin" is enabled at project scope. '
'To disable just for you: neomage plugin disable $plugin --scope local',
);
}
return PluginOperationResult(
success: false,
message:
'Plugin "$plugin" is installed in ${actual.scope.name} scope, '
'not ${scope.name}. Use --scope ${actual.scope.name} to uninstall.',
);
}
return PluginOperationResult(
success: false,
message:
'Plugin "$plugin" is not installed in ${scope.name} scope. '
'Use --scope to specify the correct scope.',
);
}
// Remove from settings.
final newEnabled = Map<String, bool>.from(settings ?? {});
newEnabled.remove(pluginId);
updateSettings(settingSource, {'enabledPlugins': newEnabled});
clearAllCaches();
// Remove from V2 data.
removePluginInstallation(pluginId, scope, projectPath);
// Check if this was the last installation scope.
final updatedData = loadInstalledPluginsV2();
final remaining = updatedData.plugins[pluginId];
final isLastScope = remaining == null || remaining.isEmpty;
if (isLastScope && scopeInstallation.installPath != null) {
await markVersionOrphaned(scopeInstallation.installPath!);
}
if (isLastScope) {
deletePluginOptions(pluginId);
if (deleteDataDirFlag) {
await deletePluginDataDir(pluginId);
}
}
final reverseDeps = findReverseDependents(pluginId, allPlugins);
final depWarn = reverseDeps.isNotEmpty
? '. Warning: the following plugins depend on this: ${reverseDeps.join(', ')}'
: '';
return PluginOperationResult(
success: true,
message:
'Successfully uninstalled plugin: $pluginName (scope: ${scope.name})$depWarn',
pluginId: pluginId,
pluginName: pluginName,
scope: scope,
reverseDependents: reverseDeps.isNotEmpty ? reverseDeps : null,
);
}