Comparing version 0.5.6 to 0.5.7
@@ -5,3 +5,3 @@ { | ||
"description": "install/uninstall Cordova plugins", | ||
"version": "0.5.6", | ||
"version": "0.5.7", | ||
"repository": { | ||
@@ -22,3 +22,3 @@ "type": "git", | ||
"bplist-parser": "0.0.x", | ||
"shelljs": "0.0.x", | ||
"shelljs": "0.1.x", | ||
"osenv": "0.0.x" | ||
@@ -25,0 +25,0 @@ }, |
var fs = require('fs') // use existsSync in 0.6.x | ||
, path = require('path') | ||
, util = require('util') | ||
, shell = require('shelljs') | ||
@@ -25,3 +26,28 @@ , et = require('elementtree') | ||
// find which config-files we're interested in | ||
// get config.xml filename | ||
var config_xml_filename = 'res/xml/config.xml'; | ||
if(fs.existsSync(path.resolve(project_dir, 'res/xml/plugins.xml'))) { | ||
config_xml_filename = 'res/xml/plugins.xml'; | ||
} | ||
// collision detection | ||
if(action == "install" && pluginInstalled(plugin_et, project_dir, config_xml_filename)) { | ||
throw "Plugin "+plugin_id+" already installed" | ||
} else if(action == "uninstall" && !pluginInstalled(plugin_et, project_dir, config_xml_filename)) { | ||
throw "Plugin "+plugin_id+" not installed" | ||
} | ||
root = et.Element("config-file"); | ||
root.attrib['parent'] = '.' | ||
plugin_et.findall('./access').forEach(function (tag) { | ||
root.append(tag); | ||
}); | ||
if (root.len()) { | ||
(configChanges[config_xml_filename]) ? | ||
configChanges[config_xml_filename].push(root) : | ||
configChanges[config_xml_filename] = [root]; | ||
} | ||
// find which config-files we're interested in | ||
Object.keys(configChanges).forEach(function (configFile) { | ||
@@ -32,9 +58,2 @@ if (!fs.existsSync(path.resolve(project_dir, configFile))) { | ||
}); | ||
// collision detection | ||
if(action == "install" && pluginInstalled(plugin_et, project_dir)) { | ||
throw "Plugin "+plugin_id+" already installed" | ||
} else if(action == "uninstall" && !pluginInstalled(plugin_et, project_dir)) { | ||
throw "Plugin "+plugin_id+" not installed" | ||
} | ||
@@ -118,3 +137,2 @@ // move asset files | ||
// edit configuration files | ||
@@ -168,7 +186,7 @@ Object.keys(configChanges).forEach(function (filename) { | ||
function pluginInstalled(plugin_et, project_dir) { | ||
var config_tag = plugin_et.find('./platform[@name="android"]/config-file[@target="res/xml/config.xml"]/plugin') | ||
var plugin_name = config_tag.attrib.name; | ||
return (fs.readFileSync(path.resolve(project_dir, 'res/xml/config.xml'), 'utf8') | ||
function pluginInstalled(plugin_et, project_dir, config_xml_filename) { | ||
var tag_xpath = util.format('./platform[@name="android"]/config-file[@target="%s"]/plugin', config_xml_filename); | ||
var plugin_name = plugin_et.find(tag_xpath).attrib.name; | ||
return (fs.readFileSync(path.resolve(project_dir, config_xml_filename), 'utf8') | ||
.match(new RegExp(plugin_name, "g")) != null); | ||
} |
@@ -134,6 +134,8 @@ var path = require('path') | ||
frameworks.forEach(function (framework) { | ||
var src = framework.attrib['src']; | ||
var src = framework.attrib['src'], | ||
weak = framework.attrib['weak']; | ||
if (action == 'install') { | ||
xcodeproj.addFramework(src); | ||
var opt = { weak: (weak && weak.toLowerCase() == 'true') }; | ||
xcodeproj.addFramework(src, opt); | ||
} else { | ||
@@ -228,28 +230,66 @@ xcodeproj.removeFramework(src); | ||
platformTag = plugin_et.find('./platform[@name="ios"]'), // FIXME: can probably do better than this | ||
plistEle = platformTag.find('./plugins-plist'), // TODO: use this for older that have plugins-plist | ||
configChanges = getConfigChanges(platformTag), | ||
pl, | ||
external_hosts = []; | ||
plistEle = platformTag.find('./plugins-plist'), // use this for older that have plugins-plist | ||
configChanges = getConfigChanges(platformTag), | ||
base_config_path = path.basename(config_path); | ||
// edit configuration files | ||
var xmlDoc = xml_helpers.parseElementtreeSync(config_path), | ||
output; | ||
output, | ||
pListOnly = plistEle; | ||
configChanges[path.basename(config_path)].forEach(function (configNode) { | ||
var selector = configNode.attrib["parent"], | ||
children = configNode.findall('*'); | ||
if (configChanges[path.basename(config_path)]) { | ||
configChanges[path.basename(config_path)].forEach(function (val) { | ||
if (val.find("plugin")) pListOnly = false; | ||
}); | ||
} | ||
if( action == 'install') { | ||
if (!xml_helpers.graftXML(xmlDoc, children, selector)) { | ||
throw new Error('failed to add children to ' + filename); | ||
} | ||
if (pListOnly) { | ||
// if the plugin supports the old plugins-plist element only | ||
var name = plistEle.attrib.key; | ||
var value = plistEle.attrib.string; | ||
var pluginsEl = xmlDoc.find('plugins'); | ||
if ( action == 'install') { | ||
var new_plugin = new et.Element('plugin'); | ||
new_plugin.attrib.name = name; | ||
new_plugin.attrib.value = value; | ||
pluginsEl.append(new_plugin); | ||
} else { | ||
if (!xml_helpers.pruneXML(xmlDoc, children, selector)) { | ||
throw new Error('failed to remove children from' + filename); | ||
} | ||
var culprit = pluginsEl.find("plugin[@name='"+name+"']"); | ||
pluginsEl.remove(0, culprit); | ||
} | ||
}); | ||
} | ||
// add whitelist hosts | ||
root = et.Element("config-file"); | ||
root.attrib['parent'] = '.' | ||
hosts.forEach(function (tag) { | ||
root.append(tag); | ||
}); | ||
if (root.len()) { | ||
(configChanges[path.basename(config_path)]) ? | ||
configChanges[path.basename(config_path)].push(root) : | ||
configChanges[path.basename(config_path)] = [root]; | ||
} | ||
if (configChanges[path.basename(config_path)]) { | ||
configChanges[base_config_path].forEach(function (configNode) { | ||
var selector = configNode.attrib["parent"], | ||
children = configNode.findall('*'); | ||
if( action == 'install') { | ||
if (!xml_helpers.graftXML(xmlDoc, children, selector)) { | ||
throw new Error('failed to add children to ' + filename); | ||
} | ||
} else { | ||
if (!xml_helpers.pruneXML(xmlDoc, children, selector)) { | ||
throw new Error('failed to remove children from' + filename); | ||
} | ||
} | ||
}); | ||
} | ||
output = xmlDoc.write({indent: 4}); | ||
fs.writeFileSync(config_path, output); | ||
} | ||
@@ -256,0 +296,0 @@ |
@@ -14,6 +14,7 @@ #!/usr/bin/env node | ||
'ios': require('./platforms/ios'), | ||
'bb10': require('./platforms/bb10'), | ||
'www': require('./platforms/www') | ||
}; | ||
var known_opts = { 'platform' : [ 'ios', 'android', 'www' ] | ||
var known_opts = { 'platform' : [ 'ios', 'android', 'bb10' ,'www' ] | ||
, 'project' : path | ||
@@ -42,3 +43,7 @@ , 'plugin' : [String, path, url] | ||
else if (cli_opts.list) { | ||
plugins.listAllPlugins(); | ||
plugins.listAllPlugins(function(plugins) { | ||
for(var i = 0, j = plugins.length ; i < j ; i++) { | ||
console.log(plugins[i].value.name, '-', plugins[i].value.description); | ||
} | ||
}); | ||
} | ||
@@ -87,4 +92,4 @@ else if (!cli_opts.platform || !cli_opts.project || !cli_opts.plugin) { | ||
plugins.getPluginInfo(plugin_dir, | ||
function(plugin_dir) { | ||
execAction(action, platform, project_dir, plugin_dir); | ||
function(plugin_info) { | ||
execAction(action, platform, project_dir, plugins.clonePluginGitRepo(plugin_info.url)); | ||
}, | ||
@@ -91,0 +96,0 @@ function(e) { |
@@ -313,9 +313,13 @@ plugman | ||
Identifies a framework (usually part of the OS/platform) that the plugin depends | ||
on. Example: | ||
Identifies a framework (usually part of the OS/platform) that the plugin depends on. | ||
Examples: | ||
<framework src="libsqlite3.dylib" /> | ||
<framework src="social.framework" weak="true" /> | ||
plugman identifies the framework through the `src` attribute and attempts to add the framework to the Cordova project, in the correct fashion for a given platform. | ||
The optional `weak` attribute is a boolean denoting whether the framework should be weakly-linked. Default is `false`. | ||
## Variables | ||
@@ -322,0 +326,0 @@ |
@@ -55,3 +55,2 @@ // Test installation on Cordova 1.x project | ||
var jsPath = path.join(test_dir, 'projects', 'android_one', 'assets', 'www', 'childbrowser.js'); | ||
android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et); | ||
@@ -116,1 +115,14 @@ fs.stat(jsPath, function(err, stats) { | ||
} | ||
exports['should add whitelist hosts'] = function (test) { | ||
android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et); | ||
var pluginsXmlPath = path.join(test_dir, 'projects', 'android_one', 'res', 'xml', 'plugins.xml'); | ||
var pluginsTxt = fs.readFileSync(pluginsXmlPath, 'utf-8'), | ||
pluginsDoc = new et.ElementTree(et.XML(pluginsTxt)); | ||
test.equal(pluginsDoc.findall("access").length, 2, "/access"); | ||
test.equal(pluginsDoc.findall("access")[0].attrib["origin"], "build.phonegap.com") | ||
test.equal(pluginsDoc.findall("access")[1].attrib["origin"], "s3.amazonaws.com") | ||
test.done(); | ||
} |
@@ -133,1 +133,13 @@ // Test uninstallation on Cordova 1.x project | ||
} | ||
exports['should remove whitelist hosts'] = function (test) { | ||
android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et); | ||
android.handlePlugin('uninstall', test_project_dir, test_plugin_dir, plugin_et); | ||
var pluginsXmlPath = path.join(test_dir, 'projects', 'android_one', 'res', 'xml', 'plugins.xml'); | ||
var pluginsTxt = fs.readFileSync(pluginsXmlPath, 'utf-8'), | ||
pluginsDoc = new et.ElementTree(et.XML(pluginsTxt)); | ||
test.equal(pluginsDoc.findall("access").length, 0, "/access"); | ||
test.done(); | ||
} |
@@ -126,1 +126,14 @@ // Test installation on Cordova 2 project | ||
} | ||
exports['should add whitelist hosts'] = function (test) { | ||
android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et); | ||
var pluginsXmlPath = path.join(test_dir, 'projects', 'android_two', 'res', 'xml', 'config.xml'); | ||
var pluginsTxt = fs.readFileSync(pluginsXmlPath, 'utf-8'), | ||
pluginsDoc = new et.ElementTree(et.XML(pluginsTxt)); | ||
test.equal(pluginsDoc.findall("access").length, 3, "/access"); | ||
test.equal(pluginsDoc.findall("access")[1].attrib["origin"], "build.phonegap.com") | ||
test.equal(pluginsDoc.findall("access")[2].attrib["origin"], "s3.amazonaws.com") | ||
test.done(); | ||
} |
@@ -134,2 +134,14 @@ // Test uninstallation on Cordova 2 project | ||
exports['should remove whitelist hosts'] = function (test) { | ||
android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et); | ||
android.handlePlugin('uninstall', test_project_dir, test_plugin_dir, plugin_et); | ||
var pluginsXmlPath = path.join(test_dir, 'projects', 'android_two', 'res', 'xml', 'config.xml'); | ||
var pluginsTxt = fs.readFileSync(pluginsXmlPath, 'utf-8'), | ||
pluginsDoc = new et.ElementTree(et.XML(pluginsTxt)); | ||
test.equal(pluginsDoc.findall("access").length, 1, "/access"); | ||
test.done(); | ||
} | ||
exports['should not uninstall a plugin that is not installed'] = function (test) { | ||
@@ -136,0 +148,0 @@ var jsPath = path.join(test_dir, 'projects', 'android_two', 'assets', 'www', 'childbrowser.js'); |
@@ -59,7 +59,4 @@ var fs = require('fs') | ||
var jsPath = path.join(test_dir, 'projects', 'ios', 'www', 'childbrowser.js'); | ||
fs.stat(jsPath, function(err, stats) { | ||
test.ok(!err); | ||
test.ok(stats.isFile()); | ||
test.done(); | ||
}); | ||
test.ok(fs.existsSync(jsPath)); | ||
test.done(); | ||
} | ||
@@ -144,3 +141,31 @@ | ||
test.ok(pluginsDoc.find(expected)); | ||
test.equal(pluginsDoc.findall("access").length, 3, "/access"); | ||
test.equal(pluginsDoc.findall("access")[1].attrib["origin"], "build.phonegap.com") | ||
test.equal(pluginsDoc.findall("access")[2].attrib["origin"], "s3.amazonaws.com") | ||
test.done(); | ||
} | ||
exports['should edit config.xml even when using old <plugins-plist> approach'] = function (test) { | ||
// setting up PGSQLitePlugin (with config.xml) | ||
var dummy_plugin_dir = path.join(test_dir, 'plugins', 'ChildBrowser') | ||
var dummy_xml_path = path.join(dummy_plugin_dir, 'plugin.xml') | ||
// overriding some params | ||
var project_dir = path.join(test_dir, 'projects', 'ios-config-xml') | ||
var dummy_plugin_et = new et.ElementTree(et.XML(fs.readFileSync(dummy_xml_path, 'utf-8'))); | ||
// run the platform-specific function | ||
ios.handlePlugin('install', project_dir, dummy_plugin_dir, dummy_plugin_et); | ||
var configXmlPath = path.join(project_dir, 'SampleApp', 'config.xml'); | ||
var pluginsTxt = fs.readFileSync(configXmlPath, 'utf-8'), | ||
pluginsDoc = new et.ElementTree(et.XML(pluginsTxt)), | ||
expected = 'plugins/plugin[@name="com.phonegap.plugins.childbrowser"]' + | ||
'[@value="ChildBrowserCommand"]'; | ||
test.ok(pluginsDoc.find(expected)); | ||
test.equal(pluginsDoc.findall("access").length, 3, "/access"); | ||
test.equal(pluginsDoc.findall("access")[1].attrib["origin"], "build.phonegap.com") | ||
test.equal(pluginsDoc.findall("access")[2].attrib["origin"], "s3.amazonaws.com") | ||
test.done(); | ||
@@ -158,3 +183,3 @@ } | ||
fileRefLength = Object.keys(fileRefSection).length, | ||
EXPECTED_TOTAL_REFERENCES = 92; // magic number ahoy! | ||
EXPECTED_TOTAL_REFERENCES = 96; // magic number ahoy! | ||
@@ -171,2 +196,3 @@ test.equal(fileRefLength, EXPECTED_TOTAL_REFERENCES); | ||
projLines = projContents.split("\n"), | ||
weak_linked = "settings = {ATTRIBUTES = (Weak, ); };", | ||
references; | ||
@@ -181,5 +207,33 @@ | ||
test.equal(references.length, 4); | ||
test.ok(references[0].indexOf(weak_linked) == -1); | ||
test.done(); | ||
} | ||
exports['should add the framework references with weak option to the pbxproj file'] = function (test) { | ||
// run the platform-specific function | ||
ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et); | ||
var projPath = test_project_dir + '/SampleApp.xcodeproj/project.pbxproj', | ||
projContents = fs.readFileSync(projPath, 'utf8'), | ||
projLines = projContents.split("\n"), | ||
weak_linked = "settings = {ATTRIBUTES = (Weak, ); };", | ||
references; | ||
weak_references = projLines.filter(function (line) { | ||
return !!(line.match("social.framework")); | ||
}) | ||
non_weak_references = projLines.filter(function (line) { | ||
return !!(line.match("music.framework")); | ||
}) | ||
// should be four libsqlite3 reference lines added | ||
// pretty low-rent test eh | ||
test.equal(weak_references.length, 4); | ||
test.ok(weak_references[0].indexOf(weak_linked) != -1); | ||
test.equal(non_weak_references.length, 4); | ||
test.ok(non_weak_references[0].indexOf(weak_linked) == -1); | ||
test.done(); | ||
} | ||
exports['should not install a plugin that is already installed'] = function (test) { | ||
@@ -186,0 +240,0 @@ ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et); |
@@ -125,2 +125,28 @@ var fs = require('fs') | ||
exports['should edit config.xml even when using old <plugins-plist> approach'] = function (test) { | ||
// setting up PGSQLitePlugin (with config.xml) | ||
var dummy_plugin_dir = path.join(test_dir, 'plugins', 'PGSQLitePlugin') | ||
var dummy_xml_path = path.join(dummy_plugin_dir, 'plugin.xml') | ||
// overriding some params | ||
var project_dir = path.join(test_dir, 'projects', 'ios-config-xml') | ||
var dummy_plugin_et = new et.ElementTree(et.XML(fs.readFileSync(dummy_xml_path, 'utf-8'))); | ||
// run the platform-specific function | ||
ios.handlePlugin('install', project_dir, dummy_plugin_dir, dummy_plugin_et); | ||
ios.handlePlugin('uninstall', project_dir, dummy_plugin_dir, dummy_plugin_et); | ||
var configXmlPath = path.join(project_dir, 'SampleApp', 'config.xml'); | ||
var pluginsTxt = fs.readFileSync(configXmlPath, 'utf-8'), | ||
pluginsDoc = new et.ElementTree(et.XML(pluginsTxt)), | ||
expected = 'plugins/plugin[@name="PGSQLitePlugin"]' + | ||
'[@value="PGSQLitePlugin"]'; | ||
test.ok(!pluginsDoc.find(expected)); | ||
test.equal(pluginsDoc.findall("access").length, 1, "/access"); | ||
test.done(); | ||
} | ||
exports['should edit config.xml'] = function (test) { | ||
@@ -147,2 +173,3 @@ // setting up WebNotification (with config.xml) | ||
test.ok(!pluginsDoc.find(expected)); | ||
test.equal(pluginsDoc.findall("access").length, 1, "/access"); | ||
@@ -149,0 +176,0 @@ test.done(); |
#!/usr/bin/env node | ||
// FIXME: change this quickly | ||
var url = "http://ec2-184-72-173-33.compute-1.amazonaws.com"; | ||
var http = require('http'), | ||
@@ -8,7 +6,9 @@ osenv = require('osenv'), | ||
fs = require('fs'), | ||
shell = require('shelljs'); | ||
util = require('util'), | ||
shell = require('shelljs'), | ||
remote = require(path.join(__dirname, '..', 'config', 'remote')); | ||
// Fetches plugin information from remote server | ||
exports.getPluginInfo = function(plugin_name, success, error) { | ||
http.get(url + "/cordova_plugins/_design/cordova_plugins/_view/by_name?key=\""+plugin_name+"\"", function(res) { | ||
http.get(remote.url + util.format(remote.query_path, plugin_name), function(res) { | ||
var str = ''; | ||
@@ -22,3 +22,3 @@ res.on('data', function (chunk) { | ||
plugin_info = response.rows[0].value; | ||
success(exports.clonePluginGitRepo(plugin_info.url)); | ||
success(plugin_info); | ||
} else { | ||
@@ -35,4 +35,4 @@ error("Could not find information on "+plugin_dir+" plugin"); | ||
exports.listAllPlugins = function(plugin_name, success, error) { | ||
http.get(url + "/cordova_plugins/_design/cordova_plugins/_view/by_name", function(res) { | ||
exports.listAllPlugins = function(success, error) { | ||
http.get(remote.url + remote.list_path, function(res) { | ||
var str = ''; | ||
@@ -43,6 +43,4 @@ res.on('data', function (chunk) { | ||
res.on('end', function () { | ||
var plugins = (JSON.parse(str)).rows, i, j; | ||
for(i = 0, j = plugins.length ; i < j ; i++) { | ||
console.log(plugins[i].value.name, '-', plugins[i].value.description); | ||
} | ||
var plugins = (JSON.parse(str)).rows; | ||
success(plugins); | ||
}); | ||
@@ -56,3 +54,3 @@ | ||
exports.clonePluginGitRepo = function(plugin_dir) { | ||
exports.clonePluginGitRepo = function(plugin_git_url) { | ||
if(!shell.which('git')) { | ||
@@ -62,7 +60,11 @@ throw new Error('git command line is not installed'); | ||
// use osenv to get a temp directory in a portable way | ||
plugin_git_url = plugin_dir; | ||
plugin_dir = path.join(osenv.tmpdir(), 'plugin'); | ||
// trash it if it already exists (something went wrong before probably) | ||
if(fs.existsSync(plugin_dir)) { | ||
shell.rm('-rf', plugin_dir); | ||
} | ||
if(shell.exec('git clone ' + plugin_git_url + ' ' + plugin_dir + ' 2>&1 1>/dev/null').code != 0) { | ||
throw new Error('failed to get the plugin via git URL', plugin_git_url); | ||
if(shell.exec('git clone ' + plugin_git_url + ' ' + plugin_dir + ' 2>&1 1>/dev/null', {silent: true}).code != 0) { | ||
throw new Error('failed to get the plugin via git URL '+ plugin_git_url); | ||
} | ||
@@ -80,1 +82,13 @@ | ||
} | ||
// TODO add method for archives and other formats | ||
// exports.extractArchive = function(plugin_dir) { | ||
// } | ||
// TODO add method to publish plugin from cli | ||
// exports.publishPlugin = function(plugin_dir) { | ||
// } | ||
// TODO add method to unpublish plugin from cli | ||
// exports.unpublishPlugin = function(plugin_dir) { | ||
// } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 2 instances in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2286960
137
2666
373
36
3
+ Addedshelljs@0.1.4(transitive)
- Removedshelljs@0.0.9(transitive)
Updatedshelljs@0.1.x