You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by an...@apache.org on 2014/04/11 21:46:31 UTC
[15/50] [abbrv] Refactoring of install & uninstall tests
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ae2ce7ac/src/install.js
----------------------------------------------------------------------
diff --git a/src/install.js b/src/install.js
index 0949068..1a82f65 100644
--- a/src/install.js
+++ b/src/install.js
@@ -9,7 +9,11 @@ var path = require('path'),
Q = require('q'),
platform_modules = require('./platforms'),
os = require('os'),
- isWindows = (os.platform() === 'win32');
+ underscore = require('underscore'),
+ shell = require('shelljs'),
+ events = require('./events'),
+ plugman = require('../plugman'),
+ isWindows = (os.platform().substr(0,3) === 'win');
/* INSTALL FLOW
------------
@@ -36,11 +40,15 @@ var path = require('path'),
// Returns a promise.
module.exports = function installPlugin(platform, project_dir, id, plugins_dir, options) {
options = options || {};
+ options.is_top_level = true;
+ plugins_dir = plugins_dir || path.join(project_dir, 'cordova', 'plugins');
+
if (!platform_modules[platform]) {
return Q.reject(new Error(platform + " not supported."));
}
+
var current_stack = new action_stack();
- options.is_top_level = true;
+
return possiblyFetch(id, plugins_dir, options)
.then(function(plugin_dir) {
return runInstall(current_stack, platform, project_dir, plugin_dir, plugins_dir, options);
@@ -50,26 +58,31 @@ module.exports = function installPlugin(platform, project_dir, id, plugins_dir,
// possible options: subdir, cli_variables, www_dir, git_ref, is_top_level
// Returns a promise.
function possiblyFetch(id, plugins_dir, options) {
- var plugin_dir = path.join(plugins_dir, id);
+
+ // if plugin is a relative path, check if it already exists
+ var plugin_src_dir = path.join(plugins_dir, id);
+ if( isAbsolutePath(id) )
+ plugin_src_dir = id;
// Check that the plugin has already been fetched.
- if (fs.existsSync(plugin_dir)) {
- return Q(plugin_dir);
+ if (fs.existsSync(plugin_src_dir)) {
+ return Q(plugin_src_dir);
}
- var opts = {
- link: false,
- subdir: options.subdir,
- git_ref: options.git_ref,
- client: 'plugman',
- expected_id: options.expected_id,
- searchpath: options.searchpath
- };
- return require('../plugman').raw.fetch(id, plugins_dir, opts);
+
+ var opts = underscore.extend({}, options, {
+ link: false,
+ client: 'plugman'
+ });
+
+ // if plugin doesnt exist, use fetch to get it.
+ return plugman.raw.fetch(id, plugins_dir, opts);
}
function checkEngines(engines) {
+
for(var i = 0; i < engines.length; i++) {
var engine = engines[i];
+
if(semver.satisfies(engine.currentVersion, engine.minVersion) || engine.currentVersion === null){
// engine ok!
}else{
@@ -88,15 +101,13 @@ function cleanVersionOutput(version, name){
out = out.substr(0, rc_index) + '-' + out.substr(rc_index);
}
- // strip out the -dev and put a warning about using the dev branch
+ // put a warning about using the dev branch
if (dev_index > -1) {
// some platform still lists dev branches as just dev, set to null and continue
if(out=="dev"){
out = null;
- }else{
- out = out.substr(0, dev_index-1);
}
- require('../plugman').emit('verbose', name+' has been detected as using a development branch. Attemping to install anyways.');
+ events.emit('verbose', name+' has been detected as using a development branch. Attemping to install anyways.');
}
// add extra period/digits to conform to semver - some version scripts will output
@@ -124,29 +135,36 @@ function callEngineScripts(engines) {
return Q.all(
engines.map(function(engine){
// CB-5192; on Windows scriptSrc doesn't have file extension so we shouldn't check whether the script exists
- if(isWindows || fs.existsSync(engine.scriptSrc)){
+ var scriptPath = engine.scriptSrc ? '"' + engine.scriptSrc + '"' : null;
+
+ if(scriptPath && (isWindows || fs.existsSync(engine.scriptSrc)) ) {
+
+ var d = Q.defer();
if(!isWindows) { // not required on Windows
fs.chmodSync(engine.scriptSrc, '755');
}
- var d = Q.defer();
- child_process.exec('"' + engine.scriptSrc + '"', function(error, stdout, stderr) {
+ child_process.exec(scriptPath, function(error, stdout, stderr) {
if (error) {
- require('../plugman').emit('log', 'Cordova project '+ engine.scriptSrc +' script failed, continuing anyways.');
+ events.emit('warn', engine.name +' version check failed ('+ scriptPath +'), continuing anyways.');
engine.currentVersion = null;
- d.resolve(engine); // Yes, resolve. We're trying to continue despite the error.
} else {
- var version = cleanVersionOutput(stdout, engine.name);
- engine.currentVersion = version;
- d.resolve(engine);
+ engine.currentVersion = cleanVersionOutput(stdout, engine.name);
}
+
+ d.resolve(engine);
});
return d.promise;
- }else if(engine.currentVersion){
- return cleanVersionOutput(engine.currentVersion, engine.name)
- }else{
- require('../plugman').emit('verbose', 'Cordova project '+ engine.scriptSrc +' not detected (lacks a '+ engine.scriptSrc +' script), continuing.');
- return null;
+
+ } else {
+
+ if(engine.currentVersion) {
+ engine.currentVersion = cleanVersionOutput(engine.currentVersion, engine.name)
+ } else {
+ events.emit('warn', engine.name +' version not detected (lacks script '+ scriptPath +' ), continuing.');
+ }
+
+ return Q(engine);
}
})
);
@@ -159,6 +177,7 @@ function getEngines(pluginElement, platform, project_dir, plugin_dir){
var uncheckedEngines = [];
var cordovaEngineIndex, cordovaPlatformEngineIndex, theName, platformIndex, defaultPlatformIndex;
// load in known defaults and update when necessary
+
engines.forEach(function(engine){
theName = engine.attrib["name"];
@@ -210,7 +229,7 @@ function isPluginInstalled(plugins_dir, platform, plugin_id) {
// possible options: cli_variables, www_dir, is_top_level
// Returns a promise.
-var runInstall = module.exports.runInstall = function runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, options, graph) {
+var runInstall = module.exports.runInstall = function runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, options) {
var xml_path = path.join(plugin_dir, 'plugin.xml')
, plugin_et = xml_helpers.parseElementtreeSync(xml_path)
, filtered_variables = {};
@@ -218,146 +237,228 @@ var runInstall = module.exports.runInstall = function runInstall(actions, platfo
var plugin_id = plugin_et.getroot().attrib['id'];
options = options || {};
- graph = graph || new dep_graph();
+ options.graph = options.graph || new dep_graph();
if (isPluginInstalled(plugins_dir, platform, plugin_id)) {
if (options.is_top_level) {
- require('../plugman').emit('results', 'Plugin "' + plugin_id + '" already installed on ' + platform + '.');
+ events.emit('results', 'Plugin "' + plugin_id + '" already installed on ' + platform + '.');
} else {
- require('../plugman').emit('verbose', 'Dependent plugin "' + plugin_id + '" already installed on ' + platform + '.');
+ events.emit('verbose', 'Dependent plugin "' + plugin_id + '" already installed on ' + platform + '.');
}
return Q();
}
- require('../plugman').emit('log', 'Installing ' + plugin_id + ' (' + platform + ')');
-
- var plugin_basename = path.basename(plugin_dir);
+ events.emit('log', 'Installing "' + plugin_id + '" for ' + platform);
var theEngines = getEngines(plugin_et, platform, project_dir, plugin_dir);
+
+ var install = {
+ actions: actions,
+ platform: platform,
+ project_dir: project_dir,
+ plugins_dir: plugins_dir,
+ top_plugin_id: plugin_id,
+ top_plugin_dir: plugin_dir
+ }
+
return callEngineScripts(theEngines)
.then(checkEngines)
- .then(function() {
- // checking preferences, if certain variables are not provided, we should throw.
- var prefs = plugin_et.findall('./preference') || [];
- prefs = prefs.concat(plugin_et.findall('./platform[@name="'+platform+'"]/preference'));
- var missing_vars = [];
- prefs.forEach(function (pref) {
- var key = pref.attrib["name"].toUpperCase();
- options.cli_variables = options.cli_variables || {};
- if (options.cli_variables[key] === undefined)
- missing_vars.push(key)
- else
- filtered_variables[key] = options.cli_variables[key]
- });
- if (missing_vars.length > 0) {
- return Q.reject(new Error('Variable(s) missing: ' + missing_vars.join(", ")));
+ .then(
+ function() {
+ // checking preferences, if certain variables are not provided, we should throw.
+ var prefs = plugin_et.findall('./preference') || [];
+ prefs = prefs.concat(plugin_et.findall('./platform[@name="'+platform+'"]/preference'));
+ var missing_vars = [];
+ prefs.forEach(function (pref) {
+ var key = pref.attrib["name"].toUpperCase();
+ options.cli_variables = options.cli_variables || {};
+ if (options.cli_variables[key] === undefined)
+ missing_vars.push(key)
+ else
+ filtered_variables[key] = options.cli_variables[key]
+ });
+ install.filtered_variables = filtered_variables;
+
+ if (missing_vars.length > 0) {
+ throw new Error('Variable(s) missing: ' + missing_vars.join(", "));
+ }
+
+ // Check for dependencies
+ var dependencies = plugin_et.findall('dependency') || [];
+ dependencies = dependencies.concat(plugin_et.findall('./platform[@name="'+platform+'"]/dependency'));
+ if(dependencies && dependencies.length)
+ return installDependencies(install, dependencies, options);
+
+ return Q(true);
+ }
+ ).then(
+ function(){
+ var install_plugin_dir = path.join(plugins_dir, plugin_id);
+
+ // may need to copy to destination...
+ if ( !fs.existsSync(install_plugin_dir) ) {
+ copyPlugin(plugin_dir, plugins_dir, options.link);
+ }
+
+ return handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plugins_dir, install_plugin_dir, filtered_variables, options.www_dir, options.is_top_level);
+ }
+ ).fail(
+ function (error) {
+ events.emit('warn', "Failed to install '"+plugin_id+"':"+ error.stack);
+ return Q(false);
}
+ );
+}
- // Check for dependencies, (co)recurse to install each one
- var dependencies = plugin_et.findall('dependency') || [];
- dependencies = dependencies.concat(plugin_et.findall('./platform[@name="'+platform+'"]/dependency'));
- if (dependencies && dependencies.length) {
- require('../plugman').emit('verbose', 'Dependencies detected, iterating through them...');
- var dep_plugin_id, dep_subdir, dep_git_ref;
- return dependencies.reduce(function (soFar, dep) {
+function installDependencies(install, dependencies, options) {
+ events.emit('verbose', 'Dependencies detected, iterating through them...');
+
+ var top_plugins = path.join(install.top_plugin_dir, '..');
+
+ // Add directory of top-level plugin to search path
+ options.searchpath = options.searchpath || [];
+ if( top_plugins != install.plugins_dir && options.searchpath.indexOf(top_plugins) == -1 )
+ options.searchpath.push(top_plugins);
+
+ // Search for dependency by Id is:
+ // a) Look for {$top_plugins}/{$depId} directory
+ // b) Scan the top level plugin directory {$top_plugins} for matching id (searchpath)
+ // c) Fetch from registry
+
+ return dependencies.reduce(function(soFar, depXml) {
+ return soFar.then(
+ function() {
+ var dep = {
+ id: depXml.attrib.id,
+ subdir: depXml.attrib.subdir,
+ url: depXml.attrib.url || '',
+ git_ref: depXml.attrib.commit
+ }
+
+ if (dep.subdir) {
+ dep.subdir = path.join(dep.subdir.split('/'));
+ }
// We build the dependency graph only to be able to detect cycles, getChain will throw an error if it detects one
- graph.add(plugin_id, dep.attrib.id);
- graph.getChain(plugin_id);
- return soFar.then(function() {
- dep_plugin_id = dep.attrib.id;
- dep_subdir = dep.attrib.subdir;
- var dep_url = dep.attrib.url;
- dep_git_ref = dep.attrib.commit;
- if (dep_subdir) {
- dep_subdir = path.join.apply(null, dep_subdir.split('/'));
+ options.graph.add(install.top_plugin_id, dep.id);
+ options.graph.getChain(install.top_plugin_id);
+
+ return tryFetchDependency(dep, install)
+ .then(
+ function(url){
+ dep.url = url;
+ return installDependency(dep, install, options);
}
+ );
+ }
+ );
- // Handle relative dependency paths by expanding and resolving them.
- // The easy case of relative paths is to have a URL of '.' and a different subdir.
- // TODO: Implement the hard case of different repo URLs, rather than the special case of
- // same-repo-different-subdir.
- if (dep_url == '.') {
- // Look up the parent plugin's fetch metadata and determine the correct URL.
- var fetchdata = require('./util/metadata').get_fetch_metadata(plugin_dir);
-
- if (!fetchdata || !(fetchdata.source && fetchdata.source.type)) {
- return Q.reject(new Error('No fetch metadata found for ' + plugin_id + '. Cannot install relative dependencies.'));
- }
-
- // Now there are two cases here: local directory, and git URL.
- if (fetchdata.source.type === 'local') {
- dep_url = fetchdata.source.path;
-
- var d = Q.defer();
- child_process.exec('git rev-parse --show-toplevel', { cwd:dep_url }, function(err, stdout, stderr) {
- if (err) {
- if (err.code == 128) {
- return d.reject(new Error('Plugin ' + plugin_id + ' is not in git repository. All plugins must be in a git repository.'));
- } else {
- return d.reject(new Error('Failed to locate git repository for ' + plugin_id + ' plugin.'));
- }
- }
-
- return d.resolve(stdout.trim());
- });
- return d.promise.then(function(git_repo) {
- //Clear out the subdir since the url now contains it
- var url = path.join(git_repo, dep_subdir);
- dep_subdir = "";
- return url;
- });
- } else if (fetchdata.source.type === 'git') {
- return Q(fetchdata.source.url);
- }
- } else {
- return Q(dep_url);
- }
- })
- .then(function(dep_url) {
- var dep_plugin_dir = path.join(plugins_dir, dep_plugin_id);
- if (fs.existsSync(dep_plugin_dir)) {
- require('../plugman').emit('verbose', 'Dependent plugin "' + dep_plugin_id + '" already fetched, using that version.');
- var opts = {
- cli_variables: filtered_variables,
- www_dir: options.www_dir,
- is_top_level: false
- };
- return runInstall(actions, platform, project_dir, dep_plugin_dir, plugins_dir, opts, graph);
+ }, Q(true));
+}
+
+function tryFetchDependency(dep, install) {
+
+ // Handle relative dependency paths by expanding and resolving them.
+ // The easy case of relative paths is to have a URL of '.' and a different subdir.
+ // TODO: Implement the hard case of different repo URLs, rather than the special case of
+ // same-repo-different-subdir.
+ if ( dep.url == '.' ) {
+
+ // Look up the parent plugin's fetch metadata and determine the correct URL.
+ var fetchdata = require('./util/metadata').get_fetch_metadata(install.top_plugin_dir);
+ if (!fetchdata || !(fetchdata.source && fetchdata.source.type)) {
+ throw new Error('No fetch metadata found for plugin ' + install.top_plugin_id + '. Cannot install relative dependency --> ' + dep.id);
+ }
+
+ // Now there are two cases here: local directory, and git URL.
+ var d = Q.defer();
+
+ if (fetchdata.source.type === 'local') {
+
+ dep.url = fetchdata.source.path;
+
+ child_process.exec('git rev-parse --show-toplevel', { cwd:dep.url }, function(err, stdout, stderr) {
+ if (err) {
+ if (err.code == 128) {
+ return d.reject(new Error('Plugin ' + dep.id + ' is not in git repository. All plugins must be in a git repository.'));
} else {
- require('../plugman').emit('verbose', 'Dependent plugin "' + dep_plugin_id + '" not fetched, retrieving then installing.');
- var opts = {
- cli_variables: filtered_variables,
- www_dir: options.www_dir,
- is_top_level: false,
- subdir: dep_subdir,
- git_ref: dep_git_ref,
- expected_id: dep_plugin_id,
- searchpath: options.searchpath
- };
-
- // CB-4770: registry fetching
- if(dep_url === undefined) {
- dep_url = dep_plugin_id;
- }
-
- return possiblyFetch(dep_url, plugins_dir, opts)
- .then(function(plugin_dir) {
- return runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, opts, graph);
- });
+ return d.reject(new Error('Failed to locate git repository for ' + dep.id + ' plugin.'));
}
- });
- }, Q())
- .then(function() {
- return handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_basename, plugin_dir, filtered_variables, options.www_dir, options.is_top_level);
+ }
+ return d.resolve(stdout.trim());
});
- } else {
- return handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_basename, plugin_dir, filtered_variables, options.www_dir, options.is_top_level);
+
+ return d.promise.then(function(git_repo) {
+ //Clear out the subdir since the url now contains it
+ var url = path.join(git_repo, dep.subdir);
+ dep.subdir = "";
+ return Q(url);
+ }).fail(function(error){
+//console.log("Failed to resolve url='.': " + error);
+ return Q(dep.url);
+ });
+
+ } else if (fetchdata.source.type === 'git') {
+ return Q(fetchdata.source.url);
}
- });
+ }
+
+ // Test relative to parent folder
+ if( dep.url && isRelativePath(dep.url) ) {
+ var relativePath = path.resolve(install.top_plugin_dir, '../' + dep.url);
+
+ if( fs.existsSync(relativePath) ) {
+ dep.url = relativePath;
+ }
+ }
+
+ // CB-4770: registry fetching
+ if(dep.url === undefined) {
+ dep.url = dep.plugin_id;
+ }
+
+ return Q(dep.url);
}
-function handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_basename, plugin_dir, filtered_variables, www_dir, is_top_level) {
- require('../plugman').emit('verbose', 'Installing plugin ' + plugin_id);
+function installDependency(dep, install, options) {
+
+ dep.install_dir = path.join(install.plugins_dir, dep.id);
+
+ if ( fs.existsSync(dep.install_dir) ) {
+ events.emit('verbose', 'Dependent plugin "' + dep.id + '" already fetched, using that version.');
+ var opts = underscore.extend({}, options, {
+ cli_variables: install.filtered_variables,
+ is_top_level: false
+ });
+
+ return runInstall(install.actions, install.platform, install.project_dir, dep.install_dir, install.plugins_dir, opts);
+
+ } else {
+ events.emit('verbose', 'Dependent plugin "' + dep.id + '" not fetched, retrieving then installing.');
+
+ var opts = underscore.extend({}, options, {
+ cli_variables: install.filtered_variables,
+ is_top_level: false,
+ subdir: dep.subdir,
+ git_ref: dep.git_ref,
+ expected_id: dep.id
+ });
+
+ var dep_src = dep.url.length ? dep.url : dep.id;
+
+ return possiblyFetch(dep_src, install.plugins_dir, opts)
+ .then(
+ function(plugin_dir) {
+ return runInstall(install.actions, install.platform, install.project_dir, plugin_dir, install.plugins_dir, opts);
+ }
+ );
+ };
+}
+
+function handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_dir, filtered_variables, www_dir, is_top_level) {
+
+ // @tests - important this event is checked spec/install.spec.js
+ events.emit('verbose', 'Install start for "' + plugin_id + '" on ' + platform + '.');
+
var handler = platform_modules[platform];
www_dir = www_dir || handler.www_dir(project_dir);
@@ -415,20 +516,20 @@ function handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plu
return actions.process(platform, project_dir)
.then(function(err) {
// queue up the plugin so prepare knows what to do.
- config_changes.add_installed_plugin_to_prepare_queue(plugins_dir, plugin_basename, platform, filtered_variables, is_top_level);
+ config_changes.add_installed_plugin_to_prepare_queue(plugins_dir, plugin_id, platform, filtered_variables, is_top_level);
// call prepare after a successful install
- require('./../plugman').prepare(project_dir, platform, plugins_dir, www_dir);
+ plugman.prepare(project_dir, platform, plugins_dir, www_dir);
- require('../plugman').emit('verbose', 'Install complete for ' + plugin_id + ' on ' + platform + '.');
+ events.emit('verbose', 'Install complete for ' + plugin_id + ' on ' + platform + '.');
// WIN!
// Log out plugin INFO element contents in case additional install steps are necessary
var info = plugin_et.findall('./info');
if(info.length) {
- require('../plugman').emit('results', interp_vars(filtered_variables, info[0].text));
+ events.emit('results', interp_vars(filtered_variables, info[0].text));
}
info = (platformTag ? platformTag.findall('./info') : []);
if(info.length) {
- require('../plugman').emit('results', interp_vars(filtered_variables, info[0].text));
+ events.emit('results', interp_vars(filtered_variables, info[0].text));
}
});
}
@@ -440,3 +541,52 @@ function interp_vars(vars, text) {
});
return text;
}
+
+function isAbsolutePath(path) {
+ return path && (path[0] === '/' || path[0] === '\\' || path.indexOf(':\\') > 0 );
+}
+
+function isRelativePath(path) {
+ return !isAbsolutePath();
+}
+
+function readId(plugin_dir) {
+ var xml_path = path.join(plugin_dir, 'plugin.xml');
+ events.emit('verbose', 'Fetch is reading plugin.xml from location "' + xml_path + '"...');
+ var et = xml_helpers.parseElementtreeSync(xml_path);
+
+ return et.getroot().attrib.id;
+}
+
+// Copy or link a plugin from plugin_dir to plugins_dir/plugin_id.
+function copyPlugin(plugin_src_dir, plugins_dir, link) {
+ var plugin_id = readId(plugin_src_dir);
+ var dest = path.join(plugins_dir, plugin_id);
+ shell.rm('-rf', dest);
+
+ if (link) {
+ events.emit('verbose', 'Symlinking from location "' + plugin_src_dir + '" to location "' + dest + '"');
+ fs.symlinkSync(plugin_src_dir, dest, 'dir');
+ } else {
+ shell.mkdir('-p', dest);
+ events.emit('verbose', 'Copying from location "' + plugin_src_dir + '" to location "' + dest + '"');
+ shell.cp('-R', path.join(plugin_src_dir, '*') , dest);
+ }
+
+ return dest;
+}
+
+function isPluginInstalled(plugins_dir, platform, plugin_id) {
+ var platform_config = config_changes.get_platform_json(plugins_dir, platform);
+ for (var installed_plugin_id in platform_config.installed_plugins) {
+ if (installed_plugin_id == plugin_id) {
+ return true;
+ }
+ }
+ for (var installed_plugin_id in platform_config.dependent_plugins) {
+ if (installed_plugin_id == plugin_id) {
+ return true;
+ }
+ }
+ return false;
+}
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ae2ce7ac/src/platforms/android.js
----------------------------------------------------------------------
diff --git a/src/platforms/android.js b/src/platforms/android.js
index 038f92d..e396680 100644
--- a/src/platforms/android.js
+++ b/src/platforms/android.js
@@ -37,9 +37,8 @@ module.exports = {
"source-file":{
install:function(source_el, plugin_dir, project_dir, plugin_id) {
var dest = path.join(source_el.attrib['target-dir'], path.basename(source_el.attrib['src']));
- var target_path = common.resolveTargetPath(project_dir, dest);
- if (fs.existsSync(target_path)) throw new Error('"' + target_path + '" already exists!');
- common.copyFile(plugin_dir, source_el.attrib['src'], project_dir, dest);
+
+ common.copyNewFile(plugin_dir, source_el.attrib['src'], project_dir, dest);
},
uninstall:function(source_el, project_dir, plugin_id) {
var dest = path.join(source_el.attrib['target-dir'], path.basename(source_el.attrib['src']));
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ae2ce7ac/src/platforms/blackberry10.js
----------------------------------------------------------------------
diff --git a/src/platforms/blackberry10.js b/src/platforms/blackberry10.js
index d3709c0..d9e93ad 100644
--- a/src/platforms/blackberry10.js
+++ b/src/platforms/blackberry10.js
@@ -39,9 +39,8 @@ module.exports = {
var target = source_el.attrib['target-dir'] || plugin_id;
TARGETS.forEach(function(arch) {
var dest = path.join("native", arch, "chrome", "plugin", target, path.basename(src));
- var target_path = common.resolveTargetPath(project_dir, dest);
- if (fs.existsSync(target_path)) throw new Error('"' + target_path + '" already exists!');
- common.copyFile(plugin_dir, src, project_dir, dest);
+
+ common.copyNewFile(plugin_dir, src, project_dir, dest);
});
},
uninstall:function(source_el, project_dir, plugin_id) {
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ae2ce7ac/src/platforms/common.js
----------------------------------------------------------------------
diff --git a/src/platforms/common.js b/src/platforms/common.js
index 671e722..8fe1730 100644
--- a/src/platforms/common.js
+++ b/src/platforms/common.js
@@ -1,8 +1,9 @@
var shell = require('shelljs'),
path = require('path'),
- fs = require('fs');
+ fs = require('fs'),
+ common;
-module.exports = {
+module.exports = common = {
// helper for resolving source paths from plugin.xml
resolveSrcPath:function(plugin_dir, relative_path) {
var full_path = path.resolve(plugin_dir, relative_path);
@@ -22,11 +23,19 @@ module.exports = {
// XXX sheljs decides to create a directory when -R|-r is used which sucks. http://goo.gl/nbsjq
if(fs.statSync(src).isDirectory()) {
- shell.cp('-R', src+'/*', dest);
+ shell.cp('-Rf', src+'/*', dest);
} else {
shell.cp('-f', src, dest);
}
},
+ // Same as copy file but throws error if target exists
+ copyNewFile:function(plugin_dir, src, project_dir, dest) {
+ var target_path = common.resolveTargetPath(project_dir, dest);
+ if (fs.existsSync(target_path))
+ throw new Error('"' + target_path + '" already exists!');
+
+ common.copyFile(plugin_dir, src, project_dir, dest);
+ },
// checks if file exists and then deletes. Error if doesn't exist
removeFile:function(project_dir, src) {
var file = module.exports.resolveSrcPath(project_dir, src);
@@ -41,7 +50,7 @@ module.exports = {
var file = path.resolve(project_dir, destFile);
if (!fs.existsSync(file)) return;
- module.exports.removeFileF(file);
+ common.removeFileF(file);
// check if directory is empty
var curDir = path.dirname(file);
@@ -69,7 +78,7 @@ module.exports = {
throw new Error('<asset> tag without required "target" attribute');
}
- module.exports.copyFile(plugin_dir, src, www_dir, target);
+ common.copyFile(plugin_dir, src, www_dir, target);
},
uninstall:function(asset_el, www_dir, plugin_id) {
var target = asset_el.attrib.target || asset_el.attrib.src;
@@ -78,8 +87,8 @@ module.exports = {
throw new Error('<asset> tag without required "target" attribute');
}
- module.exports.removeFile(www_dir, target);
- module.exports.removeFileF(path.resolve(www_dir, 'plugins', plugin_id));
+ common.removeFile(www_dir, target);
+ common.removeFileF(path.resolve(www_dir, 'plugins', plugin_id));
}
}
};
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ae2ce7ac/src/platforms/windows8.js
----------------------------------------------------------------------
diff --git a/src/platforms/windows8.js b/src/platforms/windows8.js
index 287c048..2232192 100644
--- a/src/platforms/windows8.js
+++ b/src/platforms/windows8.js
@@ -47,9 +47,8 @@ module.exports = {
install:function(source_el, plugin_dir, project_dir, plugin_id, project_file) {
var targetDir = source_el.attrib['target-dir'] || '';
var dest = path.join('www', 'plugins', plugin_id, targetDir, path.basename(source_el.attrib['src']));
- var target_path = common.resolveTargetPath(project_dir, dest);
- if (fs.existsSync(target_path)) throw new Error('"' + target_path + '" already exists!');
- common.copyFile(plugin_dir, source_el.attrib['src'], project_dir, dest);
+
+ common.copyNewFile(plugin_dir, source_el.attrib['src'], project_dir, dest);
// add reference to this file to jsproj.
project_file.addSourceFile(dest);
},
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ae2ce7ac/src/platforms/wp7.js
----------------------------------------------------------------------
diff --git a/src/platforms/wp7.js b/src/platforms/wp7.js
index b60697c..ebbd862 100644
--- a/src/platforms/wp7.js
+++ b/src/platforms/wp7.js
@@ -43,9 +43,8 @@ module.exports = {
"source-file":{
install:function(source_el, plugin_dir, project_dir, plugin_id, project_file) {
var dest = path.join('Plugins', plugin_id, source_el.attrib['target-dir'] ? source_el.attrib['target-dir'] : '', path.basename(source_el.attrib['src']));
- var target_path = common.resolveTargetPath(project_dir, dest);
- if (fs.existsSync(target_path)) throw new Error('"' + target_path + '" already exists!');
- common.copyFile(plugin_dir, source_el.attrib['src'], project_dir, dest);
+
+ common.copyNewFile(plugin_dir, source_el.attrib['src'], project_dir, dest);
// add reference to this file to csproj.
project_file.addSourceFile(dest);
},
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ae2ce7ac/src/platforms/wp8.js
----------------------------------------------------------------------
diff --git a/src/platforms/wp8.js b/src/platforms/wp8.js
index 4a74a1f..8eb62c2 100644
--- a/src/platforms/wp8.js
+++ b/src/platforms/wp8.js
@@ -43,9 +43,8 @@ module.exports = {
"source-file":{
install:function(source_el, plugin_dir, project_dir, plugin_id, project_file) {
var dest = path.join('Plugins', plugin_id, source_el.attrib['target-dir'] ? source_el.attrib['target-dir'] : '', path.basename(source_el.attrib['src']));
- var target_path = common.resolveTargetPath(project_dir, dest);
- if (fs.existsSync(target_path)) throw new Error('"' + target_path + '" already exists!');
- common.copyFile(plugin_dir, source_el.attrib['src'], project_dir, dest);
+
+ common.copyNewFile(plugin_dir, source_el.attrib['src'], project_dir, dest);
// add reference to this file to csproj.
project_file.addSourceFile(dest);
},
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ae2ce7ac/src/prepare.js
----------------------------------------------------------------------
diff --git a/src/prepare.js b/src/prepare.js
index 46e9487..3fbb7c0 100644
--- a/src/prepare.js
+++ b/src/prepare.js
@@ -30,6 +30,7 @@ var platform_modules = require('./platforms'),
fs = require('fs'),
shell = require('shelljs'),
util = require('util'),
+ events = require('./events'),
plugman = require('../plugman'),
et = require('elementtree');
@@ -47,7 +48,7 @@ module.exports = function handlePrepare(project_dir, platform, plugins_dir, www_
// - For each js-module (general first, then platform) build up an object storing the path and any clobbers, merges and runs for it.
// - Write this object into www/cordova_plugins.json.
// - Cordova.js contains code to load them at runtime from that file.
- plugman.emit('verbose', 'Preparing ' + platform + ' project');
+ events.emit('verbose', 'Preparing ' + platform + ' project');
var platform_json = config_changes.get_platform_json(plugins_dir, platform);
var wwwDir = www_dir || platform_modules[platform].www_dir(project_dir);
@@ -60,17 +61,15 @@ module.exports = function handlePrepare(project_dir, platform, plugins_dir, www_
plugins_to_uninstall.forEach(function(plug) {
var id = plug.id;
var plugin_modules = path.join(plugins_www, id);
- if (!fs.existsSync(plugin_modules)) {
- plugman.emit('verbose', 'There is no directory "'+plugin_modules+'"');
- return;
+ if (fs.existsSync(plugin_modules)) {
+ events.emit('verbose', 'Removing plugins directory from www "'+plugin_modules+'"');
+ shell.rm('-rf', plugin_modules);
}
- plugman.emit('verbose', 'Removing plugins directory from www "'+plugin_modules+'"');
- shell.rm('-rf', plugin_modules);
});
}
}
- plugman.emit('verbose', 'Processing configuration changes for plugins.');
+ events.emit('verbose', 'Processing configuration changes for plugins.');
config_changes.process(plugins_dir, project_dir, platform);
// for windows phone plaform we need to add all www resources to the .csproj file
@@ -123,7 +122,7 @@ module.exports = function handlePrepare(project_dir, platform, plugins_dir, www_
var plugins = Object.keys(platform_json.installed_plugins).concat(Object.keys(platform_json.dependent_plugins));
var moduleObjects = [];
var pluginMetadata = {};
- plugman.emit('verbose', 'Iterating over installed plugins:', plugins);
+ events.emit('verbose', 'Iterating over installed plugins:', plugins);
plugins && plugins.forEach(function(plugin) {
var pluginDir = path.join(plugins_dir, plugin),
@@ -155,7 +154,7 @@ module.exports = function handlePrepare(project_dir, platform, plugins_dir, www_
// Copy www assets described in <asset> tags.
assets = assets || [];
- assets.forEach(function(asset) {
+ assets.forEach(function(asset) {
common.asset.install(asset, pluginDir, wwwDir);
});
@@ -223,7 +222,7 @@ module.exports = function handlePrepare(project_dir, platform, plugins_dir, www_
final_contents += '// BOTTOM OF METADATA\n';
final_contents += '});'; // Close cordova.define.
- plugman.emit('verbose', 'Writing out cordova_plugins.js...');
+ events.emit('verbose', 'Writing out cordova_plugins.js...');
fs.writeFileSync(path.join(wwwDir, 'cordova_plugins.js'), final_contents, 'utf-8');
if(platform == 'wp7' || platform == 'wp8' || platform == "windows8") {
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ae2ce7ac/src/uninstall.js
----------------------------------------------------------------------
diff --git a/src/uninstall.js b/src/uninstall.js
index 0d55670..18d7a18 100644
--- a/src/uninstall.js
+++ b/src/uninstall.js
@@ -1,3 +1,4 @@
+
var path = require('path'),
fs = require('fs'),
et = require('elementtree'),
@@ -9,85 +10,124 @@ var path = require('path'),
underscore = require('underscore'),
Q = require('q'),
plugins = require('./util/plugins'),
- platform_modules = require('./platforms');
+ underscore = require('underscore'),
+ events = require('./events'),
+ platform_modules = require('./platforms'),
+ plugman = require('../plugman');
// possible options: cli_variables, www_dir
// Returns a promise.
module.exports = function(platform, project_dir, id, plugins_dir, options) {
+ options = options || {};
+ options.is_top_level = true;
+ plugins_dir = plugins_dir || path.join(project_dir, 'cordova', 'plugins');
+
+ // Allow path to file to grab an ID
+ var xml_path = path.join(id, 'plugin.xml');
+ if ( fs.existsSync(xml_path) ) {
+ var plugin_et = xml_helpers.parseElementtreeSync(xml_path),
+ id = plugin_et._root.attrib['id'];
+ }
+
return module.exports.uninstallPlatform(platform, project_dir, id, plugins_dir, options)
- .then(function(uninstalled) {
- return module.exports.uninstallPlugin(id, plugins_dir);
+ .then(function() {
+ return module.exports.uninstallPlugin(id, plugins_dir, options);
});
}
// Returns a promise.
module.exports.uninstallPlatform = function(platform, project_dir, id, plugins_dir, options) {
options = options || {};
+ options.is_top_level = true;
+ plugins_dir = plugins_dir || path.join(project_dir, 'cordova', 'plugins');
+
if (!platform_modules[platform]) {
return Q.reject(new Error(platform + " not supported."));
}
var plugin_dir = path.join(plugins_dir, id);
-
if (!fs.existsSync(plugin_dir)) {
return Q.reject(new Error('Plugin "' + id + '" not found. Already uninstalled?'));
}
var current_stack = new action_stack();
- options.is_top_level = true;
- return runUninstall(current_stack, platform, project_dir, plugin_dir, plugins_dir, options);
+ return runUninstallPlatform(current_stack, platform, project_dir, plugin_dir, plugins_dir, options);
};
// Returns a promise.
-module.exports.uninstallPlugin = function(id, plugins_dir) {
+module.exports.uninstallPlugin = function(id, plugins_dir, options) {
+ options = options || {};
+
var plugin_dir = path.join(plugins_dir, id);
+
// If already removed, skip.
if (!fs.existsSync(plugin_dir)) {
return Q();
}
- var xml_path = path.join(plugin_dir, 'plugin.xml')
- , plugin_et = xml_helpers.parseElementtreeSync(xml_path);
- require('../plugman').emit('log', 'Deleting plugin ' + id);
+ var xml_path = path.join(plugin_dir, 'plugin.xml')
+ , plugin_et = xml_helpers.parseElementtreeSync(xml_path);
+
+ events.emit('log', 'Deleting "'+ id +'"');
var doDelete = function(id) {
var plugin_dir = path.join(plugins_dir, id);
- if (!fs.existsSync(plugin_dir)) return;
+ if ( !fs.existsSync(plugin_dir) )
+ return;
+
shell.rm('-rf', plugin_dir);
- require('../plugman').emit('verbose', id + ' deleted.');
+ events.emit('verbose', '"'+ id +'" deleted.');
};
// We've now lost the metadata for the plugins that have been uninstalled, so we can't use that info.
// Instead, we list all dependencies of the target plugin, and check the remaining metadata to see if
// anything depends on them, or if they're listed as top-level.
// If neither, they can be deleted.
+ var top_plugin_id = id;
var toDelete = plugin_et.findall('dependency');
toDelete = toDelete && toDelete.length ? toDelete.map(function(p) { return p.attrib.id; }) : [];
- toDelete.push(id);
+ toDelete.push(top_plugin_id);
// Okay, now we check if any of these are depended on, or top-level.
// Find the installed platforms by whether they have a metadata file.
- var platforms = Object.keys(platform_modules).filter(function(plat) {
- return fs.existsSync(path.join(plugins_dir, plat + '.json'));
+ var platforms = Object.keys(platform_modules).filter(function(platform) {
+ return fs.existsSync(path.join(plugins_dir, platform + '.json'));
});
- var found = [];
- platforms.forEach(function(plat) {
- var tlps = dependencies.generate_dependency_info(plugins_dir, plat).top_level_plugins;
+ var dependList = {};
+ platforms.forEach(function(platform) {
+ var depsInfo = dependencies.generate_dependency_info(plugins_dir, platform);
+ var tlps = depsInfo.top_level_plugins,
+ deps, i;
+
toDelete.forEach(function(plugin) {
- if (tlps.indexOf(plugin) >= 0 || dependencies.dependents(plugin, plugins_dir, plat).length) {
- found.push(plugin);
+ deps = dependencies.dependents(plugin, depsInfo);
+ var i = deps.indexOf(top_plugin_id);
+ if(i >= 0)
+ deps.splice(i, 1); // remove current/top-level plugin as blocking uninstall
+
+ if(deps.length) {
+ dependList[plugin] = deps.join(', ');
}
});
});
- var danglers = underscore.difference(toDelete, found);
- if (danglers && danglers.length) {
- require('../plugman').emit('log', 'Found ' + danglers.length + ' removable plugins. Deleting them.');
- danglers.forEach(doDelete);
- } else {
- require('../plugman').emit('log', 'No dangling plugins to remove.');
+ var i, plugin_id, msg;
+ for(i in toDelete) {
+ plugin_id = toDelete[i];
+
+ if( dependList[plugin_id] ) {
+ msg = '"' + plugin_id + '" is required by ('+ dependList[plugin_id] + ')';
+ if(options.force) {
+ events.emit('log', msg +' but forcing removal.');
+ } else {
+ events.emit('warn', msg +' and cannot be removed (hint: use -f or --force)');
+ continue;
+ }
+ }
+
+ doDelete(plugin_id);
}
return Q();
@@ -95,36 +135,47 @@ module.exports.uninstallPlugin = function(id, plugins_dir) {
// possible options: cli_variables, www_dir, is_top_level
// Returns a promise
-function runUninstall(actions, platform, project_dir, plugin_dir, plugins_dir, options) {
- var xml_path = path.join(plugin_dir, 'plugin.xml')
- , plugin_et = xml_helpers.parseElementtreeSync(xml_path);
- var plugin_id = plugin_et._root.attrib['id'];
+function runUninstallPlatform(actions, platform, project_dir, plugin_dir, plugins_dir, options) {
options = options || {};
+ var xml_path = path.join(plugin_dir, 'plugin.xml');
+ var plugin_et = xml_helpers.parseElementtreeSync(xml_path);
+ var plugin_id = plugin_et._root.attrib['id'];
+
+ // deps info can be passed recusively
+ var depsInfo = options.depsInfo || dependencies.generate_dependency_info(plugins_dir, platform, 'remove');
+
// Check that this plugin has no dependents.
- var dependents = dependencies.dependents(plugin_id, plugins_dir, platform);
+ var dependents = dependencies.dependents(plugin_id, depsInfo, platform);
+
if(options.is_top_level && dependents && dependents.length > 0) {
- require('../plugman').emit('verbose', 'Other top-level plugins (' + dependents.join(', ') + ') depend on ' + plugin_id + ', skipping uninstallation.');
- return Q();
+ var msg = "The plugin '"+ plugin_id +"' is required by (" + dependents.join(', ') + ")";
+ if(options.force) {
+ events.emit("info", msg + " but forcing removal");
+ } else {
+ return Q.reject( new Error(msg + ", skipping uninstallation.") );
+ }
}
// Check how many dangling dependencies this plugin has.
- var dependency_info = dependencies.generate_dependency_info(plugins_dir, platform);
- var deps = dependency_info.graph.getChain(plugin_id);
- var danglers = dependencies.danglers(plugin_id, plugins_dir, platform);
+ var deps = depsInfo.graph.getChain(plugin_id);
+ var danglers = dependencies.danglers(plugin_id, depsInfo, platform);
var promise;
if (deps && deps.length && danglers && danglers.length) {
- require('../plugman').emit('log', 'Uninstalling ' + danglers.length + ' dangling dependent plugins.');
+
+ // @tests - important this event is checked spec/uninstall.spec.js
+ events.emit('log', 'Uninstalling ' + danglers.length + ' dependent plugins.');
promise = Q.all(
danglers.map(function(dangler) {
- var dependent_path = path.join(plugins_dir, dangler);
- var opts = {
- www_dir: options.www_dir,
- cli_variables: options.cli_variables,
- is_top_level: dependency_info.top_level_plugins.indexOf(dangler) > -1
- };
- return runUninstall(actions, platform, project_dir, dependent_path, plugins_dir, opts);
+ var dependent_path = dependencies.resolvePath(dangler, plugins_dir);
+
+ var opts = underscore.extend({}, options, {
+ is_top_level: depsInfo.top_level_plugins.indexOf(dangler) > -1,
+ depsInfo: depsInfo
+ });
+
+ return runUninstallPlatform(actions, platform, project_dir, dependent_path, plugins_dir, opts);
})
);
} else {
@@ -142,7 +193,7 @@ function handleUninstall(actions, platform, plugin_id, plugin_et, project_dir, w
var handler = platform_modules[platform];
var platformTag = plugin_et.find('./platform[@name="'+platform+'"]');
www_dir = www_dir || handler.www_dir(project_dir);
- require('../plugman').emit('log', 'Uninstalling ' + plugin_id + ' from ' + platform);
+ events.emit('log', 'Uninstalling ' + plugin_id + ' from ' + platform);
var assets = plugin_et.findall('./asset');
if (platformTag) {
@@ -201,11 +252,10 @@ function handleUninstall(actions, platform, plugin_id, plugin_et, project_dir, w
return actions.process(platform, project_dir)
.then(function() {
// WIN!
- require('../plugman').emit('verbose', plugin_id + ' uninstalled from ' + platform + '.');
+ events.emit('verbose', plugin_id + ' uninstalled from ' + platform + '.');
// queue up the plugin so prepare can remove the config changes
- config_changes.add_uninstalled_plugin_to_prepare_queue(plugins_dir, path.basename(plugin_dir), platform, is_top_level);
+ config_changes.add_uninstalled_plugin_to_prepare_queue(plugins_dir, plugin_id, platform, is_top_level);
// call prepare after a successful uninstall
- require('./../plugman').prepare(project_dir, platform, plugins_dir, www_dir);
+ plugman.prepare(project_dir, platform, plugins_dir, www_dir);
});
}
-
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ae2ce7ac/src/util/default-engines.js
----------------------------------------------------------------------
diff --git a/src/util/default-engines.js b/src/util/default-engines.js
index 2ca8b13..926c206 100644
--- a/src/util/default-engines.js
+++ b/src/util/default-engines.js
@@ -3,10 +3,9 @@ var path = require('path');
module.exports = function(project_dir){
return {
'cordova':
- { 'platform':'*', 'scriptSrc': path.join(project_dir,'cordova','version') },
- // no location needed for plugman as this should be the calling process
+ { 'platform':'*', 'scriptSrc': path.join(project_dir,'cordova','version') },
'cordova-plugman':
- { 'platform':'*', 'currentVersion': process.version },
+ { 'platform':'*', 'currentVersion': require('../../package.json').version },
'cordova-android':
{ 'platform':'android', 'scriptSrc': path.join(project_dir,'cordova','version') },
'cordova-ios':
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ae2ce7ac/src/util/dependencies.js
----------------------------------------------------------------------
diff --git a/src/util/dependencies.js b/src/util/dependencies.js
index acd7816..8abbc5b 100644
--- a/src/util/dependencies.js
+++ b/src/util/dependencies.js
@@ -4,33 +4,43 @@ var dep_graph = require('dep-graph'),
plugman = require('../../plugman'),
config_changes = require('./config-changes'),
underscore = require('underscore'),
- xml_helpers = require('./xml-helpers');
+ xml_helpers = require('./xml-helpers'),
+ package;
+
+module.exports = package = {
+
+ resolvePath: function(plugin_id, plugins_dir)
+ {
+ return path.join(plugins_dir, plugin_id);
+ },
+
+ resolveConfig: function(plugin_id, plugins_dir)
+ {
+ return path.join(plugins_dir, plugin_id, 'plugin.xml');
+ },
-module.exports = {
generate_dependency_info:function(plugins_dir, platform) {
var json = config_changes.get_platform_json(plugins_dir, platform);
+
+ // TODO: store whole dependency tree in plugins/[platform].json
+ // in case plugins are forcefully removed...
var tlps = [];
var graph = new dep_graph();
- Object.keys(json.installed_plugins).forEach(function(tlp) {
- tlps.push(tlp);
- var xml = xml_helpers.parseElementtreeSync(path.join(plugins_dir, tlp, 'plugin.xml'));
+ Object.keys(json.installed_plugins).forEach(function(plugin_id) {
+ tlps.push(plugin_id);
+
+ var xml = xml_helpers.parseElementtreeSync( package.resolveConfig(plugin_id, plugins_dir) );
var deps = xml.findall('dependency');
+
deps && deps.forEach(function(dep) {
- var id = dep.attrib.id;
- graph.add(tlp, id);
+ graph.add(plugin_id, dep.attrib.id);
});
});
- Object.keys(json.dependent_plugins).forEach(function(plug) {
- var pluginXML = path.join(plugins_dir, plug, 'plugin.xml');
- if (!fs.existsSync(pluginXML)) {
- plugman.emit('verbose', 'Could not find "' + pluginXML + '"');
- return;
- }
- var xml = xml_helpers.parseElementtreeSync(pluginXML);
+ Object.keys(json.dependent_plugins).forEach(function(plugin_id) {
+ var xml = xml_helpers.parseElementtreeSync( package.resolveConfig(plugin_id, plugins_dir) );
var deps = xml.findall('dependency');
deps && deps.forEach(function(dep) {
- var id = dep.attrib.id;
- graph.add(plug, id);
+ graph.add(plugin_id, dep.attrib.id);
});
});
@@ -42,10 +52,13 @@ module.exports = {
// Returns a list of top-level plugins which are (transitively) dependent on the given plugin.
dependents: function(plugin_id, plugins_dir, platform) {
- var dependency_info = module.exports.generate_dependency_info(plugins_dir, platform);
- var graph = dependency_info.graph;
+ if(typeof plugins_dir == 'object')
+ var depsInfo = plugins_dir;
+ else
+ var depsInfo = package.generate_dependency_info(plugins_dir, platform);
- var tlps = dependency_info.top_level_plugins;
+ var graph = depsInfo.graph;
+ var tlps = depsInfo.top_level_plugins;
var dependents = tlps.filter(function(tlp) {
return tlp != plugin_id && graph.getChain(tlp).indexOf(plugin_id) >= 0;
});
@@ -56,11 +69,15 @@ module.exports = {
// Returns a list of plugins which the given plugin depends on, for which it is the only dependent.
// In other words, if the given plugin were deleted, these dangling dependencies should be deleted too.
danglers: function(plugin_id, plugins_dir, platform) {
- var dependency_info = module.exports.generate_dependency_info(plugins_dir, platform);
- var graph = dependency_info.graph;
+ if(typeof plugins_dir == 'object')
+ var depsInfo = plugins_dir;
+ else
+ var depsInfo = package.generate_dependency_info(plugins_dir, platform);
+
+ var graph = depsInfo.graph;
var dependencies = graph.getChain(plugin_id);
- var tlps = dependency_info.top_level_plugins;
+ var tlps = depsInfo.top_level_plugins;
var diff_arr = [];
tlps.forEach(function(tlp) {
if (tlp != plugin_id) {
@@ -76,4 +93,4 @@ module.exports = {
danglers = danglers && danglers.filter(function(x) { return tlps.indexOf(x) < 0; });
return danglers;
}
-};
+};
\ No newline at end of file