mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-26 03:53:09 +08:00
CB-11138 Reuse PluginManager from common to add/rm plugins
This closes #301
This commit is contained in:
parent
dc6384d063
commit
d351e316bf
224
bin/templates/cordova/Api.js
vendored
224
bin/templates/cordova/Api.js
vendored
@ -17,19 +17,11 @@
|
|||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Q = require('q');
|
|
||||||
var fs = require('fs');
|
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var shell = require('shelljs');
|
|
||||||
|
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
|
||||||
var PlatformJson = require('cordova-common').PlatformJson;
|
|
||||||
var ActionStack = require('cordova-common').ActionStack;
|
|
||||||
var AndroidProject = require('./lib/AndroidProject');
|
var AndroidProject = require('./lib/AndroidProject');
|
||||||
var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger;
|
var PluginManager = require('cordova-common').PluginManager;
|
||||||
var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
|
|
||||||
|
|
||||||
var pluginHandlers = require('./lib/pluginHandlers');
|
|
||||||
var CordovaLogger = require('cordova-common').CordovaLogger;
|
var CordovaLogger = require('cordova-common').CordovaLogger;
|
||||||
var selfEvents = require('cordova-common').events;
|
var selfEvents = require('cordova-common').events;
|
||||||
|
|
||||||
@ -65,10 +57,6 @@ function Api(platform, platformRootDir, events) {
|
|||||||
|
|
||||||
setupEvents(events);
|
setupEvents(events);
|
||||||
|
|
||||||
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;
|
var self = this;
|
||||||
|
|
||||||
this.locations = {
|
this.locations = {
|
||||||
@ -197,59 +185,25 @@ Api.prototype.prepare = function (cordovaProject) {
|
|||||||
* CordovaError instance.
|
* CordovaError instance.
|
||||||
*/
|
*/
|
||||||
Api.prototype.addPlugin = function (plugin, installOptions) {
|
Api.prototype.addPlugin = function (plugin, installOptions) {
|
||||||
|
var project = AndroidProject.getProjectFile(this.root);
|
||||||
if (!plugin || plugin.constructor.name !== 'PluginInfo')
|
|
||||||
return Q.reject(new CordovaError('The parameter is incorrect. The first parameter to addPlugin should be a PluginInfo instance'));
|
|
||||||
|
|
||||||
installOptions = installOptions || {};
|
installOptions = installOptions || {};
|
||||||
installOptions.variables = installOptions.variables || {};
|
installOptions.variables = installOptions.variables || {};
|
||||||
|
// Add PACKAGE_NAME variable into vars
|
||||||
|
if (!installOptions.variables.PACKAGE_NAME) {
|
||||||
|
installOptions.variables.PACKAGE_NAME = project.getPackageName();
|
||||||
|
}
|
||||||
|
|
||||||
var self = this;
|
return PluginManager.get(this.platform, this.locations, project)
|
||||||
var actions = new ActionStack();
|
.addPlugin(plugin, installOptions)
|
||||||
var project = AndroidProject.getProjectFile(this.root);
|
.then(function () {
|
||||||
|
if (plugin.getFrameworks(this.platform).length === 0) return;
|
||||||
|
|
||||||
// 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(
|
|
||||||
pluginHandlers.getInstaller(item.itemType), [item, plugin, project, installOptions],
|
|
||||||
pluginHandlers.getUninstaller(item.itemType), [item, plugin, project, installOptions]));
|
|
||||||
});
|
|
||||||
|
|
||||||
// run through the action stack
|
|
||||||
return actions.process(this.platform)
|
|
||||||
.then(function () {
|
|
||||||
if (project) {
|
|
||||||
project.write();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add PACKAGE_NAME variable into vars
|
|
||||||
if (!installOptions.variables.PACKAGE_NAME) {
|
|
||||||
installOptions.variables.PACKAGE_NAME = project.getPackageName();
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
if (plugin.getFrameworks(self.platform).length > 0) {
|
|
||||||
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
||||||
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
|
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
|
||||||
}
|
}.bind(this))
|
||||||
|
// CB-11022 Return truthy value to prevent running prepare after
|
||||||
var targetDirs = [self.locations.www];
|
.thenResolve(true);
|
||||||
// CB-11022 if usePlatformWww is specified we need to mirror modules metadata to both directories
|
|
||||||
if (installOptions.usePlatformWww) targetDirs.push(self.locations.platformWww);
|
|
||||||
self._addModulesInfo(plugin, targetDirs);
|
|
||||||
|
|
||||||
// CB-11022 Indicate to caller that we have copied js-files and assets
|
|
||||||
// to both 'www' and 'platform_www' so prepare is not needed
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -266,51 +220,17 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
|
|||||||
* CordovaError instance.
|
* CordovaError instance.
|
||||||
*/
|
*/
|
||||||
Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
||||||
|
|
||||||
if (!plugin || plugin.constructor.name !== 'PluginInfo')
|
|
||||||
return Q.reject(new CordovaError('The parameter is incorrect. The first parameter to addPlugin should be a PluginInfo instance'));
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
var actions = new ActionStack();
|
|
||||||
var project = AndroidProject.getProjectFile(this.root);
|
var project = AndroidProject.getProjectFile(this.root);
|
||||||
|
return PluginManager.get(this.platform, this.locations, project)
|
||||||
|
.removePlugin(plugin, uninstallOptions)
|
||||||
|
.then(function () {
|
||||||
|
if (plugin.getFrameworks(this.platform).length === 0) return;
|
||||||
|
|
||||||
// queue up plugin files
|
this.events.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
||||||
plugin.getFilesAndFrameworks(this.platform)
|
|
||||||
.concat(plugin.getAssets(this.platform))
|
|
||||||
.concat(plugin.getJsModules(this.platform))
|
|
||||||
.forEach(function(item) {
|
|
||||||
actions.push(actions.createAction(
|
|
||||||
pluginHandlers.getUninstaller(item.itemType), [item, plugin, project, uninstallOptions],
|
|
||||||
pluginHandlers.getInstaller(item.itemType), [item, plugin, project, uninstallOptions]));
|
|
||||||
});
|
|
||||||
|
|
||||||
// run through the action stack
|
|
||||||
return actions.process(this.platform)
|
|
||||||
.then(function() {
|
|
||||||
if (project) {
|
|
||||||
project.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();
|
|
||||||
|
|
||||||
if (plugin.getFrameworks(self.platform).length > 0) {
|
|
||||||
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
|
||||||
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
|
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
|
||||||
}
|
}.bind(this))
|
||||||
|
// CB-11022 Return truthy value to prevent running prepare after
|
||||||
var targetDirs = [self.locations.www];
|
.thenResolve(true);
|
||||||
// CB-11022 if usePlatformWww is specified we need to mirror modules metadata to both directories
|
|
||||||
if (uninstallOptions.usePlatformWww) targetDirs.push(self.locations.platformWww);
|
|
||||||
self._removeModulesInfo(plugin, targetDirs);
|
|
||||||
|
|
||||||
// CB-11022 Indicate to caller that we have copied js-files and assets
|
|
||||||
// to both 'www' and 'platform_www' so prepare is not needed
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -424,105 +344,3 @@ Api.prototype.requirements = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Api;
|
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
|
|
||||||
};
|
|
||||||
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 directories, 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 cordova_plugins.js file at specified directories.
|
|
||||||
*
|
|
||||||
* @param {String[]} targetDirs Directories, where write cordova_plugins.js to.
|
|
||||||
* Ususally it is either <platform>/www or <platform>/platform_www or both.
|
|
||||||
*/
|
|
||||||
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');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
9
bin/templates/cordova/lib/AndroidProject.js
vendored
9
bin/templates/cordova/lib/AndroidProject.js
vendored
@ -21,6 +21,7 @@ var fs = require('fs');
|
|||||||
var path = require('path');
|
var path = require('path');
|
||||||
var properties_parser = require('properties-parser');
|
var properties_parser = require('properties-parser');
|
||||||
var AndroidManifest = require('./AndroidManifest');
|
var AndroidManifest = require('./AndroidManifest');
|
||||||
|
var pluginHandlers = require('./pluginHandlers');
|
||||||
|
|
||||||
var projectFileCache = {};
|
var projectFileCache = {};
|
||||||
|
|
||||||
@ -180,5 +181,13 @@ AndroidProject.prototype._getPropertiesFile = function (filename) {
|
|||||||
return this._propertiesEditors[filename];
|
return this._propertiesEditors[filename];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AndroidProject.prototype.getInstaller = function (type) {
|
||||||
|
return pluginHandlers.getInstaller(type);
|
||||||
|
};
|
||||||
|
|
||||||
|
AndroidProject.prototype.getUninstaller = function (type) {
|
||||||
|
return pluginHandlers.getUninstaller(type);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = AndroidProject;
|
module.exports = AndroidProject;
|
||||||
|
9
bin/templates/cordova/lib/prepare.js
vendored
9
bin/templates/cordova/lib/prepare.js
vendored
@ -26,13 +26,18 @@ var AndroidManifest = require('./AndroidManifest');
|
|||||||
var xmlHelpers = require('cordova-common').xmlHelpers;
|
var xmlHelpers = require('cordova-common').xmlHelpers;
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
var ConfigParser = require('cordova-common').ConfigParser;
|
var ConfigParser = require('cordova-common').ConfigParser;
|
||||||
|
var PlatformJson = require('cordova-common').PlatformJson;
|
||||||
|
var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger;
|
||||||
|
var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
|
||||||
|
|
||||||
module.exports.prepare = function (cordovaProject) {
|
module.exports.prepare = function (cordovaProject) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this._config = updateConfigFilesFrom(cordovaProject.projectConfig,
|
var platformJson = PlatformJson.load(this.locations.root, this.platform);
|
||||||
this._munger, this.locations);
|
var munger = new PlatformMunger(this.platform, this.locations.root, platformJson, new PluginInfoProvider());
|
||||||
|
|
||||||
|
this._config = updateConfigFilesFrom(cordovaProject.projectConfig, munger, this.locations);
|
||||||
|
|
||||||
// Update own www dir with project's www assets and plugins' assets and js-files
|
// Update own www dir with project's www assets and plugins' assets and js-files
|
||||||
return Q.when(updateWwwFrom(cordovaProject, this.locations))
|
return Q.when(updateWwwFrom(cordovaProject, this.locations))
|
||||||
|
@ -36,20 +36,16 @@ describe('addPlugin method', function () {
|
|||||||
var api, fail, gradleBuilder;
|
var api, fail, gradleBuilder;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
var ActionStack = jasmine.createSpyObj('ActionStack', ['createAction', 'push', 'process']);
|
var pluginManager = jasmine.createSpyObj('pluginManager', ['addPlugin']);
|
||||||
ActionStack.process.andReturn(Q());
|
pluginManager.addPlugin.andReturn(Q());
|
||||||
spyOn(common, 'ActionStack').andReturn(ActionStack);
|
spyOn(common.PluginManager, 'get').andReturn(pluginManager);
|
||||||
|
|
||||||
spyOn(AndroidProject, 'getProjectFile')
|
var projectSpy = jasmine.createSpyObj('AndroidProject', ['getPackageName', 'write']);
|
||||||
.andReturn(jasmine.createSpyObj('AndroidProject', ['getPackageName', 'write']));
|
spyOn(AndroidProject, 'getProjectFile').andReturn(projectSpy);
|
||||||
|
|
||||||
var Api = require('../../bin/templates/cordova/Api');
|
var Api = require('../../bin/templates/cordova/Api');
|
||||||
api = new Api('android', FAKE_PROJECT_DIR);
|
api = new Api('android', FAKE_PROJECT_DIR);
|
||||||
|
|
||||||
spyOn(api, '_addModulesInfo');
|
|
||||||
spyOn(api._munger, 'add_plugin_changes')
|
|
||||||
.andReturn(jasmine.createSpyObj('munger', ['save_all']));
|
|
||||||
|
|
||||||
fail = jasmine.createSpy('fail');
|
fail = jasmine.createSpy('fail');
|
||||||
gradleBuilder = jasmine.createSpyObj('gradleBuilder', ['prepBuildFiles']);
|
gradleBuilder = jasmine.createSpyObj('gradleBuilder', ['prepBuildFiles']);
|
||||||
spyOn(builders, 'getBuilder').andReturn(gradleBuilder);
|
spyOn(builders, 'getBuilder').andReturn(gradleBuilder);
|
||||||
|
Loading…
Reference in New Issue
Block a user