docs(appium): create a cli args docs generation system
generate markdown tables and insert into args.md
remove 1.x args generation docs
write cli args docs file preamble
MODIFY
packages/appium/docs/en/cli/args.md
packages/appium/docs/en/cli/args.md
title: Server CLI Args
---
-TODO
+To start the Appium server, you may either run `appium` or `appium server`. The `server` subcommand
+is considered to be the default, so if you omit it, Appium will interpret this as your request to
+run the Appium server. (You could run different subcommands, like `appium driver` or `appium
+plugin`: see the [Extensions CLI](./extensions.md) for more info).
+
+The invocation of `appium` (or `appium server`) takes a number of arguments, which are detailed
+below.
+
+!!! note
+
+ All of these arguments can be set via a [Configuration File](../guides/config.md) instead if
+ you want. Any arguments set on the command line will override any arguments found in
+ a configuration file.
+
+
+<!-- WARNING: anything between the AUTOGEN-START and AUTOGEN-STOP tags will get replaced by
+automatic docs generation tooling! Do not edit by hand! -->
+<!-- AUTOGEN-START -->
+|Argument&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|Description|Type|Default|Aliases|
+|--|--|--|--|--|
+|`--address`|IP address to listen on|string|`0.0.0.0`|`-a`|
+|`--allow-cors`|Whether the Appium server should allow web browser connections from any host|boolean|`false`||
+|`--allow-insecure`|Set which insecure features are allowed to run in this server's sessions. Features are defined on a driver level; see documentation for more details. Note that features defined via "deny-insecure" will be disabled, even if also listed here. If string, a path to a text file containing policy or a comma-delimited list.|array<string>|`[]`||
+|`--base-path`|Base path to use as the prefix for all webdriver routes running on the server|string|`""`|`-pa`|
+|`--callback-address`|Callback IP address (default: same as "address")|string||`-ca`|
+|`--callback-port`|Callback port (default: same as "port") (Value must be between `1` and `65535`)|integer|`4723`|`-cp`|
+|`--debug-log-spacing`|Add exaggerated spacing in logs to help with visual inspection|boolean|`false`||
+|`--default-capabilities`|Set the default desired capabilities, which will be set on each session unless overridden by received capabilities. If a string, a path to a JSON file containing the capabilities, or raw JSON.|object||`-dc`|
+|`--deny-insecure`|Set which insecure features are not allowed to run in this server's sessions. Features are defined on a driver level; see documentation for more details. Features listed here will not be enabled even if also listed in "allow-insecure", and even if "relaxed-security" is enabled. If string, a path to a text file containing policy or a comma-delimited list.|array<string>|`[]`||
+|`--driver`|Driver-specific configuration. Keys should correspond to driver package names|object|||
+|`--keep-alive-timeout`|Number of seconds the Appium server should apply as both the keep-alive timeout and the connection timeout for all requests. A value of 0 disables the timeout.|integer|`600`|`-ka`|
+|`--local-timezone`|Use local timezone for timestamps|boolean|`false`||
+|`--log`|Also send log output to this file|string||`-g`|
+|`--log-filters`|One or more log filtering rules|array<string>|||
+|`--log-level`|Log level (console[:file]) (Value must be one of: `info`, `info:debug`, `info:info`, `info:warn`, `info:error`, `warn`, `warn:debug`, `warn:info`, `warn:warn`, `warn:error`, `error`, `error:debug`, `error:info`, `error:warn`, `error:error`, `debug`, `debug:debug`, `debug:info`, `debug:warn`, `debug:error`)|string|`debug`||
+|`--log-no-colors`|Do not use color in console output|boolean|`false`||
+|`--log-timestamp`|Show timestamps in console output|boolean|`false`||
+|`--long-stacktrace`|Add long stack traces to log entries. Recommended for debugging only.|boolean|`false`||
+|`--no-perms-check`|Do not check that needed files are readable and/or writable|boolean|`false`||
+|`--nodeconfig`|Path to configuration JSON file to register Appium as a node with Selenium Grid 3; otherwise the configuration itself|object|||
+|`--plugin`|Plugin-specific configuration. Keys should correspond to plugin package names|object|||
+|`--port`|Port to listen on (Value must be between `1` and `65535`)|integer|`4723`|`-p`|
+|`--relaxed-security`|Disable additional security checks, so it is possible to use some advanced features, provided by drivers supporting this option. Only enable it if all the clients are in the trusted network and it's not the case if a client could potentially break out of the session sandbox. Specific features can be overridden by using "deny-insecure"|boolean|`false`||
+|`--session-override`|Enables session override (clobbering)|boolean|`false`||
+|`--strict-caps`|Cause sessions to fail if desired caps are sent in that Appium does not recognize as valid for the selected device|boolean|`false`||
+|`--tmp`|Absolute path to directory Appium can use to manage temp files. Defaults to C:\Windows\Temp on Windows and /tmp otherwise.|string|||
+|`--trace-dir`|Absolute path to directory Appium can use to save iOS instrument traces; defaults to <tmp>/appium-instruments|string|||
+|`--use-drivers`|A list of drivers to activate. By default, all installed drivers will be activated.|array<string>|`[]`||
+|`--use-plugins`|A list of plugins to activate. To activate all plugins, the value should be an array with a single item "all".|array<string>|`[]`||
+|`--webhook`|Also send log output to this http listener|string||`-G`|
+<!-- AUTOGEN-STOP -->

ADD
packages/appium/docs/scripts/gen-cli-args-docs.js
+// for simplicity this file is not transpiled and is run directly via an npm script
+/* eslint-disable no-console */
+/* eslint-disable promise/prefer-await-to-callbacks */
+/* eslint-disable promise/prefer-await-to-then */
+
+const path = require('path');
+const {fs} = require('@appium/support');
+const {AppiumConfigJsonSchema} = require('@appium/schema');
+
+const DOC_PATH = path.resolve(__dirname, '..', 'en', 'cli', 'args.md');
+
+const START_TAG = `<!-- AUTOGEN-START -->`;
+const STOP_TAG = `<!-- AUTOGEN-STOP -->`;
+
+async function main() {
+ console.log(`Gathering current cli doc file contents...`);
+ const [preStart, postEnd] = await getDocParts();
+ console.log(`Generating new cli arg table...`);
+ const argTable = getCliArgTable();
+ console.log(`Writing new doc file...`);
+ await writeNewDoc(preStart, argTable, postEnd);
+ console.log(`...done!`);
+}
+
+async function getDocParts() {
+ if (!(await fs.exists(DOC_PATH))) {
+ throw new Error(`Cannot find args.md at ${DOC_PATH}`);
+ }
+
+ const curContents = await fs.readFile(DOC_PATH, 'utf-8');
+
+ // attempt to verify the start/stop tags
+ const [preStart, postStart] = curContents.split(START_TAG);
+ if (!postStart) {
+ throw new Error(`Could not find autogen start tag '${START_TAG}'. Make sure it's in place!`);
+ }
+ const [, postEnd] = postStart.split(STOP_TAG);
+ if (!postEnd) {
+ throw new Error(`Could not find autogen stop tag '${STOP_TAG}'. Make sure it's in place!`);
+ }
+
+ return [preStart, postEnd];
+}
+
+function getCliArgTable() {
+ const pad = '&nbsp;'.repeat(30);
+ const header = `|Argument${pad}|Description|Type|Default|Aliases|\n` + `|--|--|--|--|--|`;
+ const serverProps = AppiumConfigJsonSchema.properties.server.properties;
+ const args = Object.keys(serverProps).map((arg) => {
+ let {appiumCliAliases = [], description, type, items, maximum, minimum} = serverProps[arg];
+ let def = serverProps[arg].default;
+ let enums = serverProps[arg].enum;
+ if (type === 'array' || type === 'object' || (type === 'string' && def === '')) {
+ def = JSON.stringify(def);
+ }
+ if (type === 'array' && items.type) {
+ type = `array<${items.type}>`;
+ }
+ if (type === 'integer' && typeof minimum !== 'undefined' && typeof maximum !== 'undefined') {
+ description = `${description} (Value must be between \`${minimum}\` and \`${maximum}\`)`;
+ }
+ if (enums) {
+ const enumsFormatted = enums.map((e) => `\`${e}\``).join(', ');
+ description = `${description} (Value must be one of: ${enumsFormatted})`;
+ }
+ return {
+ arg: `--${arg}`,
+ aliases: appiumCliAliases.map((a) => `-${a}`),
+ type,
+ def,
+ description,
+ };
+ });
+ const body = args
+ .map(({arg, aliases, type, def, description}) => {
+ const aliasStr = aliases.map((a) => `\`${a}\``).join(', ');
+ def = typeof def !== 'undefined' ? `\`${def}\`` : '';
+ return `|\`${arg}\`|${description}|${type}|${def}|${aliasStr}|`;
+ })
+ .join('\n');
+ return `${header}\n${body}`;
+}
+
+async function writeNewDoc(preStart, argTable, postEnd) {
+ const newContents = `${preStart}${START_TAG}\n${argTable}\n${STOP_TAG}${postEnd}`;
+ await fs.writeFile(DOC_PATH, newContents);
+}
+
+if (require.main === module) {
+ main().catch((err) => {
+ throw err;
+ });
+}
+
+module.exports = main;

MODIFY
packages/appium/package.json
packages/appium/package.json
"scripts": {
"build": "babel lib --root-mode=upward --out-dir=build/lib",
"build:docs": "node docs/scripts/build-docs.js",
+ "build:docs:cli": "node docs/scripts/gen-cli-args-docs.js",
"build:docs:assets": "node docs/scripts/copy-assets.js",
"dev": "npm run build -- --watch",
"dev:docs": "npm run build:docs:assets && npm run dev:docs:en",

DELETE
packages/appium/scripts/write-server-args-docs.js
-#!/usr/bin/env node
-/* eslint-disable no-console */
-
-// @ts-check
-
-const {writeFileSync} = require('fs');
-const path = require('path');
-let parser;
-try {
- parser = require('../build/lib/cli/parser.js');
-} catch {
- console.error('Could not load parser CLI file; please execute `npm run build`');
- process.exit(1);
-}
-
-/** @type {import('../lib/cli/args').ArgumentDefinitions} */
-const appiumArguments = parser.getParser().rawArgs;
-const docFile = path.normalize(
- path.join(__dirname, '..', '..', '..', 'docs', 'en', 'writing-running-appium', 'server-args.md')
-);
-let md = `
-<!-- THIS FILE IS AUTO-GENERATED BY scripts/write-server-args-docs.js; DO NOT EDIT -->
-# Appium server arguments
-
-Many Appium 1.5 server arguments have been deprecated in favor of the [--default-capabilities flag](/docs/en/writing-running-appium/default-capabilities-arg.md).
-
-Usage: \`node . [flags]\`
-
-## Server Flags
-
-All flags are optional, but some are required in conjunction with certain others.
-
-<expand_table>
-
-|Flag|Default|Description|Example|
-|----|-------|-----------|-------|
-`;
-appiumArguments.forEach(function handleArguments(argOpts, argNames) {
- // handle empty objects
- if (JSON.stringify(argOpts.default) === '{}') {
- argOpts.default = '{}';
- }
-
- md += '|`' + argNames.join('`, `') + '`';
- md += '|' + (typeof argOpts.default === 'undefined' ? '' : argOpts.default);
- md += '|' + argOpts.help;
- md += '|';
- md += '|\n';
-});
-
-try {
- writeFileSync(docFile, md);
- console.error(
- 'New docs written! Do not forget to commit:\ngit add -A %s && git commit -m "Update %s"',
- path.relative(process.cwd(), docFile),
- path.basename(docFile)
- );
-} catch (err) {
- console.error('Could not write to file %s: %s', docFile, err);
- process.exitCode = 1;
-}

docs(appium): create a cli args docs generation system
- generate markdown tables and insert into args.md
- remove 1.x args generation docs
- write cli args docs file preamble