mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-15 12:43:04 +08:00
150 lines
6.8 KiB
JavaScript
150 lines
6.8 KiB
JavaScript
/*
|
|
Licensed to the Apache Software Foundation (ASF) under one
|
|
or more contributor license agreements. See the NOTICE file
|
|
distributed with this work for additional information
|
|
regarding copyright ownership. The ASF licenses this file
|
|
to you under the Apache License, Version 2.0 (the
|
|
"License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing,
|
|
software distributed under the License is distributed on an
|
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
KIND, either express or implied. See the License for the
|
|
specific language governing permissions and limitations
|
|
under the License.
|
|
*/
|
|
|
|
var Q = require('q');
|
|
var fs = require('fs');
|
|
var path = require('path');
|
|
|
|
var ActionStack = require('./ActionStack');
|
|
var PlatformJson = require('./PlatformJson');
|
|
var CordovaError = require('./CordovaError/CordovaError');
|
|
var PlatformMunger = require('./ConfigChanges/ConfigChanges').PlatformMunger;
|
|
var PluginInfoProvider = require('./PluginInfo/PluginInfoProvider');
|
|
|
|
/**
|
|
* @constructor
|
|
* @class PluginManager
|
|
* Represents an entity for adding/removing plugins for platforms
|
|
*
|
|
* @param {String} platform Platform name
|
|
* @param {Object} locations - Platform files and directories
|
|
* @param {IDEProject} ideProject The IDE project to add/remove plugin changes to/from
|
|
*/
|
|
function PluginManager (platform, locations, ideProject) {
|
|
this.platform = platform;
|
|
this.locations = locations;
|
|
this.project = ideProject;
|
|
|
|
var platformJson = PlatformJson.load(locations.root, platform);
|
|
this.munger = new PlatformMunger(platform, locations.root, platformJson, new PluginInfoProvider());
|
|
}
|
|
|
|
/**
|
|
* @constructs PluginManager
|
|
* A convenience shortcut to new PluginManager(...)
|
|
*
|
|
* @param {String} platform Platform name
|
|
* @param {Object} locations - Platform files and directories
|
|
* @param {IDEProject} ideProject The IDE project to add/remove plugin changes to/from
|
|
* @returns new PluginManager instance
|
|
*/
|
|
PluginManager.get = function (platform, locations, ideProject) {
|
|
return new PluginManager(platform, locations, ideProject);
|
|
};
|
|
|
|
PluginManager.INSTALL = 'install';
|
|
PluginManager.UNINSTALL = 'uninstall';
|
|
|
|
module.exports = PluginManager;
|
|
|
|
/**
|
|
* Describes and implements common plugin installation/uninstallation routine. The flow is the following:
|
|
* * Validate and set defaults for options. Note that options are empty by default. Everything
|
|
* needed for platform IDE project must be passed from outside. Plugin variables (which
|
|
* are the part of the options) also must be already populated with 'PACKAGE_NAME' variable.
|
|
* * Collect all plugin's native and web files, get installers/uninstallers and process
|
|
* all these via ActionStack.
|
|
* * Save the IDE project, so the changes made by installers are persisted.
|
|
* * Generate config changes munge for plugin and apply it to all required files
|
|
* * Generate metadata for plugin and plugin modules and save it to 'cordova_plugins.js'
|
|
*
|
|
* @param {PluginInfo} plugin A PluginInfo structure representing plugin to install
|
|
* @param {Object} [options={}] An installation options. It is expected but is not necessary
|
|
* that options would contain 'variables' inner object with 'PACKAGE_NAME' field set by caller.
|
|
*
|
|
* @returns {Promise} Returns a Q promise, either resolved in case of success, rejected otherwise.
|
|
*/
|
|
PluginManager.prototype.doOperation = function (operation, plugin, options) {
|
|
if (operation !== PluginManager.INSTALL && operation !== PluginManager.UNINSTALL) { return Q.reject(new CordovaError('The parameter is incorrect. The opeation must be either "add" or "remove"')); }
|
|
|
|
if (!plugin || plugin.constructor.name !== 'PluginInfo') { return Q.reject(new CordovaError('The parameter is incorrect. The first parameter should be a PluginInfo instance')); }
|
|
|
|
// Set default to empty object to play safe when accesing properties
|
|
options = options || {};
|
|
|
|
var self = this;
|
|
var actions = new ActionStack();
|
|
|
|
// gather all files need to be handled during operation ...
|
|
plugin.getFilesAndFrameworks(this.platform, options)
|
|
.concat(plugin.getAssets(this.platform))
|
|
.concat(plugin.getJsModules(this.platform))
|
|
// ... put them into stack ...
|
|
.forEach(function (item) {
|
|
var installer = self.project.getInstaller(item.itemType);
|
|
var uninstaller = self.project.getUninstaller(item.itemType);
|
|
var actionArgs = [item, plugin, self.project, options];
|
|
|
|
var action;
|
|
if (operation === PluginManager.INSTALL) {
|
|
action = actions.createAction.apply(actions, [installer, actionArgs, uninstaller, actionArgs]); /* eslint no-useless-call: 0 */
|
|
} else /* op === PluginManager.UNINSTALL */{
|
|
action = actions.createAction.apply(actions, [uninstaller, actionArgs, installer, actionArgs]); /* eslint no-useless-call: 0 */
|
|
}
|
|
actions.push(action);
|
|
});
|
|
|
|
// ... and run through the action stack
|
|
return actions.process(this.platform)
|
|
.then(function () {
|
|
if (self.project.write) {
|
|
self.project.write();
|
|
}
|
|
|
|
if (operation === PluginManager.INSTALL) {
|
|
// Ignore passed `is_top_level` option since platform itself doesn't know
|
|
// anything about managing dependencies - it's responsibility of caller.
|
|
self.munger.add_plugin_changes(plugin, options.variables, /* is_top_level= */true, /* should_increment= */true, options.force);
|
|
self.munger.platformJson.addPluginMetadata(plugin);
|
|
} else {
|
|
self.munger.remove_plugin_changes(plugin, /* is_top_level= */true);
|
|
self.munger.platformJson.removePluginMetadata(plugin);
|
|
}
|
|
|
|
// Save everything (munge and plugin/modules metadata)
|
|
self.munger.save_all();
|
|
|
|
var metadata = self.munger.platformJson.generateMetadata();
|
|
fs.writeFileSync(path.join(self.locations.www, 'cordova_plugins.js'), metadata, 'utf-8');
|
|
|
|
// CB-11022 save plugin metadata to both www and platform_www if options.usePlatformWww is specified
|
|
if (options.usePlatformWww) {
|
|
fs.writeFileSync(path.join(self.locations.platformWww, 'cordova_plugins.js'), metadata, 'utf-8');
|
|
}
|
|
});
|
|
};
|
|
|
|
PluginManager.prototype.addPlugin = function (plugin, installOptions) {
|
|
return this.doOperation(PluginManager.INSTALL, plugin, installOptions);
|
|
};
|
|
|
|
PluginManager.prototype.removePlugin = function (plugin, uninstallOptions) {
|
|
return this.doOperation(PluginManager.UNINSTALL, plugin, uninstallOptions);
|
|
};
|