Replace shelljs calls with fs-extra & which (#21)
authorDarryl Pogue <dvpdiner2@gmail.com>
Tue, 5 Jun 2018 06:08:50 +0000 (23:08 -0700)
committerRaphael von der GrĂ¼n <raphinesse@gmail.com>
Tue, 5 Jun 2018 06:08:50 +0000 (08:08 +0200)
18 files changed:
package.json
spec/ConfigChanges/ConfigChanges.spec.js
spec/ConfigChanges/ConfigFile.spec.js
spec/ConfigParser/ConfigParser.spec.js
spec/CordovaCheck.spec.js
spec/FileUpdater.spec.js
spec/PlatformJson.spec.js
spec/PluginManager.spec.js
src/ConfigChanges/ConfigFile.js
src/ConfigParser/ConfigParser.js
src/CordovaCheck.js
src/FileUpdater.js
src/PlatformJson.js
src/PluginInfo/PluginInfo.js
src/PluginInfo/PluginInfoProvider.js
src/PluginManager.js
src/superspawn.js
src/util/xml-helpers.js

index dc68545..f0ce2e6 100644 (file)
     "bplist-parser": "^0.1.0",
     "cordova-registry-mapper": "^1.1.8",
     "elementtree": "0.1.7",
+    "fs-extra": "^6.0.1",
     "glob": "^7.1.2",
     "minimatch": "^3.0.0",
     "plist": "^3.0.1",
     "q": "^1.4.1",
-    "shelljs": "^0.8.1",
     "strip-bom": "^3.0.0",
-    "underscore": "^1.8.3"
+    "underscore": "^1.8.3",
+    "which": "^1.3.0"
   },
   "devDependencies": {
     "eslint": "^4.0.0",
index a0abe5c..fe83c70 100644 (file)
 
 var configChanges = require('../../src/ConfigChanges/ConfigChanges');
 var xml_helpers = require('../../src/util/xml-helpers');
-var fs = require('fs');
+var fs = require('fs-extra');
 var os = require('osenv');
 var et = require('elementtree');
 var path = require('path');
-var shell = require('shelljs');
 var temp = path.join(os.tmpdir(), 'plugman');
 var dummyplugin = path.join(__dirname, '../fixtures/plugins/org.test.plugins.dummyplugin');
 var cbplugin = path.join(__dirname, '../fixtures/plugins/org.test.plugins.childbrowser');
@@ -35,9 +34,9 @@ var editconfigplugin_two = path.join(__dirname, '../fixtures/plugins/org.test.ed
 var varplugin = path.join(__dirname, '../fixtures/plugins/com.adobe.vars');
 var plistplugin = path.join(__dirname, '../fixtures/plugins/org.apache.plist');
 var bplistplugin = path.join(__dirname, '../fixtures/plugins/org.apache.bplist');
-var android_two_project = path.join(__dirname, '../fixtures/projects/android_two/*');
-var android_two_no_perms_project = path.join(__dirname, '../fixtures/projects/android_two_no_perms', '*');
-var ios_config_xml = path.join(__dirname, '../fixtures/projects/ios-config-xml/*');
+var android_two_project = path.join(__dirname, '../fixtures/projects/android_two/');
+var android_two_no_perms_project = path.join(__dirname, '../fixtures/projects/android_two_no_perms');
+var ios_config_xml = path.join(__dirname, '../fixtures/projects/ios-config-xml/');
 var plugins_dir = path.join(temp, 'cordova', 'plugins');
 var mungeutil = require('../../src/ConfigChanges/munge-util');
 var PlatformJson = require('../../src/PlatformJson');
@@ -61,13 +60,17 @@ function get_munge_change () {
     return mungeutil.deep_find.apply(null, arguments);
 }
 
+function install_plugin (pluginPath) {
+    fs.copySync(pluginPath, path.join(plugins_dir, path.basename(pluginPath)));
+}
+
 describe('config-changes module', function () {
     beforeEach(function () {
-        shell.mkdir('-p', temp);
-        shell.mkdir('-p', plugins_dir);
+        fs.ensureDirSync(temp);
+        fs.ensureDirSync(plugins_dir);
     });
     afterEach(function () {
-        shell.rm('-rf', temp);
+        fs.removeSync(temp);
     });
 
     describe('queue methods', function () {
@@ -131,7 +134,7 @@ describe('config-changes module', function () {
     describe('generate_plugin_config_munge method', function () {
         describe('for android projects', function () {
             beforeEach(function () {
-                shell.cp('-rf', android_two_project, temp);
+                fs.copySync(android_two_project, temp);
             });
             it('Test 007 : should return a flat config hierarchy for simple, one-off config changes', function () {
                 var xml;
@@ -196,10 +199,10 @@ describe('config-changes module', function () {
 
     describe('processing of plugins (via process method)', function () {
         beforeEach(function () {
-            shell.cp('-rf', dummyplugin, plugins_dir);
+            install_plugin(dummyplugin);
         });
         it('Test 014 : should generate config munges for queued plugins', function () {
-            shell.cp('-rf', android_two_project, temp);
+            fs.copySync(android_two_project, temp);
             var platformJson = PlatformJson.load(plugins_dir, 'android');
             platformJson.root.prepare_queue.installed = [{'plugin': 'org.test.plugins.dummyplugin', 'vars': {}}];
             var munger = new configChanges.PlatformMunger('android', temp, platformJson, pluginInfoProvider);
@@ -210,7 +213,7 @@ describe('config-changes module', function () {
         describe(': installation', function () {
             describe('of xml config files', function () {
                 beforeEach(function () {
-                    shell.cp('-rf', android_two_project, temp);
+                    fs.copySync(android_two_project, temp);
                 });
                 it('Test 015 : should call graftXML for every new config munge it introduces (every leaf in config munge that does not exist)', function () {
                     var platformJson = PlatformJson.load(plugins_dir, 'android');
@@ -227,7 +230,7 @@ describe('config-changes module', function () {
                     expect(spy.calls.argsFor(3)[2]).toEqual('/cordova/plugins');
                 });
                 it('Test 016 : should not call graftXML for a config munge that already exists from another plugin', function () {
-                    shell.cp('-rf', configplugin, plugins_dir);
+                    install_plugin(configplugin);
                     var platformJson = PlatformJson.load(plugins_dir, 'android');
                     platformJson.addInstalledPluginToPrepareQueue('org.test.configtest', {});
 
@@ -247,7 +250,8 @@ describe('config-changes module', function () {
                     expect(spy).not.toHaveBeenCalledWith(path.join(temp, 'res', 'xml', 'plugins.xml'), 'utf-8');
                 });
                 it('Test 018 : should call graftXMLMerge for every new config munge with mode \'merge\' it introduces', function () {
-                    shell.cp('-rf', editconfigplugin, plugins_dir);
+                    install_plugin(editconfigplugin);
+
                     var platformJson = PlatformJson.load(plugins_dir, 'android');
                     platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest', {});
 
@@ -259,8 +263,9 @@ describe('config-changes module', function () {
                     expect(spy.calls.argsFor(0)[2]).toEqual('/manifest/application/activity[@android:name=\'org.test.DroidGap\']');
                 });
                 it('Test 019 : should call graftXMLMerge with --force for every new config munge with mode \'merge\' it introduces', function () {
-                    shell.cp('-rf', editconfigplugin, plugins_dir);
-                    shell.cp('-rf', editconfigplugin_two, plugins_dir);
+                    install_plugin(editconfigplugin);
+                    install_plugin(editconfigplugin_two);
+
                     var platformJson = PlatformJson.load(plugins_dir, 'android');
                     platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest', {});
                     platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest_two', {}, true, true);
@@ -275,7 +280,8 @@ describe('config-changes module', function () {
                     expect(spy.calls.argsFor(2)[2]).toEqual('/manifest/uses-sdk');
                 });
                 it('Test 020 : should call graftXMLOverwrite for every new config munge with mode \'overwrite\' it introduces', function () {
-                    shell.cp('-rf', editconfigplugin, plugins_dir);
+                    install_plugin(editconfigplugin);
+
                     var platformJson = PlatformJson.load(plugins_dir, 'android');
                     platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest', {});
 
@@ -287,8 +293,9 @@ describe('config-changes module', function () {
                     expect(spy.calls.argsFor(0)[2]).toEqual('/manifest/application/activity');
                 });
                 it('Test 021 : should call graftXMLOverwrite with --force for every new config munge with mode \'overwrite\' it introduces', function () {
-                    shell.cp('-rf', editconfigplugin, plugins_dir);
-                    shell.cp('-rf', editconfigplugin_two, plugins_dir);
+                    install_plugin(editconfigplugin);
+                    install_plugin(editconfigplugin_two);
+
                     var platformJson = PlatformJson.load(plugins_dir, 'android');
                     platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest', {});
                     platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest_two', {}, true, true);
@@ -302,8 +309,9 @@ describe('config-changes module', function () {
                     expect(spy.calls.argsFor(1)[2]).toEqual('/manifest/application/activity[@android:name=\'ChildApp\']');
                 });
                 it('Test 022 : should not install plugin when there are edit-config conflicts', function () {
-                    shell.cp('-rf', editconfigplugin, plugins_dir);
-                    shell.cp('-rf', editconfigplugin_two, plugins_dir);
+                    install_plugin(editconfigplugin);
+                    install_plugin(editconfigplugin_two);
+
                     var platformJson = PlatformJson.load(plugins_dir, 'android');
                     platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest', {});
                     platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest_two', {});
@@ -348,7 +356,8 @@ describe('config-changes module', function () {
                     expect(sdk.attrib['android:maxSdkVersion']).toBeUndefined();
                 });
                 it('should overwrite plugin config munge for every conflicting config.xml config munge', function () {
-                    shell.cp('-rf', editconfigplugin_two, plugins_dir);
+                    install_plugin(editconfigplugin_two);
+
                     var platformJson = PlatformJson.load(plugins_dir, 'android');
                     platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest_two', {}, true, true);
 
@@ -396,7 +405,8 @@ describe('config-changes module', function () {
                     expect(am_file.indexOf('android:name="zoo"')).toBeLessThan(am_file.indexOf('android:name="com.foo.Bar"'));
                 });
                 it('should throw error for conflicting plugin config munge with config.xml config munge', function () {
-                    shell.cp('-rf', editconfigplugin_two, plugins_dir);
+                    install_plugin(editconfigplugin_two);
+
                     var platformJson = PlatformJson.load(plugins_dir, 'android');
                     platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest_two', {}, true, true);
 
@@ -408,16 +418,18 @@ describe('config-changes module', function () {
             });
             describe('of plist config files', function () {
                 it('Test 023 : should write empty string nodes with no whitespace', function () {
-                    shell.cp('-rf', ios_config_xml, temp);
-                    shell.cp('-rf', varplugin, plugins_dir);
+                    fs.copySync(ios_config_xml, temp);
+                    install_plugin(varplugin);
+
                     var platformJson = PlatformJson.load(plugins_dir, 'ios');
                     platformJson.addInstalledPluginToPrepareQueue('com.adobe.vars', {});
                     configChanges.process(plugins_dir, temp, 'ios', platformJson, pluginInfoProvider);
                     expect(fs.readFileSync(path.join(temp, 'SampleApp', 'SampleApp-Info.plist'), 'utf-8')).toMatch(/<key>APluginNode<\/key>\n {4}<string\/>/m);
                 });
                 it('Test 024 : should merge dictionaries and arrays, removing duplicates', function () {
-                    shell.cp('-rf', ios_config_xml, temp);
-                    shell.cp('-rf', plistplugin, plugins_dir);
+                    fs.copySync(ios_config_xml, temp);
+                    install_plugin(plistplugin);
+
                     var platformJson = PlatformJson.load(plugins_dir, 'ios');
                     platformJson.addInstalledPluginToPrepareQueue('org.apache.plist', {});
                     configChanges.process(plugins_dir, temp, 'ios', platformJson, pluginInfoProvider);
@@ -428,8 +440,9 @@ describe('config-changes module', function () {
             });
             describe('of binary plist config files', function () {
                 it('should merge dictionaries and arrays, removing duplicates', function () {
-                    shell.cp('-rf', ios_config_xml, temp);
-                    shell.cp('-rf', bplistplugin, plugins_dir);
+                    fs.copySync(ios_config_xml, temp);
+                    install_plugin(bplistplugin);
+
                     var platformJson = PlatformJson.load(plugins_dir, 'ios');
                     platformJson.addInstalledPluginToPrepareQueue('org.apache.bplist', {});
                     configChanges.process(plugins_dir, temp, 'ios', platformJson, pluginInfoProvider);
@@ -440,8 +453,9 @@ describe('config-changes module', function () {
                 });
             });
             it('Test 025 : should resolve wildcard config-file targets to the project, if applicable', function () {
-                shell.cp('-rf', ios_config_xml, temp);
-                shell.cp('-rf', cbplugin, plugins_dir);
+                fs.copySync(ios_config_xml, temp);
+                install_plugin(cbplugin);
+
                 var platformJson = PlatformJson.load(plugins_dir, 'ios');
                 platformJson.addInstalledPluginToPrepareQueue('org.test.plugins.childbrowser', {});
                 var spy = spyOn(fs, 'readFileSync').and.callThrough();
@@ -451,8 +465,9 @@ describe('config-changes module', function () {
                 expect(spy).toHaveBeenCalledWith(path.join(temp, 'SampleApp', 'SampleApp-Info.plist').replace(/\\/g, '/'), 'utf8');
             });
             it('Test 026 : should move successfully installed plugins from queue to installed plugins section, and include/retain vars if applicable', function () {
-                shell.cp('-rf', android_two_project, temp);
-                shell.cp('-rf', varplugin, plugins_dir);
+                fs.copySync(android_two_project, temp);
+                install_plugin(varplugin);
+
                 var platformJson = PlatformJson.load(plugins_dir, 'android');
                 platformJson.addInstalledPluginToPrepareQueue('com.adobe.vars', {'API_KEY': 'hi'}, true);
 
@@ -467,7 +482,7 @@ describe('config-changes module', function () {
 
         describe(': uninstallation', function () {
             it('Test 027 : should call pruneXML for every config munge it completely removes from the app (every leaf that is decremented to 0)', function () {
-                shell.cp('-rf', android_two_project, temp);
+                fs.copySync(android_two_project, temp);
 
                 // Run through an "install"
                 var platformJson = PlatformJson.load(plugins_dir, 'android');
@@ -486,8 +501,9 @@ describe('config-changes module', function () {
                 expect(spy.calls.argsFor(3)[2]).toEqual('/cordova/plugins');
             });
             it('Test 028 : should generate a config munge that interpolates variables into config changes, if applicable', function () {
-                shell.cp('-rf', android_two_project, temp);
-                shell.cp('-rf', varplugin, plugins_dir);
+                fs.copySync(android_two_project, temp);
+                install_plugin(varplugin);
+
                 // Run through an "install"
                 var platformJson = PlatformJson.load(plugins_dir, 'android');
                 platformJson.addInstalledPluginToPrepareQueue('com.adobe.vars', {'API_KEY': 'canucks'});
@@ -504,9 +520,9 @@ describe('config-changes module', function () {
                 expect(munge_params[1]['API_KEY']).toEqual('canucks');
             });
             it('Test 029 : should not call pruneXML for a config munge that another plugin depends on', function () {
-                shell.cp('-rf', android_two_no_perms_project, temp);
-                shell.cp('-rf', childrenplugin, plugins_dir);
-                shell.cp('-rf', shareddepsplugin, plugins_dir);
+                fs.copySync(android_two_no_perms_project, temp);
+                install_plugin(childrenplugin);
+                install_plugin(shareddepsplugin);
 
                 // Run through and "install" two plugins (they share a permission for INTERNET)
                 var platformJson = PlatformJson.load(plugins_dir, 'android');
@@ -525,7 +541,7 @@ describe('config-changes module', function () {
                 expect(permission.attrib['android:name']).toEqual('android.permission.INTERNET');
             });
             it('Test 030 : should not call pruneXML for a config munge targeting a config file that does not exist', function () {
-                shell.cp('-rf', android_two_project, temp);
+                fs.copySync(android_two_project, temp);
                 // install a plugin
                 var platformJson = PlatformJson.load(plugins_dir, 'android');
                 platformJson.addInstalledPluginToPrepareQueue('org.test.plugins.dummyplugin', {});
@@ -541,8 +557,9 @@ describe('config-changes module', function () {
                 expect(spy).not.toHaveBeenCalledWith(path.join(temp, 'res', 'xml', 'plugins.xml'), 'utf-8');
             });
             it('Test 031 : should remove uninstalled plugins from installed plugins list', function () {
-                shell.cp('-rf', android_two_project, temp);
-                shell.cp('-rf', varplugin, plugins_dir);
+                fs.copySync(android_two_project, temp);
+                install_plugin(varplugin);
+
                 // install the var plugin
                 var platformJson = PlatformJson.load(plugins_dir, 'android');
                 platformJson.addInstalledPluginToPrepareQueue('com.adobe.vars', {'API_KEY': 'eat my shorts'});
@@ -557,8 +574,8 @@ describe('config-changes module', function () {
                 expect(platformJson.root.installed_plugins['com.adobe.vars']).not.toBeDefined();
             });
             it('Test 032 : should call pruneXMLRestore for every config munge with mode \'merge\' or \'overwrite\' it removes from the app', function () {
-                shell.cp('-rf', android_two_project, temp);
-                shell.cp('-rf', editconfigplugin, plugins_dir);
+                fs.copySync(android_two_project, temp);
+                install_plugin(editconfigplugin);
 
                 // Run through an "install"
                 var platformJson = PlatformJson.load(plugins_dir, 'android');
index 2da5ee8..98b1d98 100644 (file)
@@ -17,7 +17,7 @@
 
 var rewire = require('rewire');
 var configFile = rewire('../../src/ConfigChanges/ConfigFile');
-var fs = require('fs');
+var fs = require('fs-extra');
 var path = require('path');
 var projectDir = path.join('project_dir', 'app', 'src', 'main');
 
index 2129565..9416863 100644 (file)
@@ -18,7 +18,7 @@
 */
 
 var path = require('path');
-var fs = require('fs');
+var fs = require('fs-extra');
 var ConfigParser = require('../../src/ConfigParser/ConfigParser');
 var xml = path.join(__dirname, '../fixtures/test-config.xml');
 var xml_contents = fs.readFileSync(xml, 'utf-8');
index 5a2fdc0..ea12d03 100644 (file)
@@ -17,7 +17,7 @@
     under the License.
 */
 
-var shell = require('shelljs');
+var fs = require('fs-extra');
 var path = require('path');
 var CordovaCheck = require('../src/CordovaCheck');
 
@@ -30,13 +30,10 @@ describe('findProjectRoot method', function () {
         process.env.PWD = origPWD;
         process.chdir(cwd);
     });
-    function removeDir (someDirectory) {
-        shell.rm('-rf', someDirectory);
-    }
+
     it('Test 001 : should return false if it hits the home directory', function () {
         var somedir = path.join(home, 'somedir');
-        removeDir(somedir);
-        shell.mkdir(somedir);
+        fs.emptyDirSync(somedir);
         expect(CordovaCheck.findProjectRoot(somedir)).toEqual(false);
     });
     it('Test 002 : should return false if it cannot find a .cordova directory up the directory tree', function () {
@@ -46,28 +43,28 @@ describe('findProjectRoot method', function () {
     it('Test 003 : should return the first directory it finds with a .cordova folder in it', function () {
         var somedir = path.join(home, 'somedir');
         var anotherdir = path.join(somedir, 'anotherdir');
-        removeDir(somedir);
-        shell.mkdir('-p', anotherdir);
-        shell.mkdir('-p', path.join(somedir, 'www', 'config.xml'));
+        fs.removeSync(somedir);
+        fs.ensureDirSync(anotherdir);
+        fs.ensureFileSync(path.join(somedir, 'www', 'config.xml'));
         expect(CordovaCheck.findProjectRoot(somedir)).toEqual(somedir);
     });
     it('Test 004 : should ignore PWD when its undefined', function () {
         delete process.env.PWD;
         var somedir = path.join(home, 'somedir');
         var anotherdir = path.join(somedir, 'anotherdir');
-        removeDir(somedir);
-        shell.mkdir('-p', anotherdir);
-        shell.mkdir('-p', path.join(somedir, 'www'));
-        shell.mkdir('-p', path.join(somedir, 'config.xml'));
+        fs.removeSync(somedir);
+        fs.ensureDirSync(anotherdir);
+        fs.ensureDirSync(path.join(somedir, 'www'));
+        fs.ensureFileSync(path.join(somedir, 'config.xml'));
         process.chdir(anotherdir);
         expect(CordovaCheck.findProjectRoot()).toEqual(somedir);
     });
     it('Test 005 : should use PWD when available', function () {
         var somedir = path.join(home, 'somedir');
         var anotherdir = path.join(somedir, 'anotherdir');
-        removeDir(somedir);
-        shell.mkdir('-p', anotherdir);
-        shell.mkdir('-p', path.join(somedir, 'www', 'config.xml'));
+        fs.removeSync(somedir);
+        fs.ensureDirSync(anotherdir);
+        fs.ensureFileSync(path.join(somedir, 'www', 'config.xml'));
         process.env.PWD = anotherdir;
         process.chdir(path.sep);
         expect(CordovaCheck.findProjectRoot()).toEqual(somedir);
@@ -75,9 +72,9 @@ describe('findProjectRoot method', function () {
     it('Test 006 : should use cwd as a fallback when PWD is not a cordova dir', function () {
         var somedir = path.join(home, 'somedir');
         var anotherdir = path.join(somedir, 'anotherdir');
-        removeDir(somedir);
-        shell.mkdir('-p', anotherdir);
-        shell.mkdir('-p', path.join(somedir, 'www', 'config.xml'));
+        fs.removeSync(somedir);
+        fs.ensureDirSync(anotherdir);
+        fs.ensureFileSync(path.join(somedir, 'www', 'config.xml'));
         process.env.PWD = path.sep;
         process.chdir(anotherdir);
         expect(CordovaCheck.findProjectRoot()).toEqual(somedir);
@@ -85,11 +82,10 @@ describe('findProjectRoot method', function () {
     it('Test 007 : should ignore platform www/config.xml', function () {
         var somedir = path.join(home, 'somedir');
         var anotherdir = path.join(somedir, 'anotherdir');
-        removeDir(somedir);
-        shell.mkdir('-p', anotherdir);
-        shell.mkdir('-p', path.join(anotherdir, 'www', 'config.xml'));
-        shell.mkdir('-p', path.join(somedir, 'www'));
-        shell.mkdir('-p', path.join(somedir, 'config.xml'));
+        fs.removeSync(somedir);
+        fs.ensureFileSync(path.join(anotherdir, 'www', 'config.xml'));
+        fs.ensureDirSync(path.join(somedir, 'www'));
+        fs.ensureFileSync(path.join(somedir, 'config.xml'));
         expect(CordovaCheck.findProjectRoot(anotherdir)).toEqual(somedir);
     });
 });
index 8370b97..1f00f02 100644 (file)
@@ -53,7 +53,7 @@ function mockDirStats () {
     };
 }
 
-// Create a mock to replace the fs and shelljs modules used by the FileUpdater,
+// Create a mock to replace the fs-extra module used by the FileUpdater,
 // so the tests don't have to actually touch the filesystem.
 var mockFs = {
     mkdirPaths: [],
@@ -86,20 +86,19 @@ var mockFs = {
         return result;
     },
 
-    mkdir: function (flags, path) {
+    ensureDirSync: function (path) {
         this.mkdirPaths.push(path);
     },
 
-    cp: function (flags, sourcePath, targetPath) {
+    copySync: function (sourcePath, targetPath) {
         this.cpPaths.push([sourcePath, targetPath]);
     },
 
-    rm: function (flags, path) {
+    removeSync: function (path) {
         this.rmPaths.push(path);
     }
 };
 FileUpdater.__set__('fs', mockFs);
-FileUpdater.__set__('shell', mockFs);
 
 // Define some constants used in the test cases.
 var testRootDir = 'testRootDir';
index fbf7746..97d04ff 100644 (file)
@@ -117,6 +117,22 @@ describe('PlatformJson class', function () {
                 expect(meta).toMatch(JSON.stringify(platformJson.root.plugin_metadata, null, 2));\r
             });\r
         });\r
+\r
+        describe('generateAndSaveMetadata method', function () {\r
+            it('should save generated metadata', function () {\r
+                // Needs to use graceful-fs, since that is used by fs-extra\r
+                const spy = spyOn(require('graceful-fs'), 'writeFileSync');\r
+\r
+                const dest = require('path').join(__dirname, 'test-destination');\r
+                platformJson.addPluginMetadata(fakePlugin).generateAndSaveMetadata(dest);\r
+\r
+                expect(spy).toHaveBeenCalledTimes(1);\r
+                const [file, data] = spy.calls.argsFor(0);\r
+                expect(file).toBe(dest);\r
+                expect(data.indexOf(JSON.stringify(platformJson.root.modules, null, 2))).toBeGreaterThan(0);\r
+                expect(data).toMatch(JSON.stringify(platformJson.root.plugin_metadata, null, 2));\r
+            });\r
+        });\r
     });\r
 });\r
 \r
index 1cea782..adefa8c 100644 (file)
@@ -21,9 +21,8 @@
 // require('promise-matchers');\r
 \r
 var Q = require('q');\r
-var fs = require('fs');\r
+var fs = require('fs-extra');\r
 var path = require('path');\r
-var shell = require('shelljs');\r
 var rewire = require('rewire');\r
 var PluginManager = rewire('../src/PluginManager');\r
 var PluginInfo = require('../src/PluginInfo/PluginInfo');\r
@@ -41,8 +40,9 @@ describe('PluginManager class', function () {
 \r
     beforeEach(function () {\r
         spyOn(ConfigChanges, 'PlatformMunger');\r
+        spyOn(fs, 'outputJsonSync');\r
         spyOn(fs, 'writeFileSync');\r
-        spyOn(shell, 'mkdir');\r
+        spyOn(fs, 'ensureDirSync');\r
     });\r
 \r
     it('Test 001 : should be constructable', function () {\r
index 54353ef..0b2a23b 100644 (file)
@@ -16,7 +16,7 @@
 
 /* eslint no-control-regex: 0 */
 
-var fs = require('fs');
+var fs = require('fs-extra');
 var path = require('path');
 
 var modules = {};
index a393755..910b2db 100644 (file)
@@ -20,7 +20,7 @@
 var et = require('elementtree');
 var xml = require('../util/xml-helpers');
 var CordovaError = require('../CordovaError/CordovaError');
-var fs = require('fs');
+var fs = require('fs-extra');
 var events = require('../events');
 
 /** Wraps a config.xml file */
index 28f629d..5b20ade 100644 (file)
@@ -17,7 +17,7 @@
     under the License.
 */
 
-var fs = require('fs');
+var fs = require('fs-extra');
 var path = require('path');
 
 function isRootDir (dir) {
index ea5d9e2..accf63f 100644 (file)
@@ -19,9 +19,8 @@
 
 'use strict';
 
-var fs = require('fs');
+var fs = require('fs-extra');
 var path = require('path');
-var shell = require('shelljs');
 var minimatch = require('minimatch');
 
 /**
@@ -66,31 +65,24 @@ function updatePathWithStats (sourcePath, sourceStats, targetPath, targetStats,
     if (sourceStats) {
         var sourceFullPath = path.join(rootDir || '', sourcePath);
 
-        if (targetStats) {
+        if (targetStats && (targetStats.isDirectory() !== sourceStats.isDirectory())) {
             // The target exists. But if the directory status doesn't match the source, delete it.
-            if (targetStats.isDirectory() && !sourceStats.isDirectory()) {
-                log('rmdir  ' + targetPath + ' (source is a file)');
-                shell.rm('-rf', targetFullPath);
-                targetStats = null;
-                updated = true;
-            } else if (!targetStats.isDirectory() && sourceStats.isDirectory()) {
-                log('delete ' + targetPath + ' (source is a directory)');
-                shell.rm('-f', targetFullPath);
-                targetStats = null;
-                updated = true;
-            }
+            log('delete ' + targetPath);
+            fs.removeSync(targetFullPath);
+            targetStats = null;
+            updated = true;
         }
 
         if (!targetStats) {
             if (sourceStats.isDirectory()) {
                 // The target directory does not exist, so it should be created.
                 log('mkdir ' + targetPath);
-                shell.mkdir('-p', targetFullPath);
+                fs.ensureDirSync(targetFullPath);
                 updated = true;
             } else if (sourceStats.isFile()) {
                 // The target file does not exist, so it should be copied from the source.
                 log('copy  ' + sourcePath + ' ' + targetPath + (copyAll ? '' : ' (new file)'));
-                shell.cp('-f', sourceFullPath, targetFullPath);
+                fs.copySync(sourceFullPath, targetFullPath);
                 updated = true;
             }
         } else if (sourceStats.isFile() && targetStats.isFile()) {
@@ -98,7 +90,7 @@ function updatePathWithStats (sourcePath, sourceStats, targetPath, targetStats,
             if (copyAll) {
                 // The caller specified all files should be copied.
                 log('copy  ' + sourcePath + ' ' + targetPath);
-                shell.cp('-f', sourceFullPath, targetFullPath);
+                fs.copySync(sourceFullPath, targetFullPath);
                 updated = true;
             } else {
                 // Copy if the source has been modified since it was copied to the target, or if
@@ -108,20 +100,15 @@ function updatePathWithStats (sourcePath, sourceStats, targetPath, targetStats,
                 if (sourceStats.mtime.getTime() >= targetStats.mtime.getTime() ||
                         sourceStats.size !== targetStats.size) {
                     log('copy  ' + sourcePath + ' ' + targetPath + ' (updated file)');
-                    shell.cp('-f', sourceFullPath, targetFullPath);
+                    fs.copySync(sourceFullPath, targetFullPath);
                     updated = true;
                 }
             }
         }
     } else if (targetStats) {
         // The target exists but the source is null, so the target should be deleted.
-        if (targetStats.isDirectory()) {
-            log('rmdir  ' + targetPath + (copyAll ? '' : ' (no source)'));
-            shell.rm('-rf', targetFullPath);
-        } else {
-            log('delete ' + targetPath + (copyAll ? '' : ' (no source)'));
-            shell.rm('-f', targetFullPath);
-        }
+        log('delete ' + targetPath + (copyAll ? '' : ' (no source)'));
+        fs.removeSync(targetFullPath);
         updated = true;
     }
 
@@ -150,7 +137,7 @@ function updatePathInternal (sourcePath, targetPath, options, log) {
         // Create the target's parent directory if it doesn't exist.
         var parentDir = path.dirname(targetFullPath);
         if (!fs.existsSync(parentDir)) {
-            shell.mkdir('-p', parentDir);
+            fs.ensureDirSync(parentDir);
         }
     }
 
index 86dace3..9cfb185 100644 (file)
@@ -14,9 +14,8 @@
  *
 */
 
-var fs = require('fs');
+var fs = require('fs-extra');
 var path = require('path');
-var shelljs = require('shelljs');
 var mungeutil = require('./ConfigChanges/munge-util');
 var pluginMappernto = require('cordova-registry-mapper').newToOld;
 var pluginMapperotn = require('cordova-registry-mapper').oldToNew;
@@ -37,8 +36,7 @@ PlatformJson.load = function (plugins_dir, platform) {
 };
 
 PlatformJson.prototype.save = function () {
-    shelljs.mkdir('-p', path.dirname(this.filePath));
-    fs.writeFileSync(this.filePath, JSON.stringify(this.root, null, 2), 'utf-8');
+    fs.outputJsonSync(this.filePath, this.root, {spaces: 2});
 };
 
 /**
@@ -211,9 +209,7 @@ PlatformJson.prototype.generateMetadata = function () {
  * @return {PlatformJson} PlatformJson instance
  */
 PlatformJson.prototype.generateAndSaveMetadata = function (destination) {
-    var meta = this.generateMetadata();
-    shelljs.mkdir('-p', path.dirname(destination));
-    fs.writeFileSync(destination, meta, 'utf-8');
+    fs.outputFileSync(destination, this.generateMetadata());
 
     return this;
 };
index 7e9754d..428df9d 100644 (file)
@@ -26,7 +26,7 @@ TODO (kamrik): refactor this to not use sync functions and return promises.
 */
 
 var path = require('path');
-var fs = require('fs');
+var fs = require('fs-extra');
 var xml_helpers = require('../util/xml-helpers');
 var CordovaError = require('../CordovaError/CordovaError');
 
index 5d3f329..403167d 100644 (file)
@@ -19,7 +19,7 @@
 
 /* jshint sub:true, laxcomma:true, laxbreak:true */
 
-var fs = require('fs');
+var fs = require('fs-extra');
 var path = require('path');
 var PluginInfo = require('./PluginInfo');
 var events = require('../events');
index b875d0e..5a018de 100644 (file)
@@ -18,7 +18,7 @@
 */\r
 \r
 var Q = require('q');\r
-var fs = require('fs');\r
+var fs = require('fs-extra');\r
 var path = require('path');\r
 \r
 var ActionStack = require('./ActionStack');\r
index 99e3057..eae552c 100644 (file)
 */
 
 var child_process = require('child_process');
-var fs = require('fs');
+var fs = require('fs-extra');
 var path = require('path');
 var _ = require('underscore');
 var Q = require('q');
-var shell = require('shelljs');
+var which = require('which');
 var events = require('./events');
 var iswin32 = process.platform === 'win32';
 
@@ -35,7 +35,7 @@ function resolveWindowsExe (cmd) {
     if (isValidExe(cmd)) {
         return cmd;
     }
-    cmd = String(shell.which(cmd) || cmd);
+    cmd = which.sync(cmd, { nothrow: true }) || cmd;
     if (!isValidExe(cmd)) {
         winExtensions.some(function (ext) {
             if (fs.existsSync(cmd + ext)) {
index ca65bfa..b8a03e9 100644 (file)
@@ -21,7 +21,7 @@
  * contains XML utility functions, some of which are specific to elementtree
  */
 
-var fs = require('fs');
+var fs = require('fs-extra');
 var path = require('path');
 var _ = require('underscore');
 var et = require('elementtree');