src/cordova/restore-util.js
function installPluginsFromConfigXML(args) {
    events.emit('verbose', 'Checking config.xml for saved plugins that haven\'t been added to the project');

    //Install plugins that are listed on config.xml
    var projectRoot = cordova_util.cdProjectRoot();
    var configPath = cordova_util.projectConfig(projectRoot);
    var cfg = new ConfigParser(configPath);
    var plugins_dir = path.join(projectRoot, 'plugins');

    // Get all configured plugins
    var plugins = cfg.getPluginIdList();
    if (0 === plugins.length) {
        return Q('No plugins found in config.xml that haven\'t been added to the project');
    }


    // Intermediate variable to store current installing plugin name
    // to be able to create informative warning on plugin failure
    var pluginName;

    // CB-9560 : Run `plugin add` serially, one plugin after another
    // We need to wait for the plugin and its dependencies to be installed
    // before installing the next root plugin otherwise we can have common
    // plugin dependencies installed twice which throws a nasty error.
    return promiseutil.Q_chainmap_graceful(plugins, function(featureId) {
        var pluginPath = path.join(plugins_dir, featureId);
        if (fs.existsSync(pluginPath)) {
            // Plugin already exists
            return Q();
        }
        events.emit('log', 'Discovered plugin "' + featureId + '" in config.xml. Adding it to the project');
        var pluginEntry = cfg.getPlugin(featureId);

        // Install from given URL if defined or using a plugin id. If spec isn't a valid version or version range,
        // assume it is the location to install from.
        var pluginSpec = pluginEntry.spec;
        pluginName = pluginEntry.name;

        // CB-10761 If plugin spec is not specified, use plugin name
        var installFrom = pluginSpec || pluginName;
        if (pluginSpec && semver.validRange(pluginSpec, true))
            installFrom = pluginName + '@' + pluginSpec;

        // Add feature preferences as CLI variables if have any
        var options = {
            cli_variables: pluginEntry.variables,
            searchpath: args.searchpath,
            fetch: args.fetch || false,
            save: args.save || false
        };
        var plugin = require('./plugin');
        return plugin('add', installFrom, options);
    }, function (error) {
        // CB-10921 emit a warning in case of error
        var msg = 'Failed to restore plugin \"' + pluginName + '\" from config.xml. ' +
            'You might need to try adding it again. Error: ' + error;
        events.emit('warn', msg);
    });
}
function installPluginsFromConfigXML(args) {
    events.emit('verbose', 'Checking config.xml for saved plugins that haven\'t been added to the project');

    //Install plugins that are listed on config.xml
    var projectRoot = cordova_util.cdProjectRoot();
    var configPath = cordova_util.projectConfig(projectRoot);
    var cfg = new ConfigParser(configPath);
    var plugins_dir = path.join(projectRoot, 'plugins');

    // Get all configured plugins
    var plugins = cfg.getPluginIdList();
    if (0 === plugins.length) {
        return Q('No plugins found in config.xml that haven\'t been added to the project');
    }


    // Intermediate variable to store current installing plugin name
    // to be able to create informative warning on plugin failure
    var pluginName;

    // CB-9560 : Run `plugin add` serially, one plugin after another
    // We need to wait for the plugin and its dependencies to be installed
    // before installing the next root plugin otherwise we can have common
    // plugin dependencies installed twice which throws a nasty error.
    return promiseutil.Q_chainmap_graceful(plugins, function(featureId) {
        var pluginPath = path.join(plugins_dir, featureId);
        if (fs.existsSync(pluginPath)) {
            // Plugin already exists
            return Q();
        }
        events.emit('log', 'Discovered plugin "' + featureId + '" in config.xml. Adding it to the project');
        var pluginEntry = cfg.getPlugin(featureId);

        // Install from given URL if defined or using a plugin id. If spec isn't a valid version or version range,
        // assume it is the location to install from.
        var pluginSpec = pluginEntry.spec;
        pluginName = pluginEntry.name;

        // CB-10761 If plugin spec is not specified, use plugin name
        var installFrom = pluginSpec || pluginName;
        if (pluginSpec && semver.validRange(pluginSpec, true))
            installFrom = pluginName + '@' + pluginSpec;

        // Add feature preferences as CLI variables if have any
        var options = {
            cli_variables: pluginEntry.variables,
            searchpath: args.searchpath,
            fetch: args.fetch || false,
            save: args.save || false
        };
        var plugin = require('./plugin');
        return plugin('add', installFrom, options);
    }, function (error) {
        // CB-10921 emit a warning in case of error
        var msg = 'Failed to restore plugin \"' + pluginName + '\" from config.xml. ' +
            'You might need to try adding it again. Error: ' + error;
        events.emit('warn', msg);
    });
}
function installPluginsFromConfigXML ( args ) { events . emit ( 'verbose' , 'Checking config.xml for saved plugins that haven\'t been added to the project' ) ; //Install plugins that are listed on config.xml var projectRoot = cordova_util . cdProjectRoot ( ) ; var configPath = cordova_util . projectConfig ( projectRoot ) ; var cfg = new ConfigParser ( configPath ) ; var plugins_dir = path . join ( projectRoot , 'plugins' ) ; // Get all configured plugins var plugins = cfg . getPluginIdList ( ) ; if ( 0 === plugins . length ) { return Q ( 'No plugins found in config.xml that haven\'t been added to the project' ) ; } // Intermediate variable to store current installing plugin name // to be able to create informative warning on plugin failure var pluginName ; // CB-9560 : Run `plugin add` serially, one plugin after another // We need to wait for the plugin and its dependencies to be installed // before installing the next root plugin otherwise we can have common // plugin dependencies installed twice which throws a nasty error. return promiseutil . Q_chainmap_graceful ( plugins , function ( featureId ) { var pluginPath = path . join ( plugins_dir , featureId ) ; if ( fs . existsSync ( pluginPath ) ) { // Plugin already exists return Q ( ) ; } events . emit ( 'log' , 'Discovered plugin "' + featureId + '" in config.xml. Adding it to the project' ) ; var pluginEntry = cfg . getPlugin ( featureId ) ; // Install from given URL if defined or using a plugin id. If spec isn't a valid version or version range, // assume it is the location to install from. var pluginSpec = pluginEntry . spec ; pluginName = pluginEntry . name ; // CB-10761 If plugin spec is not specified, use plugin name var installFrom = pluginSpec || pluginName ; if ( pluginSpec && semver . validRange ( pluginSpec , true ) ) installFrom = pluginName + '@' + pluginSpec ; // Add feature preferences as CLI variables if have any var options = { cli_variables : pluginEntry . variables , searchpath : args . searchpath , fetch : args . fetch || false , save : args . save || false } ; var plugin = require ( './plugin' ) ; return plugin ( 'add' , installFrom , options ) ; } , function ( error ) { // CB-10921 emit a warning in case of error var msg = 'Failed to restore plugin \"' + pluginName + '\" from config.xml. ' + 'You might need to try adding it again. Error: ' + error ; events . emit ( 'warn' , msg ) ; } ) ; }
returns a Promise
returns a Promise