diff --git a/lib/Api.js b/lib/Api.js index 4f1646955..4a99fe8f0 100644 --- a/lib/Api.js +++ b/lib/Api.js @@ -277,6 +277,12 @@ class Api { }); } + listTargets (options) { + return require('./check_reqs').check_android().then(() => { + return require('./run').runListDevices.call(this, options); + }); + } + /** * Cleans out the build artifacts from platform's directory, and also * cleans out the platform www directory if called without options specified. diff --git a/lib/run.js b/lib/run.js index d3bbaee6d..ef9e71fdc 100644 --- a/lib/run.js +++ b/lib/run.js @@ -83,3 +83,49 @@ module.exports.run = async function (runOptions = {}) { return target.install(resolvedTarget, { manifest, buildResults, cordovaGradleConfigParser }); }; + +module.exports.listDevices = async function () { + events.emit('log', `\nAvailable ${this.platform} devices:`); + + const { list } = require('./target'); + + await list().then(targets => { + const deviceIds = targets + .filter(({ type }) => type === 'device') + .map(({ id }) => id); + + console.log(deviceIds.join('\n')); + }, function (err) { + console.error('ERROR: ' + err); + process.exit(2); + }); +}; + +module.exports.listEmulators = async function () { + events.emit('log', `\nAvailable ${this.platform} virtual devices:`); + const emulators = require('./emulator'); + + await emulators.list_images().then(function (emulator_list) { + emulator_list && emulator_list.forEach(function (emu) { + console.log(emu.name); + }); + }, function (err) { + console.error('ERROR: ' + err); + process.exit(2); + }); +}; + +module.exports.runListDevices = async function (options = {}) { + const { options: cliArgs = {} } = options; + + if (cliArgs?.device) { + await module.exports.listDevices.call(this); + } else if (cliArgs?.emulator) { + await module.exports.listEmulators.call(this); + } else { + await module.exports.listDevices.call(this); + await module.exports.listEmulators.call(this); + } + + return true; +}; diff --git a/spec/unit/Api.spec.js b/spec/unit/Api.spec.js index e0d4546e8..ca3754f5d 100644 --- a/spec/unit/Api.spec.js +++ b/spec/unit/Api.spec.js @@ -24,6 +24,8 @@ const EventEmitter = require('events'); const Api = require('../../lib/Api'); const AndroidProject = require('../../lib/AndroidProject'); +const check_reqs = require('../../lib/check_reqs'); +const run_mod = require('../../lib/run'); const PluginInfo = common.PluginInfo; @@ -60,4 +62,19 @@ describe('Api', () => { }); }); }); + + describe('listTargets', () => { + let api; + + beforeEach(() => { + api = new Api('android', FAKE_PROJECT_DIR, new EventEmitter()); + spyOn(check_reqs, 'run').and.returnValue(Promise.resolve()); + }); + it('should call into lib/run module', () => { + spyOn(run_mod, 'runListDevices'); + return api.listTargets().then(() => { + expect(run_mod.runListDevices).toHaveBeenCalled(); + }); + }); + }); }); diff --git a/spec/unit/run.spec.js b/spec/unit/run.spec.js index 93d76b2e2..701775fb2 100644 --- a/spec/unit/run.spec.js +++ b/spec/unit/run.spec.js @@ -106,4 +106,32 @@ describe('run', () => { .toBeRejectedWithError(/Package type "bundle" is not supported/); }); }); + + describe('--list option', () => { + beforeEach(() => { + spyOn(run, 'listDevices').and.returnValue(Promise.resolve()); + spyOn(run, 'listEmulators').and.returnValue(Promise.resolve()); + }); + + it('should delegate to "listDevices" when the "runListDevices" method options param contains "options.device".', () => { + return run.runListDevices({ options: { device: true } }).then(() => { + expect(run.listDevices).toHaveBeenCalled(); + expect(run.listEmulators).not.toHaveBeenCalled(); + }); + }); + + it('should delegate to "listDevices" when the "runListDevices" method options param contains "options.emulator".', () => { + return run.runListDevices({ options: { emulator: true } }).then(() => { + expect(run.listDevices).not.toHaveBeenCalled(); + expect(run.listEmulators).toHaveBeenCalled(); + }); + }); + + it('should delegate to both "listEmulators" and "listDevices" when the "runListDevices" method does not contain "options.device" or "options.emulator".', () => { + return run.runListDevices({ options: {} }).then(() => { + expect(run.listDevices).toHaveBeenCalled(); + expect(run.listEmulators).toHaveBeenCalled(); + }); + }); + }); });