in src/plugman/fetch.js [40:173]
function fetchPlugin (plugin_src, plugins_dir, options) {
// Ensure the containing directory exists.
fs.ensureDirSync(plugins_dir);
options = options || {};
options.subdir = options.subdir || '.';
options.searchpath = options.searchpath || [];
if (typeof options.searchpath === 'string') {
options.searchpath = options.searchpath.split(path.delimiter);
}
const pluginInfoProvider = options.pluginInfoProvider || new PluginInfoProvider();
// clone from git repository
// @todo Use 'url.URL' constructor instead since 'url.parse' was deprecated since v11.0.0
var uri = url.parse(plugin_src); // eslint-disable-line
// If the hash exists, it has the form from npm: http://foo.com/bar#git-ref[:subdir]
// git-ref can be a commit SHA, a tag, or a branch
// NB: No leading or trailing slash on the subdir.
if (uri.hash) {
const result = uri.hash.match(/^#([^:]*)(?::\/?(.*?)\/?)?$/);
if (result) {
if (result[1]) { options.git_ref = result[1]; }
if (result[2]) { options.subdir = result[2]; }
}
}
return Promise.resolve().then(function () {
let plugin_dir = cordovaUtil.fixRelativePath(path.join(plugin_src, options.subdir));
return Promise.resolve().then(function () {
// check if it is a local path
if (fs.existsSync(plugin_dir)) {
if (!fs.existsSync(path.join(plugin_dir, 'package.json'))) {
return Promise.reject(new CordovaError('Invalid Plugin! ' + plugin_dir + ' needs a valid package.json'));
}
projectRoot = path.join(plugins_dir, '..');
// Plugman projects need to go up two directories to reach project root.
// Plugman projects have an options.projectRoot variable
if (options.projectRoot) {
projectRoot = options.projectRoot;
}
return fetch(path.resolve(plugin_dir), projectRoot, options)
.then(function (directory) {
return {
pinfo: pluginInfoProvider.get(directory),
fetchJsonSource: {
type: 'local',
path: directory
}
};
}).catch(function (error) {
// something went wrong with cordova-fetch
return Promise.reject(new CordovaError(error.message));
});
}
// If there is no such local path or it's a git URL, it's a plugin id or id@versionspec.
// First look for it in the local search path (if provided).
const pinfo = findLocalPlugin(plugin_src, options.searchpath, pluginInfoProvider);
if (pinfo) {
events.emit('verbose', 'Found ' + plugin_src + ' at ' + pinfo.dir);
return {
pinfo,
fetchJsonSource: {
type: 'local',
path: pinfo.dir
}
};
} else if (options.noregistry) {
return Promise.reject(new CordovaError(
'Plugin ' + plugin_src + ' not found locally. ' +
'Note, plugin registry was disabled by --noregistry flag.'
));
}
// If not found in local search path, fetch from the registry.
const parsedSpec = pluginSpec.parse(plugin_src);
let P;
let skipCopyingPlugin;
plugin_dir = path.join(plugins_dir, parsedSpec.id);
// if the plugin has already been fetched, use it.
if (fs.existsSync(plugin_dir)) {
P = Promise.resolve(plugin_dir);
skipCopyingPlugin = true;
} else {
// use cordova-fetch
projectRoot = path.join(plugins_dir, '..');
// Plugman projects need to go up two directories to reach project root.
// Plugman projects have an options.projectRoot variable
if (options.projectRoot) {
projectRoot = options.projectRoot;
}
P = fetch(plugin_src, projectRoot, options);
skipCopyingPlugin = false;
}
return P
.catch(function (error) {
const message = 'Failed to fetch plugin ' + plugin_src + ' via registry.' +
'\nProbably this is either a connection problem, or plugin spec is incorrect.' +
'\nCheck your connection and plugin name/version/URL.' +
'\n' + error;
return Promise.reject(new CordovaError(message));
})
.then(function (dir) {
return {
pinfo: pluginInfoProvider.get(dir),
fetchJsonSource: {
type: 'registry',
id: plugin_src
},
skipCopyingPlugin
};
});
}).then(function (result) {
options.plugin_src_dir = result.pinfo.dir;
let P;
if (result.skipCopyingPlugin) {
P = Promise.resolve(options.plugin_src_dir);
} else {
P = Promise.resolve(copyPlugin(result.pinfo, plugins_dir, options.link && result.fetchJsonSource.type === 'local'));
}
return P.then(function (dir) {
result.dest = dir;
return result;
});
});
}).then(function (result) {
checkID(options.expected_id, result.pinfo);
const data = { source: result.fetchJsonSource };
data.is_top_level = options.is_top_level;
data.variables = options.variables || {};
metadata.save_fetch_metadata(plugins_dir, result.pinfo.id, data);
return result.dest;
});
}