refactor: add plugin subcommand to parser by making driver subcommand generic
MODIFY
lib/cli/args.js
lib/cli/args.js
@@ -2,6 +2,11 @@ import { DEFAULT_BASE_PATH } from 'appium-base-driver';
import { parseSecurityFeatures, parseDefaultCaps, parseInstallTypes } from './parser-helpers';
import { INSTALL_TYPES, DEFAULT_APPIUM_HOME } from '../driver-config';
+const DRIVER_EXAMPLE = 'xcuitest';
+const PLUGIN_EXAMPLE = 'find_by_image';
+const DRIVER_TYPE = 'driver';
+const PLUGIN_TYPE = 'plugin';
+
// sharedArgs will be added to every subcommand
const sharedArgs = [
[['-ah', '--home', '--appium-home'], {
@@ -318,7 +323,8 @@ const serverArgs = [
}],
];
-const globalDriverArgs = [
+// this set of args works for both drivers and plugins ('extensions')
+const globalExtensionArgs = [
[['--json'], {
required: false,
defaultValue: false,
@@ -329,13 +335,16 @@ const globalDriverArgs = [
}]
];
-const driverListArgs = [
- ...globalDriverArgs,
+const extensionArgs = {[DRIVER_TYPE]: {}, [PLUGIN_TYPE]: {}};
+
+function makeListArgs (type) {
+ return [
+ ...globalExtensionArgs,
[['--installed'], {
required: false,
defaultValue: false,
action: 'storeTrue',
- help: 'List only installed drivers',
+ help: `List only installed ${type}s`,
nargs: 0,
dest: 'showInstalled'
}],
@@ -348,39 +357,46 @@ const driverListArgs = [
dest: 'showUpdates'
}]
];
+}
-const driverInstallArgs = [
- ...globalDriverArgs,
- [['driver'], {
+
+function makeInstallArgs (type) {
+ return [
+ ...globalExtensionArgs,
+ [[type], {
type: 'string',
- example: 'xcuitest',
- help: 'Name of the driver to install',
+ example: type === DRIVER_TYPE ? DRIVER_EXAMPLE : PLUGIN_EXAMPLE,
+ help: `Name of the ${type} to install`,
}],
[['--source'], {
required: false,
defaultValue: null,
type: parseInstallTypes,
- help: `Where to look for the driver if it is not one of Appium's verified ` +
- `drivers. Possible values: ${JSON.stringify(INSTALL_TYPES)}`,
+ help: `Where to look for the ${type} if it is not one of Appium's verified ` +
+ `${type}s. Possible values: ${JSON.stringify(INSTALL_TYPES)}`,
dest: 'installType'
}],
];
+}
-const driverUninstallArgs = [
- ...globalDriverArgs,
- [['driver'], {
+function makeUninstallArgs (type) {
+ return [
+ ...globalExtensionArgs,
+ [[type], {
type: 'string',
- example: 'xcuitest',
+ example: type === DRIVER_TYPE ? DRIVER_EXAMPLE : PLUGIN_EXAMPLE,
help: 'Name of the driver to uninstall',
}],
];
+}
-const driverUpdateArgs = [
- ...globalDriverArgs,
- [['driver'], {
+function makeUpdateArgs (type) {
+ return [
+ ...globalExtensionArgs,
+ [[type], {
type: 'string',
- example: 'xcuitest',
- help: 'Name of the driver to update, or the word "installed" to update all installed drivers. To see available updates, run "appium driver list --installed --updates"',
+ example: type === DRIVER_TYPE ? DRIVER_EXAMPLE : PLUGIN_EXAMPLE,
+ help: `Name of the ${type} to update, or the word "installed" to update all installed ${type}s. To see available updates, run "appium ${type} list --installed --updates"`,
}],
[['--unsafe'], {
required: false,
@@ -390,12 +406,19 @@ const driverUpdateArgs = [
help: 'Include updates that might have a new major revision, and potentially include breaking changes',
}],
];
+}
+
+for (const type of [DRIVER_TYPE, PLUGIN_TYPE]) {
+ extensionArgs[type].list = makeListArgs(type);
+ extensionArgs[type].install = makeInstallArgs(type);
+ extensionArgs[type].uninstall = makeUninstallArgs(type);
+ extensionArgs[type].update = makeUpdateArgs(type);
+}
export {
sharedArgs,
serverArgs,
- driverListArgs,
- driverInstallArgs,
- driverUninstallArgs,
- driverUpdateArgs,
+ extensionArgs,
+ DRIVER_TYPE,
+ PLUGIN_TYPE,
};

MODIFY
lib/cli/parser.js
lib/cli/parser.js
import path from 'path';
import _ from 'lodash';
import { ArgumentParser } from 'argparse';
-import { sharedArgs, serverArgs, driverListArgs, driverInstallArgs, driverUninstallArgs,
- driverUpdateArgs } from './args';
+import { sharedArgs, serverArgs, extensionArgs, DRIVER_TYPE, PLUGIN_TYPE } from './args';
import { rootDir } from '../utils';
function getParser (debug = false) {
@@ -21,8 +20,8 @@ function getParser (debug = false) {
const serverArgs = addServerToParser(sharedArgs, subParsers, debug);
parser.rawArgs = serverArgs;
- // add the 'driver' subcommand
- addDriverToParser(sharedArgs, subParsers, debug);
+ // add the 'driver' and 'plugin' subcommands
+ addExtensionsToParser(sharedArgs, subParsers, debug);
// modify the parseArgs function to insert the 'server' subcommand if the
// user hasn't specified a subcommand or the global help command
@@ -31,7 +30,7 @@ function getParser (debug = false) {
if (_.isUndefined(args)) {
args = [...process.argv.slice(2)];
}
- if (!_.includes(['driver', 'server', '-h'], args[0])) {
+ if (!_.includes([DRIVER_TYPE, PLUGIN_TYPE, 'server', '-h'], args[0])) {
args.splice(0, 0, 'server');
}
return this._parseArgs(args, namespace);
@@ -62,35 +61,37 @@ function getDefaultServerArgs () {
return defaults;
}
-function addDriverToParser (sharedArgs, subParsers, debug) {
- const driverParser = subParsers.addParser('driver', {
+function addExtensionsToParser (sharedArgs, subParsers, debug) {
+ for (const type of [DRIVER_TYPE, PLUGIN_TYPE]) {
+ const extParser = subParsers.addParser(type, {
addHelp: true,
- help: 'Access the driver management CLI commands',
+ help: `Access the ${type} management CLI commands`,
debug
});
- const driverSubParsers = driverParser.addSubparsers({
- dest: 'driverCommand',
+ const extSubParsers = extParser.addSubparsers({
+ dest: `${type}Command`,
debug
});
const parserSpecs = [
- {command: 'list', args: driverListArgs,
- help: 'List available and installed drivers'},
- {command: 'install', args: driverInstallArgs,
- help: 'Install a driver'},
- {command: 'uninstall', args: driverUninstallArgs,
- help: 'Uninstall a driver'},
- {command: 'update', args: driverUpdateArgs,
- help: 'Update installed drivers to the latest version'},
+ {command: 'list', args: extensionArgs[type].list,
+ help: `List available and installed ${type}s`},
+ {command: 'install', args: extensionArgs[type].install,
+ help: `Install a ${type}`},
+ {command: 'uninstall', args: extensionArgs[type].uninstall,
+ help: `Uninstall a ${type}`},
+ {command: 'update', args: extensionArgs[type].update,
+ help: `Update installed ${type}s to the latest version`},
];
for (const {command, args, help} of parserSpecs) {
- const parser = driverSubParsers.addParser(command, {help, debug});
+ const parser = extSubParsers.addParser(command, {help, debug});
for (const [flags, opts] of [...sharedArgs, ...args]) {
// addArgument mutates params so make sure to send in copies instead
parser.addArgument([...flags], {...opts});
}
}
}
+}
export default getParser;
export { getParser, getDefaultServerArgs };

ADD
lib/plugins.js
+// This is a map of plugin names to npm packages representing those plugins.
+// The plugins in this list will be available to the CLI so users can just
+// type 'appium plugin install 'name'', rather than having to specify the full
+// npm package. I.e., these are the officially recognized plugins.
+const KNOWN_PLUGINS = {
+};
+
+export {
+ KNOWN_PLUGINS,
+};

refactor: add plugin subcommand to parser by making driver subcommand generic