From 083c139307d571ae32e416c967d0e807a436dfaa Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Mon, 14 May 2018 23:17:05 -0700 Subject: [PATCH 1/3] Replace shelljs with fs-extra --- package.json | 5 +- spec/ConfigChanges/ConfigChanges.spec.js | 87 ++++++++++++------------ spec/ConfigChanges/ConfigFile.spec.js | 2 +- spec/ConfigParser/ConfigParser.spec.js | 2 +- spec/CordovaCheck.spec.js | 32 ++++----- spec/FileUpdater.spec.js | 9 ++- spec/PluginManager.spec.js | 5 +- src/ConfigChanges/ConfigFile.js | 2 +- src/ConfigParser/ConfigParser.js | 2 +- src/CordovaCheck.js | 2 +- src/FileUpdater.js | 33 +++------ src/PlatformJson.js | 7 +- src/PluginInfo/PluginInfo.js | 2 +- src/PluginInfo/PluginInfoProvider.js | 2 +- src/PluginManager.js | 2 +- src/superspawn.js | 6 +- src/util/xml-helpers.js | 2 +- 17 files changed, 94 insertions(+), 108 deletions(-) diff --git a/package.json b/package.json index 1d68395d..48bf7e06 100644 --- a/package.json +++ b/package.json @@ -27,13 +27,14 @@ "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", diff --git a/spec/ConfigChanges/ConfigChanges.spec.js b/spec/ConfigChanges/ConfigChanges.spec.js index a0abe5c7..44466cee 100644 --- a/spec/ConfigChanges/ConfigChanges.spec.js +++ b/spec/ConfigChanges/ConfigChanges.spec.js @@ -19,11 +19,10 @@ 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'); @@ -63,11 +62,11 @@ function get_munge_change () { 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 +130,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 +195,10 @@ describe('config-changes module', function () { describe('processing of plugins (via process method)', function () { beforeEach(function () { - shell.cp('-rf', dummyplugin, plugins_dir); + fs.copySync(dummyplugin, path.join(plugins_dir, path.basename(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 +209,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 +226,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); + fs.copySync(configplugin, path.join(plugins_dir, path.basename(configplugin))); var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.configtest', {}); @@ -247,7 +246,7 @@ 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); + fs.copySync(editconfigplugin, path.join(plugins_dir, path.basename(editconfigplugin))); var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest', {}); @@ -259,8 +258,8 @@ 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); + fs.copySync(editconfigplugin, path.join(plugins_dir, path.basename(editconfigplugin))); + fs.copySync(editconfigplugin_two, path.join(plugins_dir, path.basename(editconfigplugin_two))); var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest', {}); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest_two', {}, true, true); @@ -275,7 +274,7 @@ 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); + fs.copySync(editconfigplugin, path.join(plugins_dir, path.basename(editconfigplugin))); var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest', {}); @@ -287,8 +286,8 @@ 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); + fs.copySync(editconfigplugin, path.join(plugins_dir, path.basename(editconfigplugin))); + fs.copySync(editconfigplugin_two, path.join(plugins_dir, path.basename(editconfigplugin_two))); var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest', {}); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest_two', {}, true, true); @@ -302,8 +301,8 @@ 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); + fs.copySync(editconfigplugin, path.join(plugins_dir, path.basename(editconfigplugin))); + fs.copySync(editconfigplugin_two, path.join(plugins_dir, path.basename(editconfigplugin_two))); var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest', {}); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest_two', {}); @@ -348,7 +347,7 @@ 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); + fs.copySync(editconfigplugin_two, path.join(plugins_dir, path.basename(editconfigplugin_two))); var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest_two', {}, true, true); @@ -396,7 +395,7 @@ 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); + fs.copySync(editconfigplugin_two, path.join(plugins_dir, path.basename(editconfigplugin_two))); var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest_two', {}, true, true); @@ -408,16 +407,16 @@ 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); + fs.copySync(varplugin, path.join(plugins_dir, path.basename(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(/APluginNode<\/key>\n {4}/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); + fs.copySync(plistplugin, path.join(plugins_dir, path.basename(plistplugin))); var platformJson = PlatformJson.load(plugins_dir, 'ios'); platformJson.addInstalledPluginToPrepareQueue('org.apache.plist', {}); configChanges.process(plugins_dir, temp, 'ios', platformJson, pluginInfoProvider); @@ -428,8 +427,8 @@ 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); + fs.copySync(bplistplugin, path.join(plugins_dir, path.basename(bplistplugin))); var platformJson = PlatformJson.load(plugins_dir, 'ios'); platformJson.addInstalledPluginToPrepareQueue('org.apache.bplist', {}); configChanges.process(plugins_dir, temp, 'ios', platformJson, pluginInfoProvider); @@ -440,8 +439,8 @@ 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); + fs.copySync(cbplugin, path.join(plugins_dir, path.basename(cbplugin))); var platformJson = PlatformJson.load(plugins_dir, 'ios'); platformJson.addInstalledPluginToPrepareQueue('org.test.plugins.childbrowser', {}); var spy = spyOn(fs, 'readFileSync').and.callThrough(); @@ -451,8 +450,8 @@ 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); + fs.copySync(varplugin, path.join(plugins_dir, path.basename(varplugin))); var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('com.adobe.vars', {'API_KEY': 'hi'}, true); @@ -467,7 +466,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 +485,8 @@ 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); + fs.copySync(varplugin, path.join(plugins_dir, path.basename(varplugin))); // Run through an "install" var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('com.adobe.vars', {'API_KEY': 'canucks'}); @@ -504,9 +503,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); + fs.copySync(childrenplugin, path.join(plugins_dir, path.basename(childrenplugin))); + fs.copySync(shareddepsplugin, path.join(plugins_dir, path.basename(shareddepsplugin))); // Run through and "install" two plugins (they share a permission for INTERNET) var platformJson = PlatformJson.load(plugins_dir, 'android'); @@ -525,7 +524,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 +540,8 @@ 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); + fs.copySync(varplugin, path.join(plugins_dir, path.basename(varplugin))); // install the var plugin var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('com.adobe.vars', {'API_KEY': 'eat my shorts'}); @@ -557,8 +556,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); + fs.copySync(editconfigplugin, path.join(plugins_dir, path.basename(editconfigplugin))); // Run through an "install" var platformJson = PlatformJson.load(plugins_dir, 'android'); diff --git a/spec/ConfigChanges/ConfigFile.spec.js b/spec/ConfigChanges/ConfigFile.spec.js index 2da5ee89..98b1d986 100644 --- a/spec/ConfigChanges/ConfigFile.spec.js +++ b/spec/ConfigChanges/ConfigFile.spec.js @@ -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'); diff --git a/spec/ConfigParser/ConfigParser.spec.js b/spec/ConfigParser/ConfigParser.spec.js index 21295652..94168637 100644 --- a/spec/ConfigParser/ConfigParser.spec.js +++ b/spec/ConfigParser/ConfigParser.spec.js @@ -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'); diff --git a/spec/CordovaCheck.spec.js b/spec/CordovaCheck.spec.js index 5a2fdc08..cd84df02 100644 --- a/spec/CordovaCheck.spec.js +++ b/spec/CordovaCheck.spec.js @@ -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'); @@ -31,12 +31,12 @@ describe('findProjectRoot method', function () { process.chdir(cwd); }); function removeDir (someDirectory) { - shell.rm('-rf', someDirectory); + fs.removeSync(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.ensureDirSync(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 () { @@ -47,8 +47,8 @@ describe('findProjectRoot method', 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.ensureDirSync(anotherdir); + fs.ensureDirSync(path.join(somedir, 'www', 'config.xml')); expect(CordovaCheck.findProjectRoot(somedir)).toEqual(somedir); }); it('Test 004 : should ignore PWD when its undefined', function () { @@ -56,9 +56,9 @@ describe('findProjectRoot method', 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')); - shell.mkdir('-p', path.join(somedir, 'config.xml')); + fs.ensureDirSync(anotherdir); + fs.ensureDirSync(path.join(somedir, 'www')); + fs.ensureDirSync(path.join(somedir, 'config.xml')); process.chdir(anotherdir); expect(CordovaCheck.findProjectRoot()).toEqual(somedir); }); @@ -66,8 +66,8 @@ describe('findProjectRoot method', 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.ensureDirSync(anotherdir); + fs.ensureDirSync(path.join(somedir, 'www', 'config.xml')); process.env.PWD = anotherdir; process.chdir(path.sep); expect(CordovaCheck.findProjectRoot()).toEqual(somedir); @@ -76,8 +76,8 @@ describe('findProjectRoot method', 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.ensureDirSync(anotherdir); + fs.ensureDirSync(path.join(somedir, 'www', 'config.xml')); process.env.PWD = path.sep; process.chdir(anotherdir); expect(CordovaCheck.findProjectRoot()).toEqual(somedir); @@ -86,10 +86,10 @@ describe('findProjectRoot method', 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.ensureDirSync(anotherdir); + fs.ensureDirSync(path.join(anotherdir, 'www', 'config.xml')); + fs.ensureDirSync(path.join(somedir, 'www')); + fs.ensureDirSync(path.join(somedir, 'config.xml')); expect(CordovaCheck.findProjectRoot(anotherdir)).toEqual(somedir); }); }); diff --git a/spec/FileUpdater.spec.js b/spec/FileUpdater.spec.js index 8370b975..1f00f029 100644 --- a/spec/FileUpdater.spec.js +++ b/spec/FileUpdater.spec.js @@ -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'; diff --git a/spec/PluginManager.spec.js b/spec/PluginManager.spec.js index 1cea782e..0b08fc2b 100644 --- a/spec/PluginManager.spec.js +++ b/spec/PluginManager.spec.js @@ -21,9 +21,8 @@ // require('promise-matchers'); var Q = require('q'); -var fs = require('fs'); +var fs = require('fs-extra'); var path = require('path'); -var shell = require('shelljs'); var rewire = require('rewire'); var PluginManager = rewire('../src/PluginManager'); var PluginInfo = require('../src/PluginInfo/PluginInfo'); @@ -42,7 +41,7 @@ describe('PluginManager class', function () { beforeEach(function () { spyOn(ConfigChanges, 'PlatformMunger'); spyOn(fs, 'writeFileSync'); - spyOn(shell, 'mkdir'); + spyOn(fs, 'ensureDirSync'); }); it('Test 001 : should be constructable', function () { diff --git a/src/ConfigChanges/ConfigFile.js b/src/ConfigChanges/ConfigFile.js index 54353ef7..0b2a23b2 100644 --- a/src/ConfigChanges/ConfigFile.js +++ b/src/ConfigChanges/ConfigFile.js @@ -16,7 +16,7 @@ /* eslint no-control-regex: 0 */ -var fs = require('fs'); +var fs = require('fs-extra'); var path = require('path'); var modules = {}; diff --git a/src/ConfigParser/ConfigParser.js b/src/ConfigParser/ConfigParser.js index a3937555..910b2db4 100644 --- a/src/ConfigParser/ConfigParser.js +++ b/src/ConfigParser/ConfigParser.js @@ -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 */ diff --git a/src/CordovaCheck.js b/src/CordovaCheck.js index 28f629d3..5b20ade7 100644 --- a/src/CordovaCheck.js +++ b/src/CordovaCheck.js @@ -17,7 +17,7 @@ under the License. */ -var fs = require('fs'); +var fs = require('fs-extra'); var path = require('path'); function isRootDir (dir) { diff --git a/src/FileUpdater.js b/src/FileUpdater.js index ea5d9e26..03f8c141 100644 --- a/src/FileUpdater.js +++ b/src/FileUpdater.js @@ -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'); /** @@ -68,14 +67,9 @@ function updatePathWithStats (sourcePath, sourceStats, targetPath, targetStats, if (targetStats) { // 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); + if ((targetStats.isDirectory() && !sourceStats.isDirectory()) || (!targetStats.isDirectory() && sourceStats.isDirectory())) { + log('delete ' + targetPath); + fs.removeSync(targetFullPath); targetStats = null; updated = true; } @@ -85,12 +79,12 @@ function updatePathWithStats (sourcePath, sourceStats, targetPath, 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 +92,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 +102,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 +139,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); } } diff --git a/src/PlatformJson.js b/src/PlatformJson.js index 86dace35..5b9275f3 100644 --- a/src/PlatformJson.js +++ b/src/PlatformJson.js @@ -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,7 +36,7 @@ PlatformJson.load = function (plugins_dir, platform) { }; PlatformJson.prototype.save = function () { - shelljs.mkdir('-p', path.dirname(this.filePath)); + fs.ensureDirSync(path.dirname(this.filePath)); fs.writeFileSync(this.filePath, JSON.stringify(this.root, null, 2), 'utf-8'); }; @@ -212,7 +211,7 @@ PlatformJson.prototype.generateMetadata = function () { */ PlatformJson.prototype.generateAndSaveMetadata = function (destination) { var meta = this.generateMetadata(); - shelljs.mkdir('-p', path.dirname(destination)); + fs.ensureDirSync(path.dirname(destination)); fs.writeFileSync(destination, meta, 'utf-8'); return this; diff --git a/src/PluginInfo/PluginInfo.js b/src/PluginInfo/PluginInfo.js index 7e9754d2..428df9d3 100644 --- a/src/PluginInfo/PluginInfo.js +++ b/src/PluginInfo/PluginInfo.js @@ -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'); diff --git a/src/PluginInfo/PluginInfoProvider.js b/src/PluginInfo/PluginInfoProvider.js index 5d3f329e..403167dd 100644 --- a/src/PluginInfo/PluginInfoProvider.js +++ b/src/PluginInfo/PluginInfoProvider.js @@ -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'); diff --git a/src/PluginManager.js b/src/PluginManager.js index b875d0ef..5a018deb 100644 --- a/src/PluginManager.js +++ b/src/PluginManager.js @@ -18,7 +18,7 @@ */ var Q = require('q'); -var fs = require('fs'); +var fs = require('fs-extra'); var path = require('path'); var ActionStack = require('./ActionStack'); diff --git a/src/superspawn.js b/src/superspawn.js index 99e30577..eae552c7 100644 --- a/src/superspawn.js +++ b/src/superspawn.js @@ -18,11 +18,11 @@ */ 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)) { diff --git a/src/util/xml-helpers.js b/src/util/xml-helpers.js index ca65bfa1..b8a03e92 100644 --- a/src/util/xml-helpers.js +++ b/src/util/xml-helpers.js @@ -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'); From d74d95c259b76527130eb4ea5df9336f08336f9e Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Tue, 22 May 2018 22:38:32 -0700 Subject: [PATCH 2/3] Squash: Updates from code review --- spec/ConfigChanges/ConfigChanges.spec.js | 62 +++++++++++++++--------- spec/CordovaCheck.spec.js | 30 +++++------- spec/PluginManager.spec.js | 1 + src/FileUpdater.js | 12 ++--- src/PlatformJson.js | 6 +-- 5 files changed, 61 insertions(+), 50 deletions(-) diff --git a/spec/ConfigChanges/ConfigChanges.spec.js b/spec/ConfigChanges/ConfigChanges.spec.js index 44466cee..fe83c702 100644 --- a/spec/ConfigChanges/ConfigChanges.spec.js +++ b/spec/ConfigChanges/ConfigChanges.spec.js @@ -60,6 +60,10 @@ 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 () { fs.ensureDirSync(temp); @@ -195,7 +199,7 @@ describe('config-changes module', function () { describe('processing of plugins (via process method)', function () { beforeEach(function () { - fs.copySync(dummyplugin, path.join(plugins_dir, path.basename(dummyplugin))); + install_plugin(dummyplugin); }); it('Test 014 : should generate config munges for queued plugins', function () { fs.copySync(android_two_project, temp); @@ -226,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 () { - fs.copySync(configplugin, path.join(plugins_dir, path.basename(configplugin))); + install_plugin(configplugin); var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.configtest', {}); @@ -246,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 () { - fs.copySync(editconfigplugin, path.join(plugins_dir, path.basename(editconfigplugin))); + install_plugin(editconfigplugin); + var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest', {}); @@ -258,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 () { - fs.copySync(editconfigplugin, path.join(plugins_dir, path.basename(editconfigplugin))); - fs.copySync(editconfigplugin_two, path.join(plugins_dir, path.basename(editconfigplugin_two))); + 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); @@ -274,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 () { - fs.copySync(editconfigplugin, path.join(plugins_dir, path.basename(editconfigplugin))); + install_plugin(editconfigplugin); + var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest', {}); @@ -286,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 () { - fs.copySync(editconfigplugin, path.join(plugins_dir, path.basename(editconfigplugin))); - fs.copySync(editconfigplugin_two, path.join(plugins_dir, path.basename(editconfigplugin_two))); + 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); @@ -301,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 () { - fs.copySync(editconfigplugin, path.join(plugins_dir, path.basename(editconfigplugin))); - fs.copySync(editconfigplugin_two, path.join(plugins_dir, path.basename(editconfigplugin_two))); + 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', {}); @@ -347,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 () { - fs.copySync(editconfigplugin_two, path.join(plugins_dir, path.basename(editconfigplugin_two))); + install_plugin(editconfigplugin_two); + var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest_two', {}, true, true); @@ -395,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 () { - fs.copySync(editconfigplugin_two, path.join(plugins_dir, path.basename(editconfigplugin_two))); + install_plugin(editconfigplugin_two); + var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('org.test.editconfigtest_two', {}, true, true); @@ -408,7 +419,8 @@ describe('config-changes module', function () { describe('of plist config files', function () { it('Test 023 : should write empty string nodes with no whitespace', function () { fs.copySync(ios_config_xml, temp); - fs.copySync(varplugin, path.join(plugins_dir, path.basename(varplugin))); + install_plugin(varplugin); + var platformJson = PlatformJson.load(plugins_dir, 'ios'); platformJson.addInstalledPluginToPrepareQueue('com.adobe.vars', {}); configChanges.process(plugins_dir, temp, 'ios', platformJson, pluginInfoProvider); @@ -416,7 +428,8 @@ describe('config-changes module', function () { }); it('Test 024 : should merge dictionaries and arrays, removing duplicates', function () { fs.copySync(ios_config_xml, temp); - fs.copySync(plistplugin, path.join(plugins_dir, path.basename(plistplugin))); + install_plugin(plistplugin); + var platformJson = PlatformJson.load(plugins_dir, 'ios'); platformJson.addInstalledPluginToPrepareQueue('org.apache.plist', {}); configChanges.process(plugins_dir, temp, 'ios', platformJson, pluginInfoProvider); @@ -428,7 +441,8 @@ describe('config-changes module', function () { describe('of binary plist config files', function () { it('should merge dictionaries and arrays, removing duplicates', function () { fs.copySync(ios_config_xml, temp); - fs.copySync(bplistplugin, path.join(plugins_dir, path.basename(bplistplugin))); + install_plugin(bplistplugin); + var platformJson = PlatformJson.load(plugins_dir, 'ios'); platformJson.addInstalledPluginToPrepareQueue('org.apache.bplist', {}); configChanges.process(plugins_dir, temp, 'ios', platformJson, pluginInfoProvider); @@ -440,7 +454,8 @@ describe('config-changes module', function () { }); it('Test 025 : should resolve wildcard config-file targets to the project, if applicable', function () { fs.copySync(ios_config_xml, temp); - fs.copySync(cbplugin, path.join(plugins_dir, path.basename(cbplugin))); + install_plugin(cbplugin); + var platformJson = PlatformJson.load(plugins_dir, 'ios'); platformJson.addInstalledPluginToPrepareQueue('org.test.plugins.childbrowser', {}); var spy = spyOn(fs, 'readFileSync').and.callThrough(); @@ -451,7 +466,8 @@ describe('config-changes module', function () { }); it('Test 026 : should move successfully installed plugins from queue to installed plugins section, and include/retain vars if applicable', function () { fs.copySync(android_two_project, temp); - fs.copySync(varplugin, path.join(plugins_dir, path.basename(varplugin))); + install_plugin(varplugin); + var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('com.adobe.vars', {'API_KEY': 'hi'}, true); @@ -486,7 +502,8 @@ describe('config-changes module', function () { }); it('Test 028 : should generate a config munge that interpolates variables into config changes, if applicable', function () { fs.copySync(android_two_project, temp); - fs.copySync(varplugin, path.join(plugins_dir, path.basename(varplugin))); + install_plugin(varplugin); + // Run through an "install" var platformJson = PlatformJson.load(plugins_dir, 'android'); platformJson.addInstalledPluginToPrepareQueue('com.adobe.vars', {'API_KEY': 'canucks'}); @@ -504,8 +521,8 @@ describe('config-changes module', function () { }); it('Test 029 : should not call pruneXML for a config munge that another plugin depends on', function () { fs.copySync(android_two_no_perms_project, temp); - fs.copySync(childrenplugin, path.join(plugins_dir, path.basename(childrenplugin))); - fs.copySync(shareddepsplugin, path.join(plugins_dir, path.basename(shareddepsplugin))); + 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'); @@ -541,7 +558,8 @@ describe('config-changes module', function () { }); it('Test 031 : should remove uninstalled plugins from installed plugins list', function () { fs.copySync(android_two_project, temp); - fs.copySync(varplugin, path.join(plugins_dir, path.basename(varplugin))); + 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,7 +575,7 @@ describe('config-changes module', function () { }); it('Test 032 : should call pruneXMLRestore for every config munge with mode \'merge\' or \'overwrite\' it removes from the app', function () { fs.copySync(android_two_project, temp); - fs.copySync(editconfigplugin, path.join(plugins_dir, path.basename(editconfigplugin))); + install_plugin(editconfigplugin); // Run through an "install" var platformJson = PlatformJson.load(plugins_dir, 'android'); diff --git a/spec/CordovaCheck.spec.js b/spec/CordovaCheck.spec.js index cd84df02..ea12d035 100644 --- a/spec/CordovaCheck.spec.js +++ b/spec/CordovaCheck.spec.js @@ -30,13 +30,10 @@ describe('findProjectRoot method', function () { process.env.PWD = origPWD; process.chdir(cwd); }); - function removeDir (someDirectory) { - fs.removeSync(someDirectory); - } + it('Test 001 : should return false if it hits the home directory', function () { var somedir = path.join(home, 'somedir'); - removeDir(somedir); - fs.ensureDirSync(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); + fs.removeSync(somedir); fs.ensureDirSync(anotherdir); - fs.ensureDirSync(path.join(somedir, 'www', 'config.xml')); + 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); + fs.removeSync(somedir); fs.ensureDirSync(anotherdir); fs.ensureDirSync(path.join(somedir, 'www')); - fs.ensureDirSync(path.join(somedir, 'config.xml')); + 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); + fs.removeSync(somedir); fs.ensureDirSync(anotherdir); - fs.ensureDirSync(path.join(somedir, 'www', 'config.xml')); + 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); + fs.removeSync(somedir); fs.ensureDirSync(anotherdir); - fs.ensureDirSync(path.join(somedir, 'www', 'config.xml')); + 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); - fs.ensureDirSync(anotherdir); - fs.ensureDirSync(path.join(anotherdir, 'www', 'config.xml')); + fs.removeSync(somedir); + fs.ensureFileSync(path.join(anotherdir, 'www', 'config.xml')); fs.ensureDirSync(path.join(somedir, 'www')); - fs.ensureDirSync(path.join(somedir, 'config.xml')); + fs.ensureFileSync(path.join(somedir, 'config.xml')); expect(CordovaCheck.findProjectRoot(anotherdir)).toEqual(somedir); }); }); diff --git a/spec/PluginManager.spec.js b/spec/PluginManager.spec.js index 0b08fc2b..adefa8cd 100644 --- a/spec/PluginManager.spec.js +++ b/spec/PluginManager.spec.js @@ -40,6 +40,7 @@ describe('PluginManager class', function () { beforeEach(function () { spyOn(ConfigChanges, 'PlatformMunger'); + spyOn(fs, 'outputJsonSync'); spyOn(fs, 'writeFileSync'); spyOn(fs, 'ensureDirSync'); }); diff --git a/src/FileUpdater.js b/src/FileUpdater.js index 03f8c141..accf63fc 100644 --- a/src/FileUpdater.js +++ b/src/FileUpdater.js @@ -65,14 +65,12 @@ 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()) || (!targetStats.isDirectory() && sourceStats.isDirectory())) { - log('delete ' + targetPath); - fs.removeSync(targetFullPath); - targetStats = null; - updated = true; - } + log('delete ' + targetPath); + fs.removeSync(targetFullPath); + targetStats = null; + updated = true; } if (!targetStats) { diff --git a/src/PlatformJson.js b/src/PlatformJson.js index 5b9275f3..2e1654ee 100644 --- a/src/PlatformJson.js +++ b/src/PlatformJson.js @@ -36,8 +36,7 @@ PlatformJson.load = function (plugins_dir, platform) { }; PlatformJson.prototype.save = function () { - fs.ensureDirSync(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,8 +210,7 @@ PlatformJson.prototype.generateMetadata = function () { */ PlatformJson.prototype.generateAndSaveMetadata = function (destination) { var meta = this.generateMetadata(); - fs.ensureDirSync(path.dirname(destination)); - fs.writeFileSync(destination, meta, 'utf-8'); + fs.outputJsonSync(destination, meta); return this; }; From 6534c21248f4b144356bb45545f8cacd410fa188 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Thu, 24 May 2018 07:16:39 -0700 Subject: [PATCH 3/3] Squash: Fix generateAndSaveMetadata output --- spec/PlatformJson.spec.js | 16 ++++++++++++++++ src/PlatformJson.js | 3 +-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/spec/PlatformJson.spec.js b/spec/PlatformJson.spec.js index fbf7746f..97d04ff3 100644 --- a/spec/PlatformJson.spec.js +++ b/spec/PlatformJson.spec.js @@ -117,6 +117,22 @@ describe('PlatformJson class', function () { expect(meta).toMatch(JSON.stringify(platformJson.root.plugin_metadata, null, 2)); }); }); + + describe('generateAndSaveMetadata method', function () { + it('should save generated metadata', function () { + // Needs to use graceful-fs, since that is used by fs-extra + const spy = spyOn(require('graceful-fs'), 'writeFileSync'); + + const dest = require('path').join(__dirname, 'test-destination'); + platformJson.addPluginMetadata(fakePlugin).generateAndSaveMetadata(dest); + + expect(spy).toHaveBeenCalledTimes(1); + const [file, data] = spy.calls.argsFor(0); + expect(file).toBe(dest); + expect(data.indexOf(JSON.stringify(platformJson.root.modules, null, 2))).toBeGreaterThan(0); + expect(data).toMatch(JSON.stringify(platformJson.root.plugin_metadata, null, 2)); + }); + }); }); }); diff --git a/src/PlatformJson.js b/src/PlatformJson.js index 2e1654ee..9cfb1855 100644 --- a/src/PlatformJson.js +++ b/src/PlatformJson.js @@ -209,8 +209,7 @@ PlatformJson.prototype.generateMetadata = function () { * @return {PlatformJson} PlatformJson instance */ PlatformJson.prototype.generateAndSaveMetadata = function (destination) { - var meta = this.generateMetadata(); - fs.outputJsonSync(destination, meta); + fs.outputFileSync(destination, this.generateMetadata()); return this; };