From 65a084a623592967a68aa9e7c7cf2d62fd362118 Mon Sep 17 00:00:00 2001 From: Vladimir Kotikov Date: Fri, 22 Apr 2016 15:38:15 +0300 Subject: [PATCH] CB-11139 Use PluginManager from common to install/uninstall plugins --- spec/unit/pluginHandler/common.spec.js | 4 +- template/cordova/Api.js | 207 ++----------------------- template/cordova/lib/JsprojManager.js | 9 ++ template/cordova/lib/prepare.js | 8 +- 4 files changed, 31 insertions(+), 197 deletions(-) diff --git a/spec/unit/pluginHandler/common.spec.js b/spec/unit/pluginHandler/common.spec.js index cfc92f75..c0db1245 100644 --- a/spec/unit/pluginHandler/common.spec.js +++ b/spec/unit/pluginHandler/common.spec.js @@ -41,8 +41,8 @@ var removeFileAndParents = common.__get__('removeFileAndParents'); describe('common platform handler', function() { describe('copyFile', function() { it('should throw if source path not found', function(){ - expect(function(){copyFile('/some/dir', src, project_dir, dest);}) - .toThrow(new Error('"' + src + '" not found!')); + expect(function(){copyFile('/some/dir', 'foo', project_dir, dest);}) + .toThrow(new Error('"' + path.resolve('/some/dir', 'foo') + '" not found!')); }); it('should throw if src not in plugin directory', function(){ diff --git a/template/cordova/Api.js b/template/cordova/Api.js index eea4db35..1a15c735 100644 --- a/template/cordova/Api.js +++ b/template/cordova/Api.js @@ -17,20 +17,11 @@ under the License. */ -var Q = require('q'); -var fs = require('fs'); var path = require('path'); -var shell = require('shelljs'); - -var JsprojManager = require('./lib/JsprojManager'); -var PluginHandler = require('./lib/PluginHandler'); var events = require('cordova-common').events; -var ActionStack = require('cordova-common').ActionStack; -var CordovaError = require('cordova-common').CordovaError; +var JsprojManager = require('./lib/JsprojManager'); +var PluginManager = require('cordova-common').PluginManager; var CordovaLogger = require('cordova-common').CordovaLogger; -var PlatformJson = require('cordova-common').PlatformJson; -var PlatformMunger = require('./lib/ConfigChanges').PlatformMunger; -var PluginInfoProvider = require('cordova-common').PluginInfoProvider; var PLATFORM = 'windows'; @@ -63,12 +54,7 @@ function Api(platform, platformRootDir, eventEmitter) { setupEvents(eventEmitter); - this._platformJson = PlatformJson.load(this.root, platform); - this._pluginInfoProvider = new PluginInfoProvider(); - this._munger = new PlatformMunger(this.platform, this.root, this._platformJson, this._pluginInfoProvider); - var self = this; - this.locations = { root: self.root, www: path.join(self.root, 'www'), @@ -193,50 +179,19 @@ Api.prototype.prepare = function (cordovaProject) { */ Api.prototype.addPlugin = function (plugin, installOptions) { - if (!plugin || plugin.constructor.name !== 'PluginInfo') - return Q.reject(new CordovaError('The parameter is incorrect. The first parameter ' + - 'should be valid PluginInfo instance')); - + var jsProject = JsprojManager.getProject(this.root); installOptions = installOptions || {}; installOptions.variables = installOptions.variables || {}; - - var self = this; - var actions = new ActionStack(); - var jsProject = JsprojManager.getProject(this.root); - // Add PACKAGE_NAME variable into vars if (!installOptions.variables.PACKAGE_NAME) { installOptions.variables.PACKAGE_NAME = jsProject.getPackageName(); } - // gather all files needs to be handled during install - plugin.getFilesAndFrameworks(this.platform) - .concat(plugin.getAssets(this.platform)) - .concat(plugin.getJsModules(this.platform)) - .forEach(function(item) { - actions.push(actions.createAction( - PluginHandler.getInstaller(item.itemType), [item, plugin, jsProject, installOptions], - PluginHandler.getUninstaller(item.itemType), [item, plugin, jsProject, installOptions])); - }); - - // run through the action stack - return actions.process(this.platform) - .then(function () { - jsProject.write(); - - self._munger - // Ignore passed `is_top_level` option since platform itself doesn't know - // anything about managing dependencies - it's responsibility of caller. - .add_plugin_changes(plugin, installOptions.variables, /*is_top_level=*/true, /*should_increment=*/true) - .save_all(); - - var targetDirs = [self.getPlatformInfo().locations.www]; - if (installOptions.usePlatformWww) targetDirs.push(self.getPlatformInfo().locations.platformWww); - self._addModulesInfo(plugin, targetDirs); - - // CB-11022 return non-falsy value to indicate that there is no need to run prepare after that - return true; - }); + return PluginManager.get(this.platform, this.locations, jsProject) + .addPlugin(plugin, installOptions) + // CB-11022 return non-falsy value to indicate + // that there is no need to run prepare after + .thenResolve(true); }; /** @@ -253,44 +208,14 @@ Api.prototype.addPlugin = function (plugin, installOptions) { * CordovaError instance. */ Api.prototype.removePlugin = function (plugin, uninstallOptions) { - - var self = this; - var actions = new ActionStack(); - var projectFile = JsprojManager.getProject(this.root); - - // queue up plugin files - plugin.getFilesAndFrameworks(this.platform) - .concat(plugin.getAssets(this.platform)) - .concat(plugin.getJsModules(this.platform)) - .forEach(function(item) { - actions.push(actions.createAction( - PluginHandler.getUninstaller(item.itemType), [item, plugin, projectFile, uninstallOptions], - PluginHandler.getInstaller(item.itemType), [item, plugin, projectFile, uninstallOptions])); - }); - - // run through the action stack - return actions.process(this.platform) - .then(function() { - projectFile.write(); - - self._munger - // Ignore passed `is_top_level` option since platform itself doesn't know - // anything about managing dependencies - it's responsibility of caller. - .remove_plugin_changes(plugin, /*is_top_level=*/true) - .save_all(); - - var targetDirs = [self.getPlatformInfo().locations.www]; - if (uninstallOptions.usePlatformWww) targetDirs.push(self.getPlatformInfo().locations.platformWww); - self._removeModulesInfo(plugin, targetDirs); - // Remove stale plugin directory - shell.rm('-rf', path.resolve(self.root, 'Plugins', plugin.id)); - - // CB-11022 return non-falsy value to indicate that there is no need to run prepare after that - return true; - }); + var jsProject = JsprojManager.getProject(this.root); + return PluginManager.get(this.platform, this.locations, jsProject) + .removePlugin(plugin, uninstallOptions) + // CB-11022 return non-falsy value to indicate + // that there is no need to run prepare after + .thenResolve(true); }; - /** * Builds an application package for current platform. * @@ -385,107 +310,3 @@ Api.prototype.requirements = function() { }; module.exports = Api; - -/** - * Removes the specified modules from list of installed modules and updates - * platform_json and cordova_plugins.js on disk. - * - * @param {PluginInfo} plugin PluginInfo instance for plugin, which modules - * needs to be added. - * @param {String[]} targetDirs The directories, where updated cordova_plugins.js - * should be written to. - */ -Api.prototype._addModulesInfo = function(plugin, targetDirs) { - var installedModules = this._platformJson.root.modules || []; - - var installedPaths = installedModules.map(function (installedModule) { - return installedModule.file; - }); - - var modulesToInstall = plugin.getJsModules(this.platform) - .filter(function (moduleToInstall) { - return installedPaths.indexOf(moduleToInstall.file) === -1; - }).map(function (moduleToInstall) { - var moduleName = plugin.id + '.' + ( moduleToInstall.name || moduleToInstall.src.match(/([^\/]+)\.js/)[1] ); - var obj = { - file: ['plugins', plugin.id, moduleToInstall.src].join('/'), - id: moduleName, - pluginId: plugin.id - }; - if (moduleToInstall.clobbers.length > 0) { - obj.clobbers = moduleToInstall.clobbers.map(function(o) { return o.target; }); - } - if (moduleToInstall.merges.length > 0) { - obj.merges = moduleToInstall.merges.map(function(o) { return o.target; }); - } - if (moduleToInstall.runs) { - obj.runs = true; - } - - return obj; - }); - - this._platformJson.root.modules = installedModules.concat(modulesToInstall); - if (!this._platformJson.root.plugin_metadata) { - this._platformJson.root.plugin_metadata = {}; - } - this._platformJson.root.plugin_metadata[plugin.id] = plugin.version; - - this._writePluginModules(targetDirs); - this._platformJson.save(); -}; - -/** - * Removes the specified modules from list of installed modules and updates - * platform_json and cordova_plugins.js on disk. - * - * @param {PluginInfo} plugin PluginInfo instance for plugin, which modules - * needs to be removed. - * @param {String[]} targetDirs The directory, where updated cordova_plugins.js - * should be written to. - */ -Api.prototype._removeModulesInfo = function(plugin, targetDirs) { - var installedModules = this._platformJson.root.modules || []; - var modulesToRemove = plugin.getJsModules(this.platform) - .map(function (jsModule) { - return ['plugins', plugin.id, jsModule.src].join('/'); - }); - - var updatedModules = installedModules - .filter(function (installedModule) { - return (modulesToRemove.indexOf(installedModule.file) === -1); - }); - - this._platformJson.root.modules = updatedModules; - if (this._platformJson.root.plugin_metadata) { - delete this._platformJson.root.plugin_metadata[plugin.id]; - } - - this._writePluginModules(targetDirs); - this._platformJson.save(); -}; - -/** - * Fetches all installed modules, generates cordova_plugins contents and writes - * it to file. - * - * @param {String[]} targetDirs Directory, where write cordova_plugins.js to. - * Ususally it is either /www or /platform_www - * directories. - */ -Api.prototype._writePluginModules = function (targetDirs) { - // Write out moduleObjects as JSON wrapped in a cordova module to cordova_plugins.js - var final_contents = 'cordova.define(\'cordova/plugin_list\', function(require, exports, module) {\n'; - final_contents += 'module.exports = ' + JSON.stringify(this._platformJson.root.modules, null, ' ') + ';\n'; - final_contents += 'module.exports.metadata = \n'; - final_contents += '// TOP OF METADATA\n'; - - final_contents += JSON.stringify(this._platformJson.root.plugin_metadata, null, 4) + ';\n'; - final_contents += '// BOTTOM OF METADATA\n'; - final_contents += '});'; // Close cordova.define. - - targetDirs.forEach(function (targetDir) { - shell.mkdir('-p', targetDir); - fs.writeFileSync(path.join(targetDir, 'cordova_plugins.js'), final_contents, 'utf-8'); - }); -}; diff --git a/template/cordova/lib/JsprojManager.js b/template/cordova/lib/JsprojManager.js index c8233144..01b35d51 100644 --- a/template/cordova/lib/JsprojManager.js +++ b/template/cordova/lib/JsprojManager.js @@ -30,6 +30,7 @@ var util = require('util'); var semver = require('semver'); var shell = require('shelljs'); var AppxManifest = require('./AppxManifest'); +var PluginHandler = require('./PluginHandler'); var events = require('cordova-common').events; var CordovaError = require('cordova-common').CordovaError; var xml_helpers = require('cordova-common').xmlHelpers; @@ -343,6 +344,14 @@ jsprojManager.prototype = { } }; +jsprojManager.prototype.getInstaller = function (type) { + return PluginHandler.getInstaller(type); +}; + +jsprojManager.prototype.getUninstaller = function (type) { + return PluginHandler.getUninstaller(type); +}; + function getProjectReferencePreInsertRegExp(projectGuid) { projectGuid = escapeRegExpString(projectGuid); return new RegExp("\\s*ProjectSection\\(ProjectDependencies\\)\\s*=\\s*postProject\\s*" + projectGuid + "\\s*=\\s*" + projectGuid + "\\s*EndProjectSection", "gi"); diff --git a/template/cordova/lib/prepare.js b/template/cordova/lib/prepare.js index 9869e06b..f4f8550e 100644 --- a/template/cordova/lib/prepare.js +++ b/template/cordova/lib/prepare.js @@ -29,6 +29,9 @@ var MSBuildTools = require('./MSBuildTools'); var ConfigParser = require('./ConfigParser'); var events = require('cordova-common').events; var xmlHelpers = require('cordova-common').xmlHelpers; +var PlatformJson = require('cordova-common').PlatformJson; +var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger; +var PluginInfoProvider = require('cordova-common').PluginInfoProvider; // Default value for VisualElements' Description attribute. // This is equal to the value that comes with default App template @@ -412,8 +415,9 @@ function getUAPVersions(config) { module.exports.prepare = function (cordovaProject) { var self = this; - this._config = updateConfigFilesFrom(cordovaProject.projectConfig, - this._munger, this.locations); + var platformJson = PlatformJson.load(this.root, this.platform); + var munger = new PlatformMunger(this.platform, this.root, platformJson, new PluginInfoProvider()); + this._config = updateConfigFilesFrom(cordovaProject.projectConfig, munger, this.locations); // CB-10845 avoid using cached appxmanifests since they could be // previously modififed outside of AppxManifest class