Skip to content

Commit

Permalink
Make plugin.remove more easily understandable
Browse files Browse the repository at this point in the history
  • Loading branch information
raphinesse committed Aug 16, 2018
1 parent 25ce908 commit 2ec81a6
Showing 1 changed file with 85 additions and 70 deletions.
155 changes: 85 additions & 70 deletions src/cordova/plugin/remove.js
Expand Up @@ -30,6 +30,7 @@ var path = require('path');
var fs = require('fs');
var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
var detectIndent = require('detect-indent');
const { Q_chainmap } = require('../../util/promise-util');

module.exports = remove;
module.exports.validatePluginId = validatePluginId;
Expand All @@ -49,76 +50,7 @@ function remove (projectRoot, targets, hooksRunner, opts) {
opts.cordova = { plugins: cordova_util.findPlugins(pluginPath) };
return hooksRunner.fire('before_plugin_rm', opts)
.then(function () {
var pluginInfoProvider = new PluginInfoProvider();
var platformRoot;
return opts.plugins.reduce(function (soFar, target) {
var validatedPluginId = module.exports.validatePluginId(target, plugins);
if (!validatedPluginId) {
return Q.reject(new CordovaError('Plugin "' + target + '" is not present in the project. See `' + cordova_util.binname + ' plugin list`.'));
}
target = validatedPluginId;

// Iterate over all installed platforms and uninstall.
// If this is a web-only or dependency-only plugin, then
// there may be nothing to do here except remove the
// reference from the platform's plugin config JSON.
return soFar.then(_ => platformList.reduce(function (soFar, platform) {
return soFar.then(function () {
platformRoot = path.join(projectRoot, 'platforms', platform);
var directory = path.join(pluginPath, target);
var pluginInfo = pluginInfoProvider.get(directory);
events.emit('verbose', 'Calling plugman.uninstall on plugin "' + target + '" for platform "' + platform + '"');
opts.force = opts.force || false;

return plugin_util.mergeVariables(pluginInfo, cfg, opts);
}).then(function (variables) {
opts.cli_variables = variables;
return plugman.uninstall.uninstallPlatform(platform, platformRoot, target, pluginPath, opts)
.then(function (didPrepare) {
// If platform does not returned anything we'll need
// to trigger a prepare after all plugins installed
// TODO: if didPrepare is falsy, what does that imply? WHY are we doing this?
if (!didPrepare) shouldRunPrepare = true;
});
});
}, Q()))
.then(function () {
// TODO: Should only uninstallPlugin when no platforms have it.
return plugman.uninstall.uninstallPlugin(target, pluginPath, opts);
}).then(function () {
// remove plugin from config.xml
if (plugin_util.saveToConfigXmlOn(config_json, opts)) {
events.emit('log', 'Removing plugin ' + target + ' from config.xml file...');
var configPath = cordova_util.projectConfig(projectRoot);
if (fs.existsSync(configPath)) { // should not happen with real life but needed for tests
var configXml = new ConfigParser(configPath);
configXml.removePlugin(target);
configXml.write();
}
var pkgJson;
var pkgJsonPath = path.join(projectRoot, 'package.json');
// If statement to see if pkgJsonPath exists in the filesystem
if (fs.existsSync(pkgJsonPath)) {
// delete any previous caches of require(package.json)
pkgJson = cordova_util.requireNoCache(pkgJsonPath);
}
// If package.json exists and contains a specified plugin in cordova['plugins'], it will be removed
if (pkgJson !== undefined && pkgJson.cordova !== undefined && pkgJson.cordova.plugins !== undefined) {
events.emit('log', 'Removing ' + target + ' from package.json');
// Remove plugin from package.json
delete pkgJson.cordova.plugins[target];
// Write out new package.json with plugin removed correctly.
var file = fs.readFileSync(pkgJsonPath, 'utf8');
var indent = detectIndent(file).indent || ' ';
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, indent), 'utf8');
}
}
}).then(function () {
// Remove plugin from fetch.json
events.emit('verbose', 'Removing plugin ' + target + ' from fetch.json');
metadata.remove_fetch_metadata(pluginPath, target);
});
}, Q());
return Q_chainmap(opts.plugins, removePlugin);
}).then(function () {
// CB-11022 We do not need to run prepare after plugin install until shouldRunPrepare flag is set to true
if (!shouldRunPrepare) {
Expand All @@ -129,6 +61,89 @@ function remove (projectRoot, targets, hooksRunner, opts) {
opts.cordova = { plugins: cordova_util.findPlugins(pluginPath) };
return hooksRunner.fire('after_plugin_rm', opts);
});

function removePlugin (target) {
return Promise.resolve()
.then(function () {
var validatedPluginId = module.exports.validatePluginId(target, plugins);
if (!validatedPluginId) {
throw new CordovaError('Plugin "' + target + '" is not present in the project. See `' + cordova_util.binname + ' plugin list`.');
}
target = validatedPluginId;
}).then(function () {
// Iterate over all installed platforms and uninstall.
// If this is a web-only or dependency-only plugin, then
// there may be nothing to do here except remove the
// reference from the platform's plugin config JSON.
return Q_chainmap(platformList, platform =>
removePluginFromPlatform(target, platform)
);
}).then(function () {
// TODO: Should only uninstallPlugin when no platforms have it.
return plugman.uninstall.uninstallPlugin(target, pluginPath, opts);
}).then(function () {
if (!plugin_util.saveToConfigXmlOn(config_json, opts)) return;
persistRemovalToCfg(target);
persistRemovalToPkg(target);
}).then(function () {
// Remove plugin from fetch.json
events.emit('verbose', 'Removing plugin ' + target + ' from fetch.json');
metadata.remove_fetch_metadata(pluginPath, target);
});
}

function removePluginFromPlatform (target, platform) {
var platformRoot;

return Promise.resolve().then(function () {
platformRoot = path.join(projectRoot, 'platforms', platform);
var directory = path.join(pluginPath, target);
var pluginInfo = new PluginInfoProvider().get(directory);
events.emit('verbose', 'Calling plugman.uninstall on plugin "' + target + '" for platform "' + platform + '"');
opts.force = opts.force || false;

return plugin_util.mergeVariables(pluginInfo, cfg, opts);
}).then(function (variables) {
opts.cli_variables = variables;
return plugman.uninstall.uninstallPlatform(platform, platformRoot, target, pluginPath, opts)
.then(function (didPrepare) {
// If platform does not returned anything we'll need
// to trigger a prepare after all plugins installed
// TODO: if didPrepare is falsy, what does that imply? WHY are we doing this?
if (!didPrepare) shouldRunPrepare = true;
});
});
}

function persistRemovalToCfg (target) {
events.emit('log', 'Removing plugin ' + target + ' from config.xml file...');
var configPath = cordova_util.projectConfig(projectRoot);
if (fs.existsSync(configPath)) { // should not happen with real life but needed for tests
var configXml = new ConfigParser(configPath);
configXml.removePlugin(target);
configXml.write();
}
}

function persistRemovalToPkg (target) {
var pkgJson;
var pkgJsonPath = path.join(projectRoot, 'package.json');
// If statement to see if pkgJsonPath exists in the filesystem
if (fs.existsSync(pkgJsonPath)) {
// delete any previous caches of require(package.json)
pkgJson = cordova_util.requireNoCache(pkgJsonPath);
}
// If package.json exists and contains a specified plugin in cordova['plugins'], it will be removed
if (pkgJson !== undefined && pkgJson.cordova !== undefined && pkgJson.cordova.plugins !== undefined) {
events.emit('log', 'Removing ' + target + ' from package.json');
// Remove plugin from package.json
delete pkgJson.cordova.plugins[target];
// Write out new package.json with plugin removed correctly.
var file = fs.readFileSync(pkgJsonPath, 'utf8');
var indent = detectIndent(file).indent || ' ';
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, indent), 'utf8');
}
}
}

function validatePluginId (pluginId, installedPlugins) {
Expand Down

0 comments on commit 2ec81a6

Please sign in to comment.