You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by fi...@apache.org on 2013/05/16 17:57:08 UTC
[09/20] git commit: updated/fixed install + uninstall specs. added
specs to both for plugins with dependencies
updated/fixed install + uninstall specs. added specs to both for plugins with dependencies
Project: http://git-wip-us.apache.org/repos/asf/cordova-plugman/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugman/commit/bf56f3ed
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugman/tree/bf56f3ed
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugman/diff/bf56f3ed
Branch: refs/heads/master
Commit: bf56f3eddda3f88cb09bfd487a3c58d112c335e3
Parents: e05e51a
Author: Fil Maj <ma...@gmail.com>
Authored: Wed May 15 12:59:07 2013 -0700
Committer: Fil Maj <ma...@gmail.com>
Committed: Thu May 16 08:55:42 2013 -0700
----------------------------------------------------------------------
main.js | 4 +-
spec/install.spec.js | 127 ++++++++++++++-------------
spec/plugins/dependencies/A/plugin.xml | 60 +++++++++++++
spec/plugins/dependencies/B/plugin.xml | 60 +++++++++++++
spec/plugins/dependencies/C/plugin.xml | 57 ++++++++++++
spec/plugins/dependencies/D/plugin.xml | 57 ++++++++++++
spec/plugins/dependencies/E/plugin.xml | 57 ++++++++++++
spec/plugins/dependencies/README.md | 5 +
spec/uninstall.spec.js | 92 +++++++++-----------
src/install.js | 46 ++++++----
src/uninstall.js | 31 ++++---
src/util/action-stack.js | 24 +++--
12 files changed, 462 insertions(+), 158 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/main.js
----------------------------------------------------------------------
diff --git a/main.js b/main.js
index 414cf18..8339061 100755
--- a/main.js
+++ b/main.js
@@ -63,7 +63,7 @@ else if (!cli_opts.platform || !cli_opts.project || !cli_opts.plugin) {
printUsage();
}
else if (cli_opts.uninstall) {
- plugman.uninstall(cli_opts.platform, cli_opts.project, cli_opts.plugin, plugins_dir, {}, cli_opts.www, true /* is top level? */);
+ plugman.uninstall(cli_opts.platform, cli_opts.project, cli_opts.plugin, plugins_dir, {}, cli_opts.www);
}
else {
var cli_variables = {}
@@ -74,7 +74,7 @@ else {
if (/^[\w-_]+$/.test(key)) cli_variables[key] = tokens.join('=');
});
}
- plugman.install(cli_opts.platform, cli_opts.project, cli_opts.plugin, plugins_dir, '.', cli_variables, cli_opts.www, true /* is top level? */);
+ plugman.install(cli_opts.platform, cli_opts.project, cli_opts.plugin, plugins_dir, '.', cli_variables, cli_opts.www);
}
function printUsage() {
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/common.spec.js
----------------------------------------------------------------------
diff --git a/spec/common.spec.js b/spec/common.spec.js
deleted file mode 100644
index e69de29..0000000
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/install.spec.js
----------------------------------------------------------------------
diff --git a/spec/install.spec.js b/spec/install.spec.js
index c471747..34bc9e2 100644
--- a/spec/install.spec.js
+++ b/spec/install.spec.js
@@ -1,6 +1,6 @@
var install = require('../src/install'),
- android = require('../src/platforms/android'),
common = require('../src/platforms/common'),
+ actions = require('../src/util/action-stack'),
//ios = require('../src/platforms/ios'),
//blackberry = require('../src/platforms/blackberry'),
config_changes = require('../src/util/config-changes'),
@@ -11,7 +11,13 @@ var install = require('../src/install'),
shell = require('shelljs'),
temp = path.join(os.tmpdir(), 'plugman'),
childbrowser = path.join(__dirname, 'plugins', 'ChildBrowser'),
+ dep_a = path.join(__dirname, 'plugins', 'dependencies', 'A'),
+ dep_b = path.join(__dirname, 'plugins', 'dependencies', 'B'),
+ dep_c = path.join(__dirname, 'plugins', 'dependencies', 'C'),
+ dep_d = path.join(__dirname, 'plugins', 'dependencies', 'D'),
+ dep_e = path.join(__dirname, 'plugins', 'dependencies', 'E'),
dummyplugin = path.join(__dirname, 'plugins', 'DummyPlugin'),
+ dummy_id = 'com.phonegap.plugins.dummyplugin',
variableplugin = path.join(__dirname, 'plugins', 'VariablePlugin'),
faultyplugin = path.join(__dirname, 'plugins', 'FaultyPlugin'),
android_one_project = path.join(__dirname, 'projects', 'android_one', '*');
@@ -24,26 +30,19 @@ describe('install', function() {
beforeEach(function() {
shell.mkdir('-p', temp);
- shell.mkdir('-p', plugins_dir);
shell.cp('-rf', android_one_project, temp);
});
afterEach(function() {
shell.rm('-rf', temp);
});
-
describe('success', function() {
- var android_installer;
- beforeEach(function() {
- shell.cp('-rf', dummyplugin, plugins_dir);
- android_installer = spyOn(android, 'install');
- });
it('should properly install assets', function() {
var s = spyOn(common, 'copyFile').andCallThrough();
- install('android', temp, 'DummyPlugin', plugins_dir, {});
+ install('android', temp, dummyplugin, plugins_dir, '.', {});
// making sure the right methods were called
expect(s).toHaveBeenCalled();
- expect(s.calls.length).toEqual(2);
+ expect(s.calls.length).toEqual(3);
expect(fs.existsSync(path.join(temp, 'assets', 'www', 'dummyplugin.js'))).toBe(true);
expect(fs.existsSync(path.join(temp, 'assets', 'www', 'dummyplugin'))).toBe(true);
@@ -57,14 +56,16 @@ describe('install', function() {
var sRemoveFile = spyOn(common, 'removeFile').andCallThrough();
var sRemoveFileF = spyOn(common, 'removeFileF').andCallThrough();
- // messing the plugin
- shell.rm('-rf', path.join(plugins_dir, 'dummyplugin', 'www', 'dummyplugin'));
+ // messing with the plugin
+ shell.mkdir('-p', plugins_dir);
+ shell.cp('-rf', dummyplugin, plugins_dir);
+ shell.rm('-rf', path.join(plugins_dir, 'DummyPlugin', 'www', 'dummyplugin'));
expect(function() {
- install('android', temp, 'DummyPlugin', plugins_dir, {});
+ install('android', temp, 'DummyPlugin', plugins_dir, '.', {});
}).toThrow();
// making sure the right methods were called
expect(sCopyFile).toHaveBeenCalled();
- expect(sCopyFile.calls.length).toEqual(2);
+ expect(sCopyFile.calls.length).toEqual(3);
expect(sRemoveFile).toHaveBeenCalled();
expect(sRemoveFile.calls.length).toEqual(1);
@@ -77,10 +78,10 @@ describe('install', function() {
it('should properly install assets into a custom www dir', function() {
var s = spyOn(common, 'copyFile').andCallThrough();
- install('android', temp, 'DummyPlugin', plugins_dir, {}, path.join(temp, 'staging'));
+ install('android', temp, dummyplugin, plugins_dir, '.', {}, path.join(temp, 'staging'));
// making sure the right methods were called
expect(s).toHaveBeenCalled();
- expect(s.calls.length).toEqual(2);
+ expect(s.calls.length).toEqual(3);
expect(fs.existsSync(path.join(temp, 'staging', 'dummyplugin.js'))).toBe(true);
expect(fs.existsSync(path.join(temp, 'staging', 'dummyplugin'))).toBe(true);
@@ -96,13 +97,15 @@ describe('install', function() {
var sRemoveFileF = spyOn(common, 'removeFileF').andCallThrough();
// messing the plugin
+ shell.mkdir('-p', plugins_dir);
+ shell.cp('-rf', dummyplugin, plugins_dir);
shell.rm('-rf', path.join(plugins_dir, 'dummyplugin', 'www', 'dummyplugin'));
expect(function() {
- install('android', temp, 'DummyPlugin', plugins_dir, {}, path.join(temp, 'staging'));
+ install('android', temp, 'DummyPlugin', plugins_dir, '.', {}, path.join(temp, 'staging'));
}).toThrow();
// making sure the right methods were called
expect(sCopyFile).toHaveBeenCalled();
- expect(sCopyFile.calls.length).toEqual(2);
+ expect(sCopyFile.calls.length).toEqual(3);
expect(sRemoveFile).toHaveBeenCalled();
expect(sRemoveFile.calls.length).toEqual(1);
@@ -115,38 +118,56 @@ describe('install', function() {
it('should call prepare after a successful install', function() {
var s = spyOn(plugman, 'prepare');
- install('android', temp, 'DummyPlugin', plugins_dir, {});
- android_installer.mostRecentCall.args[5](); // fake the installer calling back successfully
+ install('android', temp, dummyplugin, plugins_dir, '.', {});
expect(s).toHaveBeenCalled();
});
it('should call fetch if provided plugin cannot be resolved locally', function() {
var s = spyOn(plugman, 'fetch');
- install('android', temp, 'CLEANYOURSHORTS', plugins_dir, {});
+ install('android', temp, 'CLEANYOURSHORTS', plugins_dir, '.', {});
expect(s).toHaveBeenCalled();
});
- it('should generate an array of transactions required to run an installation and pass into appropriate platform handler\'s install method', function() {
- install('android', temp, 'DummyPlugin', plugins_dir, {});
- var transactions = android_installer.mostRecentCall.args[0];
-
- expect(transactions.length).toEqual(1);
- expect(transactions[0].tag).toBe('source-file');
- });
it('should call the config-changes module\'s add_installed_plugin_to_prepare_queue method', function() {
- install('android', temp, 'DummyPlugin', plugins_dir, {});
var spy = spyOn(config_changes, 'add_installed_plugin_to_prepare_queue');
- android_installer.mostRecentCall.args[5](null); // fake out handler install callback
- expect(spy).toHaveBeenCalledWith(plugins_dir, 'DummyPlugin', 'android', {});
+ install('android', temp, dummyplugin, plugins_dir, '.', {});
+ expect(spy).toHaveBeenCalledWith(plugins_dir, dummy_id, 'android', {}, true);
+ });
+ it('should notify if plugin is already installed into project', function() {
+ expect(function() {
+ install('android', temp, dummyplugin, plugins_dir,'.', {});
+ }).not.toThrow();
+ var spy = spyOn(console, 'log');
+ install('android', temp, dummyplugin, plugins_dir, '.', {});
+ expect(spy).toHaveBeenCalledWith('Plugin "com.phonegap.plugins.dummyplugin" already installed, \'sall good.');
+ });
+
+ describe('with dependencies', function() {
+ it('should process all dependent plugins', function() {
+ var spy = spyOn(actions.prototype, 'process').andCallThrough();
+ shell.mkdir('-p', plugins_dir);
+ shell.cp('-rf', dep_a, plugins_dir);
+ shell.cp('-rf', dep_d, plugins_dir);
+ shell.cp('-rf', dep_c, plugins_dir);
+ install('android', temp, 'A', plugins_dir, '.', {});
+ expect(spy.calls.length).toEqual(3);
+ });
+ it('should fetch any dependent plugins if missing', function() {
+ var spy = spyOn(plugman, 'fetch');
+ shell.mkdir('-p', plugins_dir);
+ shell.cp('-rf', dep_a, plugins_dir);
+ shell.cp('-rf', dep_c, plugins_dir);
+ install('android', temp, 'A', plugins_dir, '.', {});
+ expect(spy).toHaveBeenCalled();
+ });
});
});
describe('failure', function() {
it('should throw if asset target already exists', function() {
- shell.cp('-rf', dummyplugin, plugins_dir);
var target = path.join(temp, 'assets', 'www', 'dummyplugin.js');
fs.writeFileSync(target, 'some bs', 'utf-8');
expect(function() {
- install('android', temp, 'DummyPlugin', plugins_dir, {});
+ install('android', temp, dummyplugin, plugins_dir, '.', {});
}).toThrow();
});
it('should throw if platform is unrecognized', function() {
@@ -155,44 +176,28 @@ describe('install', function() {
}).toThrow('atari not supported.');
});
it('should throw if variables are missing', function() {
- shell.cp('-rf', variableplugin, plugins_dir);
expect(function() {
- install('android', temp, 'VariablePlugin', plugins_dir, {});
+ install('android', temp, variableplugin, plugins_dir, '.', {});
}).toThrow('Variable(s) missing: API_KEY');
});
- it('should handle a failed install by passing completed transactions into appropriate handler\'s uninstall method', function() {
- shell.cp('-rf', faultyplugin, plugins_dir);
- var s = spyOn(android, 'uninstall');
- install('android', temp, 'FaultyPlugin', plugins_dir, {});
-
- var executed_txs = s.mostRecentCall.args[0];
- expect(executed_txs.length).toEqual(0);
- });
- it('should throw if plugin is already installed into project', function() {
- // TODO: plugins and their version can be recognized using the platform.json file
+ it('should throw if a file required for installation cannot be found', function() {
+ shell.mkdir('-p', plugins_dir);
shell.cp('-rf', dummyplugin, plugins_dir);
+ shell.rm(path.join(plugins_dir, 'DummyPlugin', 'src', 'android', 'DummyPlugin.java'));
+
expect(function() {
- install('android', temp, 'DummyPlugin', plugins_dir, {});
- }).not.toThrow();
- expect(function() {
- install('android', temp, 'DummyPlugin', plugins_dir, {});
+ install('android', temp, 'DummyPlugin', plugins_dir, '.', {});
}).toThrow();
});
- it('should revert web assets if an install error occurs', function() {
- var sRemoveFile = spyOn(common, 'removeFile').andCallThrough();
- var sRemoveFileF = spyOn(common, 'removeFileF').andCallThrough();
+ it('should pass error into specified callback if a file required for installation cannot be found', function(done) {
+ shell.mkdir('-p', plugins_dir);
shell.cp('-rf', dummyplugin, plugins_dir);
shell.rm(path.join(plugins_dir, 'DummyPlugin', 'src', 'android', 'DummyPlugin.java'));
- install('android', temp, 'DummyPlugin', plugins_dir, {}, undefined, function() {});
-
- expect(sRemoveFile).toHaveBeenCalled();
- expect(sRemoveFile.calls.length).toEqual(2);
- expect(sRemoveFileF).toHaveBeenCalled();
- expect(sRemoveFileF.calls.length).toEqual(1);
-
- expect(fs.existsSync(path.join(temp, 'assets', 'www', 'dummyplugin.js'))).toBe(false);
- expect(fs.existsSync(path.join(temp, 'assets', 'www', 'dummyplugin'))).toBe(false);
+ install('android', temp, 'DummyPlugin', plugins_dir, '.', {}, null, function(err) {
+ expect(err).toBeDefined();
+ done();
+ });
});
});
});
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/A/plugin.xml
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/A/plugin.xml b/spec/plugins/dependencies/A/plugin.xml
new file mode 100644
index 0000000..604f191
--- /dev/null
+++ b/spec/plugins/dependencies/A/plugin.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2013 Anis Kadri
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ id="A"
+ version="0.6.0">
+
+ <name>Plugin A</name>
+
+ <dependency id="C" />
+ <dependency id="D" url="D" />
+
+ <asset src="www/plugin-a.js" target="plugin-a.js" />
+
+ <config-file target="config.xml" parent="/*">
+ <access origin="build.phonegap.com" />
+ </config-file>
+
+ <!-- android -->
+ <platform name="android">
+ <config-file target="res/xml/config.xml" parent="plugins">
+ <plugin name="A"
+ value="com.phonegap.A.A"/>
+ </config-file>
+
+ <source-file src="src/android/A.java"
+ target-dir="src/com/phonegap/A" />
+ </platform>
+
+
+ <!-- ios -->
+ <platform name="ios">
+ <!-- CDV 2.5+ -->
+ <config-file target="config.xml" parent="plugins">
+ <plugin name="A"
+ value="APluginCommand"/>
+ </config-file>
+
+ <header-file src="src/ios/APluginCommand.h" />
+ <source-file src="src/ios/APluginCommand.m"/>
+ </platform>
+</plugin>
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/A/src/android/A.java
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/A/src/android/A.java b/spec/plugins/dependencies/A/src/android/A.java
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/A/src/ios/APluginCommand.h
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/A/src/ios/APluginCommand.h b/spec/plugins/dependencies/A/src/ios/APluginCommand.h
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/A/src/ios/APluginCommand.m
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/A/src/ios/APluginCommand.m b/spec/plugins/dependencies/A/src/ios/APluginCommand.m
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/A/www/plugin-a.js
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/A/www/plugin-a.js b/spec/plugins/dependencies/A/www/plugin-a.js
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/B/plugin.xml
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/B/plugin.xml b/spec/plugins/dependencies/B/plugin.xml
new file mode 100644
index 0000000..6f92495
--- /dev/null
+++ b/spec/plugins/dependencies/B/plugin.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2013 Anis Kadri
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ id="B"
+ version="0.6.0">
+
+ <name>Plugin B</name>
+
+ <dependency id="D" />
+ <dependency id="E" />
+
+ <asset src="www/plugin-b.js" target="plugin-b.js" />
+
+ <config-file target="config.xml" parent="/*">
+ <access origin="build.phonegap.com" />
+ </config-file>
+
+ <!-- android -->
+ <platform name="android">
+ <config-file target="res/xml/config.xml" parent="plugins">
+ <plugin name="B"
+ value="com.phonegap.B.B"/>
+ </config-file>
+
+ <source-file src="src/android/B.java"
+ target-dir="src/com/phonegap/B" />
+ </platform>
+
+
+ <!-- ios -->
+ <platform name="ios">
+ <!-- CDV 2.5+ -->
+ <config-file target="config.xml" parent="plugins">
+ <plugin name="B"
+ value="BPluginCommand"/>
+ </config-file>
+
+ <header-file src="src/ios/BPluginCommand.h" />
+ <source-file src="src/ios/BPluginCommand.m"/>
+ </platform>
+</plugin>
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/B/src/android/B.java
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/B/src/android/B.java b/spec/plugins/dependencies/B/src/android/B.java
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/B/src/ios/BPluginCommand.h
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/B/src/ios/BPluginCommand.h b/spec/plugins/dependencies/B/src/ios/BPluginCommand.h
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/B/src/ios/BPluginCommand.m
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/B/src/ios/BPluginCommand.m b/spec/plugins/dependencies/B/src/ios/BPluginCommand.m
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/B/www/plugin-b.js
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/B/www/plugin-b.js b/spec/plugins/dependencies/B/www/plugin-b.js
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/C/plugin.xml
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/C/plugin.xml b/spec/plugins/dependencies/C/plugin.xml
new file mode 100644
index 0000000..5baf559
--- /dev/null
+++ b/spec/plugins/dependencies/C/plugin.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2013 Anis Kadri
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ id="C"
+ version="0.6.0">
+
+ <name>Plugin C</name>
+
+ <asset src="www/plugin-c.js" target="plugin-c.js" />
+
+ <config-file target="config.xml" parent="/*">
+ <access origin="build.phonegap.com" />
+ </config-file>
+
+ <!-- android -->
+ <platform name="android">
+ <config-file target="res/xml/config.xml" parent="plugins">
+ <plugin name="C"
+ value="com.phonegap.C.C"/>
+ </config-file>
+
+ <source-file src="src/android/C.java"
+ target-dir="src/com/phonegap/C" />
+ </platform>
+
+
+ <!-- ios -->
+ <platform name="ios">
+ <!-- CDV 2.5+ -->
+ <config-file target="config.xml" parent="plugins">
+ <plugin name="C"
+ value="CPluginCommand"/>
+ </config-file>
+
+ <header-file src="src/ios/CPluginCommand.h" />
+ <source-file src="src/ios/CPluginCommand.m"/>
+ </platform>
+</plugin>
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/C/src/android/C.java
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/C/src/android/C.java b/spec/plugins/dependencies/C/src/android/C.java
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/C/src/ios/CPluginCommand.h
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/C/src/ios/CPluginCommand.h b/spec/plugins/dependencies/C/src/ios/CPluginCommand.h
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/C/src/ios/CPluginCommand.m
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/C/src/ios/CPluginCommand.m b/spec/plugins/dependencies/C/src/ios/CPluginCommand.m
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/C/www/plugin-c.js
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/C/www/plugin-c.js b/spec/plugins/dependencies/C/www/plugin-c.js
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/D/plugin.xml
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/D/plugin.xml b/spec/plugins/dependencies/D/plugin.xml
new file mode 100644
index 0000000..94449ef
--- /dev/null
+++ b/spec/plugins/dependencies/D/plugin.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2013 Anis Kadri
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ id="D"
+ version="0.6.0">
+
+ <name>Plugin D</name>
+
+ <asset src="www/plugin-d.js" target="plugin-d.js" />
+
+ <config-file target="config.xml" parent="/*">
+ <access origin="build.phonegap.com" />
+ </config-file>
+
+ <!-- android -->
+ <platform name="android">
+ <config-file target="res/xml/config.xml" parent="plugins">
+ <plugin name="D"
+ value="com.phonegap.D.D"/>
+ </config-file>
+
+ <source-file src="src/android/D.java"
+ target-dir="src/com/phonegap/D" />
+ </platform>
+
+
+ <!-- ios -->
+ <platform name="ios">
+ <!-- CDV 2.5+ -->
+ <config-file target="config.xml" parent="plugins">
+ <plugin name="D"
+ value="DPluginCommand"/>
+ </config-file>
+
+ <header-file src="src/ios/DPluginCommand.h" />
+ <source-file src="src/ios/DPluginCommand.m"/>
+ </platform>
+</plugin>
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/D/src/android/D.java
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/D/src/android/D.java b/spec/plugins/dependencies/D/src/android/D.java
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/D/src/ios/DPluginCommand.h
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/D/src/ios/DPluginCommand.h b/spec/plugins/dependencies/D/src/ios/DPluginCommand.h
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/D/src/ios/DPluginCommand.m
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/D/src/ios/DPluginCommand.m b/spec/plugins/dependencies/D/src/ios/DPluginCommand.m
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/D/www/plugin-d.js
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/D/www/plugin-d.js b/spec/plugins/dependencies/D/www/plugin-d.js
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/E/plugin.xml
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/E/plugin.xml b/spec/plugins/dependencies/E/plugin.xml
new file mode 100644
index 0000000..2564e96
--- /dev/null
+++ b/spec/plugins/dependencies/E/plugin.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2013 Anis Kadri
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ id="E"
+ version="0.6.0">
+
+ <name>Plugin E</name>
+
+ <asset src="www/plugin-e.js" target="plugin-e.js" />
+
+ <config-file target="config.xml" parent="/*">
+ <access origin="build.phonegap.com" />
+ </config-file>
+
+ <!-- android -->
+ <platform name="android">
+ <config-file target="res/xml/config.xml" parent="plugins">
+ <plugin name="E"
+ value="com.phonegap.E.E"/>
+ </config-file>
+
+ <source-file src="src/android/E.java"
+ target-dir="src/com/phonegap/E" />
+ </platform>
+
+
+ <!-- ios -->
+ <platform name="ios">
+ <!-- CDV 2.5+ -->
+ <config-file target="config.xml" parent="plugins">
+ <plugin name="E"
+ value="EPluginCommand"/>
+ </config-file>
+
+ <header-file src="src/ios/EPluginCommand.h" />
+ <source-file src="src/ios/EPluginCommand.m"/>
+ </platform>
+</plugin>
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/E/src/android/E.java
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/E/src/android/E.java b/spec/plugins/dependencies/E/src/android/E.java
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/E/src/ios/EPluginCommand.h
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/E/src/ios/EPluginCommand.h b/spec/plugins/dependencies/E/src/ios/EPluginCommand.h
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/E/src/ios/EPluginCommand.m
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/E/src/ios/EPluginCommand.m b/spec/plugins/dependencies/E/src/ios/EPluginCommand.m
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/E/www/plugin-e.js
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/E/www/plugin-e.js b/spec/plugins/dependencies/E/www/plugin-e.js
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/plugins/dependencies/README.md
----------------------------------------------------------------------
diff --git a/spec/plugins/dependencies/README.md b/spec/plugins/dependencies/README.md
new file mode 100644
index 0000000..29cc70f
--- /dev/null
+++ b/spec/plugins/dependencies/README.md
@@ -0,0 +1,5 @@
+Here's a general overview of how the plugins in this directory are dependent on each other:
+
+ A B
+ / \ / \
+ C '---D--' E
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/spec/uninstall.spec.js
----------------------------------------------------------------------
diff --git a/spec/uninstall.spec.js b/spec/uninstall.spec.js
index c39812a..99d6026 100644
--- a/spec/uninstall.spec.js
+++ b/spec/uninstall.spec.js
@@ -1,6 +1,7 @@
var uninstall = require('../src/uninstall'),
install = require('../src/install'),
common = require('../src/platforms/common'),
+ actions = require('../src/util/action-stack'),
android = require('../src/platforms/android'),
ios = require('../src/platforms/ios'),
blackberry = require('../src/platforms/blackberry'),
@@ -14,41 +15,44 @@ var uninstall = require('../src/uninstall'),
shell = require('shelljs'),
temp = path.join(os.tmpdir(), 'plugman'),
dummyplugin = path.join(__dirname, 'plugins', 'DummyPlugin'),
+ dummy_id = 'com.phonegap.plugins.dummyplugin',
faultyplugin = path.join(__dirname, 'plugins', 'FaultyPlugin'),
childbrowserplugin = path.join(__dirname, 'plugins', 'ChildBrowser'),
+ dep_a = path.join(__dirname, 'plugins', 'dependencies', 'A'),
+ dep_b = path.join(__dirname, 'plugins', 'dependencies', 'B'),
+ dep_c = path.join(__dirname, 'plugins', 'dependencies', 'C'),
+ dep_d = path.join(__dirname, 'plugins', 'dependencies', 'D'),
+ dep_e = path.join(__dirname, 'plugins', 'dependencies', 'E'),
android_one_project = path.join(__dirname, 'projects', 'android_one', '*'),
ios_project = path.join(__dirname, 'projects', 'ios-config-xml', '*'),
plugins_dir = path.join(temp, 'cordova', 'plugins');
describe('uninstall', function() {
var copied_plugin_path = path.join(temp,'ChildBrowser');
+ var dummy_plugin_path = path.join(plugins_dir, dummy_id);
beforeEach(function() {
shell.mkdir('-p', temp);
- shell.mkdir('-p', plugins_dir);
shell.cp('-rf', android_one_project, temp);
- shell.cp('-rf', dummyplugin, plugins_dir);
});
afterEach(function() {
shell.rm('-rf', temp);
});
describe('success', function() {
- var android_uninstaller;
beforeEach(function() {
- install('android', temp, 'DummyPlugin', plugins_dir, {});
- android_uninstaller = spyOn(android, 'uninstall');
+ install('android', temp, dummyplugin, plugins_dir, '.', {});
});
it('should properly uninstall assets', function() {
var s = spyOn(common, 'removeFile').andCallThrough();
var s2 = spyOn(common, 'removeFileF').andCallThrough();
// making sure the right methods were called
- uninstall('android', temp, 'DummyPlugin', plugins_dir, {});
+ uninstall('android', temp, dummy_id, plugins_dir, {});
expect(s).toHaveBeenCalled();
expect(s.calls.length).toEqual(2);
expect(s2).toHaveBeenCalled();
- expect(s2.calls.length).toEqual(1);
+ expect(s2.calls.length).toEqual(2);
expect(fs.existsSync(path.join(temp, 'assets', 'www', 'dummyplugin.js'))).toBe(false);
expect(fs.existsSync(path.join(temp, 'assets', 'www', 'dummyplugin'))).toBe(false);
@@ -61,28 +65,46 @@ describe('uninstall', function() {
shell.rm('-rf', path.join(temp, 'assets', 'www', 'dummyplugin'));
expect(function() {
- uninstall('android', temp, 'DummyPlugin', plugins_dir, {});
+ uninstall('android', temp, dummy_id, plugins_dir, {});
}).toThrow();
expect(sRemoveFile).toHaveBeenCalled();
expect(sRemoveFile.calls.length).toEqual(2);
expect(sCopyFile).toHaveBeenCalled();
- expect(sCopyFile.calls.length).toEqual(1);
+ expect(sCopyFile.calls.length).toEqual(2);
expect(fs.existsSync(path.join(temp, 'assets', 'www', 'dummyplugin.js'))).toBe(true);
});
- it('should generate and pass uninstall transaction log to appropriate platform handler\'s uninstall', function() {
- uninstall('android', temp, 'DummyPlugin', plugins_dir, {});
- var transactions = android_uninstaller.mostRecentCall.args[0];
-
- expect(transactions.length).toEqual(1);
- expect(transactions[0].tag).toBe('source-file');
- });
it('should call the config-changes module\'s add_uninstalled_plugin_to_prepare_queue method', function() {
- uninstall('android', temp, 'DummyPlugin', plugins_dir, {});
var spy = spyOn(config_changes, 'add_uninstalled_plugin_to_prepare_queue');
- android_uninstaller.mostRecentCall.args[4](null); // fake out handler uninstall callback
- expect(spy).toHaveBeenCalledWith(plugins_dir, 'DummyPlugin', 'android');
+ uninstall('android', temp, dummy_id, plugins_dir, {});
+ expect(spy).toHaveBeenCalledWith(plugins_dir, dummy_id, 'android', true);
+ });
+
+ describe('with dependencies', function() {
+ it('should uninstall any dependent plugins', function() {
+ shell.mkdir('-p', plugins_dir);
+ shell.cp('-rf', dep_a, plugins_dir);
+ shell.cp('-rf', dep_d, plugins_dir);
+ shell.cp('-rf', dep_c, plugins_dir);
+ install('android', temp, 'A', plugins_dir, '.', {});
+ var spy = spyOn(actions.prototype, 'process').andCallThrough();
+ uninstall('android', temp, 'A', plugins_dir, {});
+ expect(spy.calls.length).toEqual(3);
+ });
+ it('should not uninstall any dependent plugins that are required by other top-level plugins', function() {
+ shell.mkdir('-p', plugins_dir);
+ shell.cp('-rf', dep_a, plugins_dir);
+ shell.cp('-rf', dep_b, plugins_dir);
+ shell.cp('-rf', dep_d, plugins_dir);
+ shell.cp('-rf', dep_c, plugins_dir);
+ shell.cp('-rf', dep_e, plugins_dir);
+ install('android', temp, 'A', plugins_dir, '.', {});
+ install('android', temp, 'B', plugins_dir, '.', {});
+ var spy = spyOn(actions.prototype, 'process').andCallThrough();
+ uninstall('android', temp, 'A', plugins_dir, {});
+ expect(spy.calls.length).toEqual(2);
+ });
});
});
@@ -97,37 +119,5 @@ describe('uninstall', function() {
uninstall('android', temp, 'SomePlugin', plugins_dir, {});
}).toThrow('Plugin "SomePlugin" not found. Already uninstalled?');
});
- // it('should handle a failed uninstall by passing completed transactions into appropriate handler\'s install method', function() {
- // shell.rm('-rf', path.join(temp, '*'));
- // shell.mkdir('-p', plugins_dir);
- //
- // shell.cp('-rf', ios_project, temp);
- // shell.cp('-rf', childbrowserplugin, plugins_dir);
- // install('ios', temp, 'ChildBrowser', plugins_dir, {});
-
- // // make uninstall fail by removing a js asset
- // shell.rm(path.join(temp, 'SampleApp', 'Plugins', 'ChildBrowserCommand.m'));
- // var s = spyOn(ios, 'install');
- // uninstall('ios', temp, 'ChildBrowser', plugins_dir, {});
- // var executed_txs = s.mostRecentCall.args[0];
- // expect(executed_txs.length).toEqual(1);
- // // It only ended up "uninstalling" one source file, so install reversion should pass in that source file to re-install
- // expect(executed_txs[0].tag).toEqual('source-file');
- // });
- it('should revert assets when uninstall fails', function() {
- install('android', temp, 'DummyPlugin', plugins_dir, {});
-
- var s = spyOn(common, 'copyFile').andCallThrough();
-
- shell.rm('-rf', path.join(temp, 'src', 'com', 'phonegap', 'plugins', 'dummyplugin'));
- expect(function() {
- uninstall('android', temp, 'DummyPlugin', plugins_dir, {});
- }).toThrow();
- expect(s).toHaveBeenCalled();
- expect(s.calls.length).toEqual(2);
-
- expect(fs.existsSync(path.join(temp, 'assets', 'www', 'dummyplugin.js'))).toBe(true);
- expect(fs.existsSync(path.join(temp, 'assets', 'www', 'dummyplugin'))).toBe(true);
- });
});
});
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/src/install.js
----------------------------------------------------------------------
diff --git a/src/install.js b/src/install.js
index 37a6dff..9a85e2c 100644
--- a/src/install.js
+++ b/src/install.js
@@ -6,7 +6,7 @@ var path = require('path'),
action_stack = require('./util/action-stack'),
platform_modules = require('./platforms');
-module.exports = function installPlugin(platform, project_dir, id, plugins_dir, subdir, cli_variables, www_dir, is_top_level, callback) {
+module.exports = function installPlugin(platform, project_dir, id, plugins_dir, subdir, cli_variables, www_dir, callback) {
if (!platform_modules[platform]) {
var err = new Error(platform + " not supported.");
if (callback) callback(err);
@@ -14,6 +14,12 @@ module.exports = function installPlugin(platform, project_dir, id, plugins_dir,
return;
}
+ var current_stack = new action_stack();
+
+ possiblyFetch(current_stack, platform, project_dir, id, plugins_dir, subdir, cli_variables, www_dir, true, callback);
+};
+
+function possiblyFetch(actions, platform, project_dir, id, plugins_dir, subdir, cli_variables, www_dir, is_top_level, callback) {
var plugin_dir = path.join(plugins_dir, id);
// Check that the plugin has already been fetched.
@@ -25,15 +31,15 @@ module.exports = function installPlugin(platform, project_dir, id, plugins_dir,
callback(err);
} else {
// update ref to plugin_dir after successful fetch, via fetch callback
- runInstall(platform, project_dir, plugin_dir, plugins_dir, cli_variables, www_dir, is_top_level, callback);
+ runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, cli_variables, www_dir, is_top_level, callback);
}
});
} else {
- runInstall(platform, project_dir, plugin_dir, plugins_dir, cli_variables, www_dir, is_top_level, callback);
+ runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, cli_variables, www_dir, is_top_level, callback);
}
-};
+}
-function runInstall(platform, project_dir, plugin_dir, plugins_dir, cli_variables, www_dir, is_top_level, callback) {
+function runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, cli_variables, www_dir, is_top_level, callback) {
var xml_path = path.join(plugin_dir, 'plugin.xml')
, xml_text = fs.readFileSync(xml_path, 'utf-8')
, plugin_et = new et.ElementTree(et.XML(xml_text))
@@ -83,7 +89,7 @@ function runInstall(platform, project_dir, plugin_dir, plugins_dir, cli_variable
var dependencies = plugin_et.findall('dependency');
if (dependencies && dependencies.length) {
var end = n(dependencies.length, function() {
- handleInstall(plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_basename, plugin_dir, filtered_variables, www_dir, is_top_level, callback);
+ handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_basename, plugin_dir, filtered_variables, www_dir, is_top_level, callback);
});
dependencies.forEach(function(dep) {
var dep_plugin_id = dep.attrib.id;
@@ -92,21 +98,21 @@ function runInstall(platform, project_dir, plugin_dir, plugins_dir, cli_variable
if (dep_subdir) {
dep_subdir = path.join.apply(null, dep_subdir.split('/'));
}
-
- if (fs.existsSync(path.join(plugins_dir, dep_plugin_id))) {
- console.log('Dependent plugin ' + dep.attrib.id + ' already fetched, using that version.');
- module.exports(platform, project_dir, dep_plugin_id, plugins_dir, dep_subdir, filtered_variables, www_dir, false, end);
+ var dep_plugin_dir = path.join(plugins_dir, dep_plugin_id);
+ if (fs.existsSync(dep_plugin_dir)) {
+ console.log('Dependent plugin ' + dep_plugin_id + ' already fetched, using that version.');
+ runInstall(actions, platform, project_dir, dep_plugin_dir, plugins_dir, filtered_variables, www_dir, false, end);
} else {
- console.log('Dependent plugin ' + dep.attrib.id + ' not fetched, retrieving then installing.');
- module.exports(platform, project_dir, dep_url, plugins_dir, dep_subdir, filtered_variables, www_dir, false, end);
+ console.log('Dependent plugin ' + dep_plugin_id + ' not fetched, retrieving then installing.');
+ possiblyFetch(actions, platform, project_dir, dep_url, plugins_dir, dep_subdir, filtered_variables, www_dir, false, end);
}
});
} else {
- handleInstall(plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_basename, plugin_dir, filtered_variables, www_dir, is_top_level, callback);
+ handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_basename, plugin_dir, filtered_variables, www_dir, is_top_level, callback);
}
}
-function handleInstall(plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_basename, plugin_dir, filtered_variables, www_dir, is_top_level, callback) {
+function handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_basename, plugin_dir, filtered_variables, www_dir, is_top_level, callback) {
var handler = platform_modules[platform];
www_dir = www_dir || handler.www_dir(project_dir);
@@ -121,30 +127,30 @@ function handleInstall(plugin_id, plugin_et, platform, project_dir, plugins_dir,
// queue up native stuff
sourceFiles && sourceFiles.forEach(function(source) {
- action_stack.push(action_stack.createAction(handler["source-file"].install, [source, plugin_dir, project_dir], handler["source-file"].uninstall, [source, project_dir]));
+ actions.push(actions.createAction(handler["source-file"].install, [source, plugin_dir, project_dir], handler["source-file"].uninstall, [source, project_dir]));
});
headerFiles && headerFiles.forEach(function(header) {
- action_stack.push(action_stack.createAction(handler["header-file"].install, [header, plugin_dir, project_dir], handler["header-file"].uninstall, [header, project_dir]));
+ actions.push(actions.createAction(handler["header-file"].install, [header, plugin_dir, project_dir], handler["header-file"].uninstall, [header, project_dir]));
});
resourceFiles && resourceFiles.forEach(function(resource) {
- action_stack.push(action_stack.createAction(handler["resource-file"].install, [resource, plugin_dir, project_dir], handler["resource-file"].uninstall, [resource, project_dir]));
+ actions.push(actions.createAction(handler["resource-file"].install, [resource, plugin_dir, project_dir], handler["resource-file"].uninstall, [resource, project_dir]));
});
frameworks && frameworks.forEach(function(framework) {
- action_stack.push(action_stack.createAction(handler["framework"].install, [framework, plugin_dir, project_dir], handler["framework"].uninstall, [framework, project_dir]));
+ actions.push(actions.createAction(handler["framework"].install, [framework, plugin_dir, project_dir], handler["framework"].uninstall, [framework, project_dir]));
});
}
// queue up asset installation
var common = require('./platforms/common');
assets && assets.forEach(function(asset) {
- action_stack.push(action_stack.createAction(common.asset.install, [asset, plugin_dir, www_dir], common.asset.uninstall, [asset, www_dir, plugin_id]));
+ actions.push(actions.createAction(common.asset.install, [asset, plugin_dir, www_dir], common.asset.uninstall, [asset, www_dir, plugin_id]));
});
// run through the action stack
- action_stack.process(platform, project_dir, function(err) {
+ actions.process(platform, project_dir, function(err) {
if (err) {
if (callback) callback(err);
else throw err;
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/src/uninstall.js
----------------------------------------------------------------------
diff --git a/src/uninstall.js b/src/uninstall.js
index 986e7c1..7528876 100644
--- a/src/uninstall.js
+++ b/src/uninstall.js
@@ -9,7 +9,7 @@ var path = require('path'),
underscore = require('underscore'),
platform_modules = require('./platforms');
-module.exports = function uninstallPlugin(platform, project_dir, id, plugins_dir, cli_variables, www_dir, is_top_level, callback) {
+module.exports = function uninstallPlugin(platform, project_dir, id, plugins_dir, cli_variables, www_dir, callback) {
if (!platform_modules[platform]) {
var err = new Error(platform + " not supported.");
if (callback) callback(err);
@@ -20,16 +20,18 @@ module.exports = function uninstallPlugin(platform, project_dir, id, plugins_dir
var plugin_dir = path.join(plugins_dir, id);
if (!fs.existsSync(plugin_dir)) {
- var err = new Error('Plugin "' + name + '" not found. Already uninstalled?');
+ var err = new Error('Plugin "' + id + '" not found. Already uninstalled?');
if (callback) callback(err);
else throw err;
return;
}
- runUninstall(platform, project_dir, plugin_dir, plugins_dir, cli_variables, www_dir, is_top_level, callback);
+ var current_stack = new action_stack();
+
+ runUninstall(current_stack, platform, project_dir, plugin_dir, plugins_dir, cli_variables, www_dir, true, callback);
};
-function runUninstall(platform, project_dir, plugin_dir, plugins_dir, cli_variables, www_dir, is_top_level, callback) {
+function runUninstall(actions, platform, project_dir, plugin_dir, plugins_dir, cli_variables, www_dir, is_top_level, callback) {
var xml_path = path.join(plugin_dir, 'plugin.xml')
, xml_text = fs.readFileSync(xml_path, 'utf-8')
, plugin_et = new et.ElementTree(et.XML(xml_text))
@@ -60,18 +62,19 @@ function runUninstall(platform, project_dir, plugin_dir, plugins_dir, cli_variab
var danglers = underscore.difference.apply(null, diff_arr);
if (dependents.length && danglers && danglers.length) {
var end = n(danglers.length, function() {
- handleUninstall(platform, plugin_id, plugin_et, project_dir, www_dir, plugins_dir, plugin_dir, is_top_level, callback);
+ handleUninstall(actions, platform, plugin_id, plugin_et, project_dir, www_dir, plugins_dir, plugin_dir, is_top_level, callback);
});
danglers.forEach(function(dangler) {
- module.exports(platform, project_dir, dangler, plugins_dir, cli_variables, www_dir, false /* TODO: should this "is_top_level" param be false for dependents? */, end);
+ var dependent_path = path.join(plugins_dir, dangler);
+ runUninstall(actions, platform, project_dir, dependent_path, plugins_dir, cli_variables, www_dir, false /* TODO: should this "is_top_level" param be false for dependents? */, end);
});
} else {
// this plugin can get axed by itself, gogo!
- handleUninstall(platform, plugin_id, plugin_et, project_dir, www_dir, plugins_dir, plugin_dir, is_top_level, callback);
+ handleUninstall(actions, platform, plugin_id, plugin_et, project_dir, www_dir, plugins_dir, plugin_dir, is_top_level, callback);
}
}
-function handleUninstall(platform, plugin_id, plugin_et, project_dir, www_dir, plugins_dir, plugin_dir, is_top_level, callback) {
+function handleUninstall(actions, platform, plugin_id, plugin_et, project_dir, www_dir, plugins_dir, plugin_dir, is_top_level, callback) {
var platform_modules = require('./platforms');
var handler = platform_modules[platform];
var platformTag = plugin_et.find('./platform[@name="'+platform+'"]');
@@ -87,30 +90,30 @@ function handleUninstall(platform, plugin_id, plugin_et, project_dir, www_dir, p
// queue up native stuff
sourceFiles && sourceFiles.forEach(function(source) {
- action_stack.push(action_stack.createAction(handler["source-file"].uninstall, [source, project_dir], handler["source-file"].install, [source, plugin_dir, project_dir]));
+ actions.push(actions.createAction(handler["source-file"].uninstall, [source, project_dir], handler["source-file"].install, [source, plugin_dir, project_dir]));
});
headerFiles && headerFiles.forEach(function(header) {
- action_stack.push(action_stack.createAction(handler["header-file"].uninstall, [header, project_dir], handler["header-file"].install, [header, plugin_dir, project_dir]));
+ actions.push(actions.createAction(handler["header-file"].uninstall, [header, project_dir], handler["header-file"].install, [header, plugin_dir, project_dir]));
});
resourceFiles && resourceFiles.forEach(function(resource) {
- action_stack.push(action_stack.createAction(handler["resource-file"].uninstall, [resource, project_dir], handler["resource-file"].install, [resource, plugin_dir, project_dir]));
+ actions.push(actions.createAction(handler["resource-file"].uninstall, [resource, project_dir], handler["resource-file"].install, [resource, plugin_dir, project_dir]));
});
frameworks && frameworks.forEach(function(framework) {
- action_stack.push(action_stack.createAction(handler["framework"].uninstall, [framework, project_dir], handler["framework"].install, [framework, plugin_dir, project_dir]));
+ actions.push(actions.createAction(handler["framework"].uninstall, [framework, project_dir], handler["framework"].install, [framework, plugin_dir, project_dir]));
});
}
// queue up asset installation
var common = require('./platforms/common');
assets && assets.forEach(function(asset) {
- action_stack.push(action_stack.createAction(common.asset.uninstall, [asset, www_dir, plugin_id], common.asset.install, [asset, plugin_dir, www_dir]));
+ actions.push(actions.createAction(common.asset.uninstall, [asset, www_dir, plugin_id], common.asset.install, [asset, plugin_dir, www_dir]));
});
// run through the action stack
- action_stack.process(platform, project_dir, function(err) {
+ actions.process(platform, project_dir, function(err) {
if (err) {
if (callback) callback(err);
else throw err;
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/bf56f3ed/src/util/action-stack.js
----------------------------------------------------------------------
diff --git a/src/util/action-stack.js b/src/util/action-stack.js
index a76f33c..115c6b7 100644
--- a/src/util/action-stack.js
+++ b/src/util/action-stack.js
@@ -1,10 +1,12 @@
var ios = require('../platforms/ios'),
fs = require('fs');
-var stack = [];
-var completed = [];
+function ActionStack() {
+ this.stack = [];
+ this.completed = [];
+}
-module.exports = {
+ActionStack.prototype = {
createAction:function(handler, action_params, reverter, revert_params) {
return {
handler:{
@@ -18,26 +20,26 @@ module.exports = {
};
},
push:function(tx) {
- stack.push(tx);
+ this.stack.push(tx);
},
process:function(platform, project_dir, callback) {
if (platform == 'ios') {
// parse xcode project file once
var project_files = ios.parseIOSProjectFiles(project_dir);
}
- while(stack.length) {
- var action = stack.shift();
+ while(this.stack.length) {
+ var action = this.stack.shift();
var handler = action.handler.run;
var action_params = action.handler.params;
if (platform == 'ios') action_params.push(project_files);
try {
handler.apply(null, action_params);
} catch(e) {
- var incomplete = stack.unshift(action);
+ var incomplete = this.stack.unshift(action);
var issue = 'Uh oh!\n';
// revert completed tasks
- while(completed.length) {
- var undo = completed.shift();
+ while(this.completed.length) {
+ var undo = this.completed.shift();
var revert = undo.reverter.run;
var revert_params = undo.reverter.params;
if (platform == 'ios') revert_params.push(project_files);
@@ -52,7 +54,7 @@ module.exports = {
else throw e;
return;
}
- completed.push(action);
+ this.completed.push(action);
}
if (platform == 'ios') {
// write out xcodeproj file
@@ -61,3 +63,5 @@ module.exports = {
if (callback) callback();
}
};
+
+module.exports = ActionStack;