diff --git a/bin/android_sdk_version b/bin/android_sdk_version index 99e2baf8..764a19f4 100755 --- a/bin/android_sdk_version +++ b/bin/android_sdk_version @@ -21,7 +21,7 @@ var android_sdk = require('./templates/cordova/lib/android_sdk'); -android_sdk.print_newest_available_sdk_target().done(null, function (err) { +android_sdk.print_newest_available_sdk_target().catch(err => { console.error(err); process.exit(2); }); diff --git a/bin/check_reqs b/bin/check_reqs index 39b6ca59..1e349cd3 100755 --- a/bin/check_reqs +++ b/bin/check_reqs @@ -21,7 +21,7 @@ var check_reqs = require('./templates/cordova/lib/check_reqs'); -check_reqs.run().done( +check_reqs.run().then( function success () { console.log('Looks like your environment fully supports cordova-android development!'); }, diff --git a/bin/create b/bin/create index fbab2429..0ec93f62 100755 --- a/bin/create +++ b/bin/create @@ -55,4 +55,7 @@ var options = { require('./templates/cordova/loggingHelper').adjustLoggerLevel(argv); -Api.createPlatform(argv.argv.remain[0], config, options).done(); +Api.createPlatform(argv.argv.remain[0], config, options).catch(err => { + console.error(err); + process.exitCode = 1; +}); diff --git a/bin/lib/create.js b/bin/lib/create.js index 3c4b8373..71ce5f55 100755 --- a/bin/lib/create.js +++ b/bin/lib/create.js @@ -20,7 +20,6 @@ */ var shell = require('shelljs'); -var Q = require('q'); var path = require('path'); var fs = require('fs'); var check_reqs = require('./../templates/cordova/lib/check_reqs'); @@ -197,15 +196,15 @@ function validatePackageName (package_name) { var msg = 'Error validating package name. '; if (!/^[a-zA-Z][a-zA-Z0-9_]+(\.[a-zA-Z][a-zA-Z0-9_]*)+$/.test(package_name)) { - return Q.reject(new CordovaError(msg + 'Must look like: `com.company.Name`. Currently is: `' + package_name + '`')); + return Promise.reject(new CordovaError(msg + 'Must look like: `com.company.Name`. Currently is: `' + package_name + '`')); } // Class is a reserved word if (/\b[Cc]lass\b/.test(package_name)) { - return Q.reject(new CordovaError(msg + '"class" is a reserved word')); + return Promise.reject(new CordovaError(msg + '"class" is a reserved word')); } - return Q.resolve(); + return Promise.resolve(); } /** @@ -217,20 +216,20 @@ function validateProjectName (project_name) { var msg = 'Error validating project name. '; // Make sure there's something there if (project_name === '') { - return Q.reject(new CordovaError(msg + 'Project name cannot be empty')); + return Promise.reject(new CordovaError(msg + 'Project name cannot be empty')); } // Enforce stupid name error if (project_name === 'CordovaActivity') { - return Q.reject(new CordovaError(msg + 'Project name cannot be CordovaActivity')); + return Promise.reject(new CordovaError(msg + 'Project name cannot be CordovaActivity')); } // Classes in Java don't begin with numbers if (/^[0-9]/.test(project_name)) { - return Q.reject(new CordovaError(msg + 'Project name must not begin with a number')); + return Promise.reject(new CordovaError(msg + 'Project name must not begin with a number')); } - return Q.resolve(); + return Promise.resolve(); } /** @@ -259,7 +258,7 @@ exports.create = function (project_path, config, options, events) { project_path = path.relative(process.cwd(), (project_path || 'CordovaExample')); // Check if project already exists if (fs.existsSync(project_path)) { - return Q.reject(new CordovaError('Project already exists! Delete and recreate')); + return Promise.reject(new CordovaError('Project already exists! Delete and recreate')); } var package_name = config.android_packageName() || config.packageName() || 'my.cordova.project'; @@ -333,7 +332,7 @@ exports.create = function (project_path, config, options, events) { exports.writeProjectProperties(project_path, target_api); exports.prepBuildFiles(project_path); events.emit('log', generateDoneMessage('create', options.link)); - }).thenResolve(project_path); + }).then(() => project_path); }; function generateDoneMessage (type, link) { @@ -358,5 +357,5 @@ exports.update = function (projectPath, options, events) { '\tcordova platform add android\n' ; - return Q.reject(errorString); + return Promise.reject(errorString); }; diff --git a/bin/templates/cordova/Api.js b/bin/templates/cordova/Api.js index dd4a2095..83f78277 100644 --- a/bin/templates/cordova/Api.js +++ b/bin/templates/cordova/Api.js @@ -18,7 +18,6 @@ */ var path = require('path'); -var Q = require('q'); var AndroidProject = require('./lib/AndroidProject'); var PluginManager = require('cordova-common').PluginManager; @@ -206,7 +205,7 @@ Api.prototype.addPlugin = function (plugin, installOptions) { installOptions.variables.PACKAGE_NAME = project.getPackageName(); } - return Q().then(function () { + return Promise.resolve().then(function () { return PluginManager.get(self.platform, self.locations, project).addPlugin(plugin, installOptions); }).then(function () { if (plugin.getFrameworks(this.platform).length === 0) return; @@ -215,7 +214,7 @@ Api.prototype.addPlugin = function (plugin, installOptions) { require('./lib/builders/builders').getBuilder().prepBuildFiles(); }.bind(this)) // CB-11022 Return truthy value to prevent running prepare after - .thenResolve(true); + .then(() => true); }; /** @@ -247,7 +246,7 @@ Api.prototype.removePlugin = function (plugin, uninstallOptions) { require('./lib/builders/builders').getBuilder().prepBuildFiles(); }.bind(this)) // CB-11022 Return truthy value to prevent running prepare after - .thenResolve(true); + .then(() => true); }; /** diff --git a/bin/templates/cordova/lib/Adb.js b/bin/templates/cordova/lib/Adb.js index 4cebcbac..965b4f3e 100644 --- a/bin/templates/cordova/lib/Adb.js +++ b/bin/templates/cordova/lib/Adb.js @@ -17,7 +17,6 @@ under the License. */ -var Q = require('q'); var os = require('os'); var execa = require('execa'); var events = require('cordova-common').events; @@ -70,7 +69,7 @@ Adb.install = function (target, packagePath, opts) { '\nEither uninstall an app or increment the versionCode.'; } - return Q.reject(new CordovaError('Failed to install apk to device: ' + output)); + return Promise.reject(new CordovaError('Failed to install apk to device: ' + output)); } }); }; @@ -85,7 +84,7 @@ Adb.shell = function (target, shellCommand) { var args = ['-s', target, 'shell']; shellCommand = shellCommand.split(/\s+/); return execa('adb', args.concat(shellCommand), { cwd: os.tmpdir() }).catch((error) => { - return Q.reject(new CordovaError('Failed to execute shell command "' + + return Promise.reject(new CordovaError('Failed to execute shell command "' + shellCommand + '"" on device: ' + error)); }); }; @@ -93,7 +92,7 @@ Adb.shell = function (target, shellCommand) { Adb.start = function (target, activityName) { events.emit('verbose', 'Starting application "' + activityName + '" on target ' + target + '...'); return Adb.shell(target, 'am start -W -a android.intent.action.MAIN -n' + activityName).catch((error) => { - return Q.reject(new CordovaError('Failed to start application "' + + return Promise.reject(new CordovaError('Failed to start application "' + activityName + '"" on device: ' + error)); }); }; diff --git a/bin/templates/cordova/lib/build.js b/bin/templates/cordova/lib/build.js index c3399012..61234983 100644 --- a/bin/templates/cordova/lib/build.js +++ b/bin/templates/cordova/lib/build.js @@ -19,7 +19,6 @@ under the License. */ -var Q = require('q'); var path = require('path'); var fs = require('fs'); var nopt = require('nopt'); @@ -204,9 +203,19 @@ module.exports.detectArchitecture = function (target) { return /intel/i.exec(output) ? 'x86' : 'arm'; }); } + function timeout (ms, err) { + return new Promise((resolve, reject) => { + setTimeout(() => reject(err), ms); + }); + } // It sometimes happens (at least on OS X), that this command will hang forever. // To fix it, either unplug & replug device, or restart adb server. - return helper().timeout(1000, new CordovaError('Device communication timed out. Try unplugging & replugging the device.')).then(null, function (err) { + return Promise.race([ + helper(), + timeout(1000, new CordovaError( + 'Device communication timed out. Try unplugging & replugging the device.' + )) + ]).catch(err => { if (/timed out/.exec('' + err)) { // adb kill-server doesn't seem to do the trick. // Could probably find a x-platform version of killall, but I'm not actually @@ -218,13 +227,13 @@ module.exports.detectArchitecture = function (target) { events.emit('warn', 'adb timed out a second time while detecting device/emulator architecture. Killing adb and trying again.'); return execa('killall', ['adb']).then(function () { return helper().then(null, function () { - return Q.reject(new CordovaError('adb timed out a third time while detecting device/emulator architecture. Try unplugging & replugging the device.')); + return Promise.reject(new CordovaError('adb timed out a third time while detecting device/emulator architecture. Try unplugging & replugging the device.')); }); }); }); }, function () { // For non-killall OS's. - return Q.reject(err); + return Promise.reject(err); }); } throw err; diff --git a/bin/templates/cordova/lib/check_reqs.js b/bin/templates/cordova/lib/check_reqs.js index c3338e7d..e8c08042 100644 --- a/bin/templates/cordova/lib/check_reqs.js +++ b/bin/templates/cordova/lib/check_reqs.js @@ -21,7 +21,6 @@ const execa = require('execa'); var shelljs = require('shelljs'); -var Q = require('q'); var path = require('path'); var fs = require('fs'); var os = require('os'); @@ -125,26 +124,25 @@ module.exports.get_gradle_wrapper = function () { // Returns a promise. Called only by build and clean commands. module.exports.check_gradle = function () { var sdkDir = process.env['ANDROID_HOME']; - var d = Q.defer(); if (!sdkDir) { - return Q.reject(new CordovaError('Could not find gradle wrapper within Android SDK. Could not find Android SDK directory.\n' + + return Promise.reject(new CordovaError('Could not find gradle wrapper within Android SDK. Could not find Android SDK directory.\n' + 'Might need to install Android SDK or set up \'ANDROID_HOME\' env variable.')); } var gradlePath = module.exports.get_gradle_wrapper(); - if (gradlePath.length !== 0) { d.resolve(gradlePath); } else { - d.reject(new CordovaError('Could not find an installed version of Gradle either in Android Studio,\n' + - 'or on your system to install the gradle wrapper. Please include gradle \n' + - 'in your path, or install Android Studio')); - } - return d.promise; + + if (gradlePath.length !== 0) return Promise.resolve(gradlePath); + + return Promise.reject(new CordovaError('Could not find an installed version of Gradle either in Android Studio,\n' + + 'or on your system to install the gradle wrapper. Please include gradle \n' + + 'in your path, or install Android Studio')); }; // Returns a promise. module.exports.check_java = function () { var javacPath = forgivingWhichSync('javac'); var hasJavaHome = !!process.env['JAVA_HOME']; - return Q().then(function () { + return Promise.resolve().then(function () { if (hasJavaHome) { // Windows java installer doesn't add javac to PATH, nor set JAVA_HOME (ugh). if (!javacPath) { @@ -214,7 +212,7 @@ module.exports.check_java = function () { // Returns a promise. module.exports.check_android = function () { - return Q().then(function () { + return Promise.resolve().then(function () { var androidCmdPath = forgivingWhichSync('android'); var adbInPath = forgivingWhichSync('adb'); var avdmanagerInPath = forgivingWhichSync('avdmanager'); @@ -359,7 +357,7 @@ module.exports.check_android_target = function (originalError) { // Returns a promise. module.exports.run = function () { - return Q.all([this.check_java(), this.check_android()]).then(function (values) { + return Promise.all([this.check_java(), this.check_android()]).then(function (values) { console.log('Checking Java JDK and Android SDK versions'); console.log('ANDROID_SDK_ROOT=' + process.env['ANDROID_SDK_ROOT'] + ' (recommended setting)'); console.log('ANDROID_HOME=' + process.env['ANDROID_HOME'] + ' (DEPRECATED)'); @@ -426,7 +424,7 @@ module.exports.check_all = function () { }, function (err) { requirement.metadata.reason = err instanceof Error ? err.message : err; }); - }, Q()).then(function () { + }, Promise.resolve()).then(function () { // When chain is completed, return requirements array to upstream API return requirements; }); diff --git a/bin/templates/cordova/lib/prepare.js b/bin/templates/cordova/lib/prepare.js index b3a52a04..e50278cd 100644 --- a/bin/templates/cordova/lib/prepare.js +++ b/bin/templates/cordova/lib/prepare.js @@ -17,7 +17,6 @@ under the License. */ -var Q = require('q'); var fs = require('fs'); var path = require('path'); var shell = require('shelljs'); @@ -56,7 +55,7 @@ module.exports.prepare = function (cordovaProject, options) { gradlePropertiesParser.configure(gradlePropertiesUserConfig); // Update own www dir with project's www assets and plugins' assets and js-files - return Q.when(updateWww(cordovaProject, this.locations)).then(function () { + return Promise.resolve(updateWww(cordovaProject, this.locations)).then(function () { // update project according to config.xml changes. return updateProjectAccordingTo(self._config, self.locations); }).then(function () { @@ -76,13 +75,13 @@ module.exports.clean = function (options) { var projectRoot = path.resolve(this.root, '../..'); if ((options && options.noPrepare) || !fs.existsSync(this.locations.configXml) || !fs.existsSync(this.locations.configXml)) { - return Q(); + return Promise.resolve(); } var projectConfig = new ConfigParser(this.locations.configXml); var self = this; - return Q().then(function () { + return Promise.resolve().then(function () { cleanWww(projectRoot, self.locations); cleanIcons(projectRoot, projectConfig, path.relative(projectRoot, self.locations.res)); cleanSplashes(projectRoot, projectConfig, path.relative(projectRoot, self.locations.res)); diff --git a/bin/templates/cordova/lib/run.js b/bin/templates/cordova/lib/run.js index f1c70f22..774dddd5 100644 --- a/bin/templates/cordova/lib/run.js +++ b/bin/templates/cordova/lib/run.js @@ -22,9 +22,8 @@ var path = require('path'); var emulator = require('./emulator'); var device = require('./device'); -var Q = require('q'); var PackageType = require('./PackageType'); -var events = require('cordova-common').events; +const { CordovaError, events } = require('cordova-common'); function getInstallTarget (runOptions) { var install_target; @@ -55,7 +54,7 @@ module.exports.run = function (runOptions) { var self = this; var install_target = getInstallTarget(runOptions); - return Q().then(function () { + return Promise.resolve().then(function () { if (!install_target) { // no target given, deploy to device if available, otherwise use the emulator. return device.list().then(function (device_list) { @@ -97,7 +96,7 @@ module.exports.run = function (runOptions) { }); } } - return Q.reject('Target \'' + install_target + '\' not found, unable to run project'); + return Promise.reject(new CordovaError(`Target '${install_target}' not found, unable to run project`)); }); }); }); diff --git a/bin/templates/cordova/log b/bin/templates/cordova/log index 6829f28d..216c8d76 100755 --- a/bin/templates/cordova/log +++ b/bin/templates/cordova/log @@ -27,7 +27,7 @@ var args = process.argv; if (args.length > 2) { log.help(); } else { - reqs.run().done(function () { + reqs.run().then(function () { return log.run(); }, function (err) { console.error('ERROR: ' + err); diff --git a/bin/update b/bin/update index 419d34e4..86490d50 100755 --- a/bin/update +++ b/bin/update @@ -34,4 +34,7 @@ if (args.help || args.argv.remain.length === 0) { require('./templates/cordova/loggingHelper').adjustLoggerLevel(args); -Api.updatePlatform(args.argv.remain[0], { link: (args.link || args.shared) }).done(); +Api.updatePlatform(args.argv.remain[0], { link: (args.link || args.shared) }).catch(err => { + console.error(err); + process.exitCode = 1; +}); diff --git a/package.json b/package.json index 54feca9e..e43bff3d 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "execa": "^3.2.0", "nopt": "^4.0.1", "properties-parser": "^0.3.1", - "q": "^1.5.1", "shelljs": "^0.5.3" }, "devDependencies": { diff --git a/spec/unit/Api.spec.js b/spec/unit/Api.spec.js index eb82ea25..b7242ce9 100644 --- a/spec/unit/Api.spec.js +++ b/spec/unit/Api.spec.js @@ -17,7 +17,6 @@ under the License. */ -var Q = require('q'); var os = require('os'); var path = require('path'); var common = require('cordova-common'); @@ -38,13 +37,13 @@ describe('addPlugin method', function () { Api = rewire('../../bin/templates/cordova/Api'); var pluginManager = jasmine.createSpyObj('pluginManager', ['addPlugin']); - pluginManager.addPlugin.and.returnValue(Q()); + pluginManager.addPlugin.and.resolveTo(); spyOn(common.PluginManager, 'get').and.returnValue(pluginManager); var projectSpy = jasmine.createSpyObj('AndroidProject', ['getPackageName', 'write', 'isClean']); spyOn(AndroidProject, 'getProjectFile').and.returnValue(projectSpy); - Api.__set__('Api.prototype.clean', Q); + Api.__set__('Api.prototype.clean', async () => {}); // Prevent logging to avoid polluting the test reports Api.__set__('selfEvents.emit', jasmine.createSpy()); diff --git a/spec/unit/builders/ProjectBuilder.spec.js b/spec/unit/builders/ProjectBuilder.spec.js index bc1960ba..bf88025d 100644 --- a/spec/unit/builders/ProjectBuilder.spec.js +++ b/spec/unit/builders/ProjectBuilder.spec.js @@ -201,7 +201,7 @@ describe('ProjectBuilder', () => { const testError = 'failed to find target with hash string'; ProjectBuilder.__set__('check_reqs', checkReqsSpy); - checkReqsSpy.check_android_target.and.returnValue(Promise.resolve()); + checkReqsSpy.check_android_target.and.resolveTo(); execaSpy.and.rejectWith(testError); return builder.build({}).then( diff --git a/spec/unit/check_reqs.spec.js b/spec/unit/check_reqs.spec.js index bfbf88ae..885e19b5 100644 --- a/spec/unit/check_reqs.spec.js +++ b/spec/unit/check_reqs.spec.js @@ -22,7 +22,6 @@ var android_sdk = require('../../bin/templates/cordova/lib/android_sdk'); var shelljs = require('shelljs'); var fs = require('fs'); var path = require('path'); -var Q = require('q'); describe('check_reqs', function () { var original_env; @@ -51,7 +50,7 @@ describe('check_reqs', function () { process.env.ProgramFiles = 'windows-program-files'; return check_reqs.check_android().then(function () { expect(process.env.ANDROID_HOME).toContain('windows-local-app-data'); - }).fin(function () { + }).finally(function () { delete process.env.LOCALAPPDATA; delete process.env.ProgramFiles; }); @@ -62,7 +61,7 @@ describe('check_reqs', function () { process.env.HOME = 'home is where the heart is'; return check_reqs.check_android().then(function () { expect(process.env.ANDROID_HOME).toContain('home is where the heart is'); - }).fin(function () { + }).finally(function () { delete process.env.HOME; }); }); @@ -186,10 +185,8 @@ describe('check_reqs', function () { }); describe('check_android_target', function () { it('should should return full list of supported targets if there is a match to ideal api level', () => { - var deferred = Q.defer(); - spyOn(android_sdk, 'list_targets').and.returnValue(deferred.promise); var fake_targets = ['you are my fire', 'my one desire']; - deferred.resolve(fake_targets); + spyOn(android_sdk, 'list_targets').and.resolveTo(fake_targets); spyOn(check_reqs, 'get_target').and.returnValue('you are my fire'); return check_reqs.check_android_target().then(function (targets) { expect(targets).toBeDefined(); @@ -197,10 +194,8 @@ describe('check_reqs', function () { }); }); it('should error out if there is no match between ideal api level and installed targets', () => { - var deferred = Q.defer(); - spyOn(android_sdk, 'list_targets').and.returnValue(deferred.promise); var fake_targets = ['you are my fire', 'my one desire']; - deferred.resolve(fake_targets); + spyOn(android_sdk, 'list_targets').and.resolveTo(fake_targets); spyOn(check_reqs, 'get_target').and.returnValue('and i knowwwwwwwwwwww'); return check_reqs.check_android_target().then(() => { fail('Expected promise to be rejected'); diff --git a/spec/unit/create.spec.js b/spec/unit/create.spec.js index 0fc2c873..58978823 100644 --- a/spec/unit/create.spec.js +++ b/spec/unit/create.spec.js @@ -22,7 +22,6 @@ var create = rewire('../../bin/lib/create'); var check_reqs = require('../../bin/templates/cordova/lib/check_reqs'); var fs = require('fs'); var path = require('path'); -var Q = require('q'); var shell = require('shelljs'); describe('create', function () { @@ -129,8 +128,8 @@ describe('create', function () { Manifest_mock.prototype.setPackageId.and.returnValue(new Manifest_mock()); Manifest_mock.prototype.getActivity.and.returnValue(new Manifest_mock()); Manifest_mock.prototype.setName.and.returnValue(new Manifest_mock()); - spyOn(create, 'validatePackageName').and.returnValue(Q()); - spyOn(create, 'validateProjectName').and.returnValue(Q()); + spyOn(create, 'validatePackageName').and.resolveTo(); + spyOn(create, 'validateProjectName').and.resolveTo(); spyOn(create, 'setShellFatal').and.callFake(function (noop, cb) { cb(); }); spyOn(create, 'copyJsAndLibrary'); spyOn(create, 'copyScripts'); diff --git a/spec/unit/run.spec.js b/spec/unit/run.spec.js index 76081eba..2f8f8b22 100644 --- a/spec/unit/run.spec.js +++ b/spec/unit/run.spec.js @@ -171,7 +171,7 @@ describe('run', () => { return run.run().then( () => fail('Expected error to be thrown'), - err => expect(err).toContain(target) + err => expect(err.message).toContain(target) ); }); diff --git a/test/run_java_unit_tests.js b/test/run_java_unit_tests.js index 6aa72197..7e8b9b14 100644 --- a/test/run_java_unit_tests.js +++ b/test/run_java_unit_tests.js @@ -19,12 +19,11 @@ under the License. */ -var Q = require('q'); var path = require('path'); var execa = require('execa'); var ProjectBuilder = require('../bin/templates/cordova/lib/builders/ProjectBuilder'); -Q.resolve() +Promise.resolve() .then(_ => console.log('Preparing Gradle wrapper for Java unit tests.')) .then(_ => new ProjectBuilder(__dirname).runGradleWrapper('gradle')) .then(_ => gradlew('--version'))