123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- /*
- 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-extra');
- 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);
- };
|