Created
January 7, 2014 18:18
-
-
Save jaygarcia/8303968 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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) { | |
var xml_path = path.join(plugin_dir, 'plugin.xml') | |
, plugin_et = xml_helpers.parseElementtreeSync(xml_path) | |
, filtered_variables = {}; | |
var name = plugin_et.findall('name').text; | |
var plugin_id = plugin_et.getroot().attrib['id']; | |
require('../plugman').emit('log', 'Starting installation of "' + plugin_id + '" for ' + platform); | |
// check if platform has plugin installed already. | |
var platform_config = config_changes.get_platform_json(plugins_dir, platform); | |
var plugin_basename = path.basename(plugin_dir); | |
var is_installed = false; | |
Object.keys(platform_config.installed_plugins).forEach(function(installed_plugin_id) { | |
if (installed_plugin_id == plugin_id) { | |
is_installed = true; | |
} | |
}); | |
Object.keys(platform_config.dependent_plugins).forEach(function(installed_plugin_id) { | |
if (installed_plugin_id == plugin_id) { | |
is_installed = true; | |
} | |
}); | |
if (is_installed) { | |
require('../plugman').emit('results', 'Plugin "' + plugin_id + '" already installed, \'sall good.'); | |
return Q(); | |
} | |
var theEngines = getEngines(plugin_et, platform, project_dir, plugin_dir); | |
return callEngineScripts(theEngines) | |
.then(checkEngines) | |
.then(function() { | |
// checking preferences, if certain variables are not provided, we should throw. | |
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(", "))); | |
} | |
// 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) { | |
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('/')); | |
} | |
// 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); | |
} 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 | |
}; | |
// CB-4770: registry fetching | |
if(dep_url === undefined) { | |
dep_url = dep_plugin_id; | |
} | |
return possiblyFetch(actions, platform, project_dir, dep_url, plugins_dir, opts); | |
} | |
}); | |
}, 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); | |
}); | |
} 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); | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment