feat(core): add --affected to show only affected projects (#16970)

This commit is contained in:
Craigory Coppola 2023-05-13 01:48:35 -04:00 committed by GitHub
parent c71027fbfb
commit b20e906f00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 428 additions and 193 deletions

View File

@ -55,12 +55,6 @@ Open the project graph of the workspace in the browser, highlight the projects a
## Options
### all
Type: `boolean`
All projects
### base
Type: `string`

View File

@ -73,11 +73,11 @@ Use the currently executing project name in your command.:
## Options
### all
### ~~all~~
Type: `boolean`
All projects
**Deprecated:** Use `nx run-many` instead
### base

View File

@ -21,7 +21,7 @@ Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`
Type: `boolean`
All projects
Format all projects
### base

View File

@ -21,7 +21,7 @@ Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`
Type: `boolean`
All projects
Format all projects
### base

View File

@ -49,12 +49,6 @@ Prints the tasks.target.project property from the print-affected output:
## Options
### all
Type: `boolean`
All projects
### base
Type: `string`

View File

@ -10,11 +10,31 @@ Show information about the workspace (e.g., list of projects)
## Usage
```shell
nx show <object>
nx show
```
Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`, `yarn nx`, or `pnpm nx`.
### Examples
Show all projects in the workspace:
```shell
nx show projects
```
Show affected projects in the workspace:
```shell
nx show projects --affected
```
Show affected projects in the workspace, excluding end-to-end projects:
```shell
nx show projects --affected --exclude *-e2e
```
## Options
### help
@ -23,14 +43,74 @@ Type: `boolean`
Show help
### object
Choices: [projects]
What to show (e.g., projects)
### version
Type: `boolean`
Show version number
## Subcommands
### projects
Show a list of projects in the workspace
```shell
nx show projects
```
#### Options
##### affected
Type: `boolean`
Show only affected projects
##### base
Type: `string`
Base of the current branch (usually main)
##### exclude
Type: `string`
Exclude certain projects from being processed
##### files
Type: `string`
Change the way Nx is calculating the affected command by providing directly changed files, list of files delimited by commas or spaces
##### head
Type: `string`
Latest commit of the current branch (usually HEAD)
##### help
Type: `boolean`
Show help
##### uncommitted
Type: `boolean`
Uncommitted changes
##### untracked
Type: `boolean`
Untracked changes
##### version
Type: `boolean`
Show version number

View File

@ -5,9 +5,9 @@ description: 'Runs a workspace generator from the tools/generators directory'
# workspace-generator
**Deprecated:** Use a local plugin instead. See: https://nx.dev/deprecated/workspace-generators
**Deprecated:** Use a local plugin instead. See: https://nx.dev/deprecated/workspace-generators
Runs a workspace generator from the tools/generators directory
Runs a workspace generator from the tools/generators directory
## Usage

View File

@ -5,9 +5,9 @@ description: 'Lint nx specific workspace files (nx.json, workspace.json)'
# workspace-lint
**Deprecated:** workspace-lint is deprecated, and will be removed in v17. The checks it used to perform are no longer relevant.
**Deprecated:** workspace-lint is deprecated, and will be removed in v17. The checks it used to perform are no longer relevant.
Lint nx specific workspace files (nx.json, workspace.json)
Lint nx specific workspace files (nx.json, workspace.json)
## Usage

View File

@ -55,12 +55,6 @@ Open the project graph of the workspace in the browser, highlight the projects a
## Options
### all
Type: `boolean`
All projects
### base
Type: `string`

View File

@ -73,11 +73,11 @@ Use the currently executing project name in your command.:
## Options
### all
### ~~all~~
Type: `boolean`
All projects
**Deprecated:** Use `nx run-many` instead
### base

View File

@ -21,7 +21,7 @@ Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`
Type: `boolean`
All projects
Format all projects
### base

View File

@ -21,7 +21,7 @@ Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`
Type: `boolean`
All projects
Format all projects
### base

View File

@ -49,12 +49,6 @@ Prints the tasks.target.project property from the print-affected output:
## Options
### all
Type: `boolean`
All projects
### base
Type: `string`

View File

@ -10,11 +10,31 @@ Show information about the workspace (e.g., list of projects)
## Usage
```shell
nx show <object>
nx show
```
Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`, `yarn nx`, or `pnpm nx`.
### Examples
Show all projects in the workspace:
```shell
nx show projects
```
Show affected projects in the workspace:
```shell
nx show projects --affected
```
Show affected projects in the workspace, excluding end-to-end projects:
```shell
nx show projects --affected --exclude *-e2e
```
## Options
### help
@ -23,14 +43,74 @@ Type: `boolean`
Show help
### object
Choices: [projects]
What to show (e.g., projects)
### version
Type: `boolean`
Show version number
## Subcommands
### projects
Show a list of projects in the workspace
```shell
nx show projects
```
#### Options
##### affected
Type: `boolean`
Show only affected projects
##### base
Type: `string`
Base of the current branch (usually main)
##### exclude
Type: `string`
Exclude certain projects from being processed
##### files
Type: `string`
Change the way Nx is calculating the affected command by providing directly changed files, list of files delimited by commas or spaces
##### head
Type: `string`
Latest commit of the current branch (usually HEAD)
##### help
Type: `boolean`
Show help
##### uncommitted
Type: `boolean`
Uncommitted changes
##### untracked
Type: `boolean`
Untracked changes
##### version
Type: `boolean`
Show version number

View File

@ -5,9 +5,9 @@ description: 'Runs a workspace generator from the tools/generators directory'
# workspace-generator
**Deprecated:** Use a local plugin instead. See: https://nx.dev/deprecated/workspace-generators
**Deprecated:** Use a local plugin instead. See: https://nx.dev/deprecated/workspace-generators
Runs a workspace generator from the tools/generators directory
Runs a workspace generator from the tools/generators directory
## Usage

View File

@ -5,9 +5,9 @@ description: 'Lint nx specific workspace files (nx.json, workspace.json)'
# workspace-lint
**Deprecated:** workspace-lint is deprecated, and will be removed in v17. The checks it used to perform are no longer relevant.
**Deprecated:** workspace-lint is deprecated, and will be removed in v17. The checks it used to perform are no longer relevant.
Lint nx specific workspace files (nx.json, workspace.json)
Lint nx specific workspace files (nx.json, workspace.json)
## Usage

View File

@ -65,46 +65,46 @@ describe('Nx Affected and Graph Tests', () => {
);
const affectedApps = runCLI(
`print-affected --files="libs/${mylib}/src/index.ts" --select projects`
`show projects --affected --files="libs/${mylib}/src/index.ts"`
);
expect(affectedApps).toContain(myapp);
expect(affectedApps).not.toContain(myapp2);
const implicitlyAffectedApps = runCLI(
'print-affected --select projects --files="tsconfig.base.json"'
'show projects --affected --files="tsconfig.base.json"'
);
expect(implicitlyAffectedApps).toContain(myapp);
expect(implicitlyAffectedApps).toContain(myapp2);
const noAffectedApps = runCLI(
'print-affected --select projects --files="README.md"'
'show projects --affected projects --files="README.md"'
);
expect(noAffectedApps).not.toContain(myapp);
expect(noAffectedApps).not.toContain(myapp2);
const affectedLibs = runCLI(
`print-affected --select projects --files="libs/${mylib}/src/index.ts"`
`show projects --affected --files="libs/${mylib}/src/index.ts"`
);
expect(affectedLibs).toContain(mypublishablelib);
expect(affectedLibs).toContain(mylib);
expect(affectedLibs).not.toContain(mylib2);
const implicitlyAffectedLibs = runCLI(
'print-affected --select projects --files="tsconfig.base.json"'
'show projects --affected --files="tsconfig.base.json"'
);
expect(implicitlyAffectedLibs).toContain(mypublishablelib);
expect(implicitlyAffectedLibs).toContain(mylib);
expect(implicitlyAffectedLibs).toContain(mylib2);
const noAffectedLibsNonExistentFile = runCLI(
'print-affected --select projects --files="tsconfig.json"'
'show projects --affected --files="tsconfig.json"'
);
expect(noAffectedLibsNonExistentFile).not.toContain(mypublishablelib);
expect(noAffectedLibsNonExistentFile).not.toContain(mylib);
expect(noAffectedLibsNonExistentFile).not.toContain(mylib2);
const noAffectedLibs = runCLI(
'print-affected --select projects --files="README.md"'
'show projects --affected --files="README.md"'
);
expect(noAffectedLibs).not.toContain(mypublishablelib);
expect(noAffectedLibs).not.toContain(mylib);

View File

@ -205,7 +205,7 @@
"lines-and-columns": "~2.0.3",
"loader-utils": "2.0.3",
"magic-string": "~0.26.2",
"markdown-factory": "^0.0.3",
"markdown-factory": "^0.0.5",
"memfs": "^3.0.1",
"metro-resolver": "^0.74.1",
"mini-css-extract-plugin": "~2.4.7",

View File

@ -1,4 +1,4 @@
import { CommandModule } from 'yargs';
import { boolean, CommandModule, middleware } from 'yargs';
import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
import {
withAffectedOptions,
@ -19,7 +19,18 @@ export const yargsAffectedCommand: CommandModule = {
withRunOptions(
withOutputStyleOption(withTargetAndConfigurationOption(yargs))
)
),
)
.option('all', {
type: 'boolean',
deprecated: 'Use `nx run-many` instead',
})
.middleware((args) => {
if (args.all !== undefined) {
throw new Error(
"The '--all' option has been removed for `nx affected`. Use 'nx run-many' instead."
);
}
}),
'affected'
),
handler: async (args) =>

View File

@ -339,6 +339,23 @@ export const examples: Record<string, Example[]> = {
'Create a dedicated commit for each successfully completed migration. You can customize the prefix used for each commit by additionally setting --commit-prefix="PREFIX_HERE "',
},
],
show: [
{
command: 'show projects',
description: 'Show all projects in the workspace',
},
{
command: 'show projects --affected',
description: 'Show affected projects in the workspace',
},
{
command: 'show projects --affected --exclude *-e2e',
description:
'Show affected projects in the workspace, excluding end-to-end projects',
},
],
watch: [
{
command:

View File

@ -39,6 +39,10 @@ function withFormatOptions(yargs: Argv): Argv {
type: 'string',
coerce: parseCSV,
})
.option('all', {
describe: 'Format all projects',
type: 'boolean',
})
.conflicts({
all: 'projects',
});

View File

@ -1,45 +1,47 @@
import { Argv, CommandModule } from 'yargs';
import { CommandModule } from 'yargs';
import { withAffectedOptions } from '../yargs-utils/shared-options';
import { ShowProjectOptions } from './show';
const validObjectTypes = ['projects'] as const;
type NxObject = typeof validObjectTypes[number];
interface ShowCommandArguments {
object: NxObject;
}
export const yargsShowCommand: CommandModule<
ShowCommandArguments,
ShowCommandArguments
> = {
command: 'show <object>',
export const yargsShowCommand: CommandModule = {
command: 'show',
describe: 'Show information about the workspace (e.g., list of projects)',
builder: (yargs) => withShowOptions(yargs),
builder: (yargs) =>
yargs
.command(showProjectsCommand)
.demandCommand()
.example(
'$0 show projects',
'Show a list of all projects in the workspace'
)
.example(
'$0 show projects --affected',
'Show affected projects in the workspace'
)
.example(
'$0 show projects --affected --exclude *-e2e',
'Show affected projects in the workspace, excluding end-to-end projects'
),
handler: async (args) => {
if (!validObjectTypes.includes(args.object)) {
}
await import('./show').then((m) => m.show(args));
process.exit(0);
// Noop, yargs will error if not in a subcommand.
},
};
function withShowOptions(yargs: Argv) {
return yargs
.positional('object', {
describe: 'What to show (e.g., projects)',
choices: ['projects'],
required: true,
})
.coerce({
object: (arg) => {
if (validObjectTypes.includes(arg)) {
return arg;
} else {
throw new Error(
`Invalid object type: ${arg}. Valid object types are: ${validObjectTypes.join(
', '
)}`
);
}
},
});
}
const showProjectsCommand: CommandModule<
Record<string, unknown>,
ShowProjectOptions
> = {
command: 'projects',
describe: 'Show a list of projects in the workspace',
builder: (yargs) =>
withAffectedOptions(yargs)
.option('affected', {
type: 'boolean',
description: 'Show only affected projects',
})
.implies('untracked', 'affected')
.implies('uncommitted', 'affected')
.implies('files', 'affected')
.implies('base', 'affected')
.implies('head', 'affected'),
handler: (args) => import('./show').then((m) => m.showProjectsHandler(args)),
};

View File

@ -1,13 +1,74 @@
import { filterAffected } from '../../project-graph/affected/affected-project-graph';
import {
calculateFileChanges,
readNxJson,
} from '../../project-graph/file-utils';
import {
NxArgs,
parseFiles,
splitArgsIntoNxArgsAndOverrides,
} from '../../utils/command-line-utils';
import { createProjectGraphAsync } from '../../project-graph/project-graph';
import { NxJsonConfiguration } from '../../config/nx-json';
import { ProjectGraph } from '../../config/project-graph';
import { findMatchingProjects } from '../../utils/find-matching-projects';
export async function show(args: { object: 'projects' }): Promise<void> {
if (args.object == 'projects') {
const graph = await createProjectGraphAsync();
const projects = Object.keys(graph.nodes).join('\n');
if (projects.length) {
console.log(projects);
}
} else {
throw new Error(`Unrecognized option: ${args.object}`);
export type ShowProjectOptions = {
exclude: string;
files: string;
uncommitted: any;
untracked: any;
base: string;
head: string;
affected: boolean;
};
export async function showProjectsHandler(
args: ShowProjectOptions
): Promise<void> {
let graph = await createProjectGraphAsync();
const nxJson = readNxJson();
const { nxArgs } = splitArgsIntoNxArgsAndOverrides(
args,
'affected',
{
printWarnings: false,
},
nxJson
);
if (args.affected) {
graph = await getAffectedGraph(nxArgs, nxJson, graph);
}
const selectedProjects = new Set(Object.keys(graph.nodes));
if (args.exclude) {
const excludedProjects = findMatchingProjects(nxArgs.exclude, graph.nodes);
for (const excludedProject of excludedProjects) {
selectedProjects.delete(excludedProject);
}
}
const projects = Array.from(selectedProjects).join('\n');
if (projects.length) {
console.log(projects);
}
process.exit(0);
}
function getAffectedGraph(
nxArgs: NxArgs,
nxJson: NxJsonConfiguration<'*' | string[]>,
graph: ProjectGraph
) {
return filterAffected(
graph,
calculateFileChanges(
parseFiles(nxArgs).files,
graph.allWorkspaceFiles,
nxArgs
),
nxJson
);
}

View File

@ -1,6 +1,6 @@
import { Argv } from 'yargs';
export function withExcludeOption(yargs: Argv): Argv {
export function withExcludeOption(yargs: Argv) {
return yargs.option('exclude', {
describe: 'Exclude certain projects from being processed',
type: 'string',
@ -8,7 +8,7 @@ export function withExcludeOption(yargs: Argv): Argv {
});
}
export function withRunOptions(yargs: Argv): Argv {
export function withRunOptions(yargs: Argv) {
return withExcludeOption(yargs)
.option('parallel', {
describe: 'Max number of parallel processes [default is 3]',
@ -74,7 +74,7 @@ export function withRunOptions(yargs: Argv): Argv {
export function withTargetAndConfigurationOption(
yargs: Argv,
demandOption = true
): Argv {
) {
return withConfiguration(yargs).option('targets', {
describe: 'Tasks to run for affected projects',
type: 'string',
@ -95,7 +95,7 @@ export function withConfiguration(yargs: Argv) {
});
}
export function withAffectedOptions(yargs: Argv): Argv {
export function withAffectedOptions(yargs: Argv) {
return withExcludeOption(yargs)
.parserConfiguration({
'strip-dashed': true,
@ -112,17 +112,10 @@ export function withAffectedOptions(yargs: Argv): Argv {
.option('uncommitted', {
describe: 'Uncommitted changes',
type: 'boolean',
default: undefined,
})
.option('untracked', {
describe: 'Untracked changes',
type: 'boolean',
default: undefined,
})
.option('all', {
describe: 'All projects',
type: 'boolean',
default: undefined,
})
.option('base', {
describe: 'Base of the current branch (usually main)',
@ -145,14 +138,13 @@ export function withAffectedOptions(yargs: Argv): Argv {
.group(['files', 'uncommitted', 'untracked'], 'or using:')
.implies('head', 'base')
.conflicts({
files: ['uncommitted', 'untracked', 'base', 'head', 'all'],
untracked: ['uncommitted', 'files', 'base', 'head', 'all'],
uncommitted: ['files', 'untracked', 'base', 'head', 'all'],
all: ['files', 'untracked', 'uncommitted', 'base', 'head'],
files: ['uncommitted', 'untracked', 'base', 'head'],
untracked: ['uncommitted', 'files', 'base', 'head'],
uncommitted: ['files', 'untracked', 'base', 'head'],
});
}
export function withRunManyOptions(yargs: Argv): Argv {
export function withRunManyOptions(yargs: Argv) {
return withRunOptions(yargs)
.parserConfiguration({
'strip-dashed': true,
@ -185,7 +177,7 @@ export function withOverrides(args: any): any {
export function withOutputStyleOption(
yargs: Argv,
choices = ['dynamic', 'static', 'stream', 'stream-without-prefixes']
): Argv {
) {
return yargs.option('output-style', {
describe: 'Defines how Nx emits outputs tasks logs',
type: 'string',
@ -193,7 +185,7 @@ export function withOutputStyleOption(
});
}
export function withDepGraphOptions(yargs: Argv): Argv {
export function withDepGraphOptions(yargs: Argv) {
return yargs
.option('file', {
describe:

View File

@ -111,21 +111,6 @@ export function splitArgsIntoNxArgsAndOverrides(
});
}
if (
!nxArgs.files &&
!nxArgs.uncommitted &&
!nxArgs.untracked &&
!nxArgs.base &&
!nxArgs.head &&
!nxArgs.all &&
overrides._ &&
overrides._.length >= 2
) {
throw new Error(
`Nx no longer supports using positional arguments for base and head. Please use --base and --head instead.`
);
}
// Allow setting base and head via environment variables (lower priority then direct command arguments)
if (!nxArgs.base && process.env.NX_BASE) {
nxArgs.base = process.env.NX_BASE;

8
pnpm-lock.yaml generated
View File

@ -665,8 +665,8 @@ devDependencies:
specifier: ~0.26.2
version: 0.26.2
markdown-factory:
specifier: ^0.0.3
version: 0.0.3
specifier: ^0.0.5
version: 0.0.5
memfs:
specifier: ^3.0.1
version: 3.4.7
@ -17673,8 +17673,8 @@ packages:
resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==}
dev: true
/markdown-factory@0.0.3:
resolution: {integrity: sha512-y7XffnQ61exHdRdFmvp9MeJBGOpUIYJEdiNgj25VCCivA/oXs615ppGqH01lnG8zcZ9cEEPW1jIi1y/Xu4URPA==}
/markdown-factory@0.0.5:
resolution: {integrity: sha512-76bovWfQkv0Pd4qrq3h5sTiimoBUIi3sKac6CUKGPLgEhghrPGBgdXRhVH9sjDpbbyCspRPg940WVrcA9h+XPg==}
dev: true
/markdown-to-jsx@7.2.0(react@18.2.0):

View File

@ -1,11 +1,13 @@
import * as chalk from 'chalk';
import { readFileSync } from 'fs';
import { readJsonSync } from 'fs-extra';
import { codeBlock, h1, h2, h3, lines } from 'markdown-factory';
import { join } from 'path';
import { register as registerTsConfigPaths } from 'tsconfig-paths';
import { examples } from '../../../packages/nx/src/command-line/examples';
import {
formatDeprecated,
formatDescription,
generateMarkdownFile,
generateOptionsMarkdown,
getCommands,
@ -39,39 +41,52 @@ export async function generateCliDocumentation(
);
function generateMarkdown(command: ParsedCommand) {
let template = `
let templateLines = [
`
---
title: "${command.name} - CLI command"
description: "${command.description}"
---
# ${command.name}
${formatDeprecated(command.description, command.deprecated)}
## Usage
\`\`\`shell
nx ${command.commandString}
\`\`\`
Install \`nx\` globally to invoke the command directly using \`nx\`, or use \`npx nx\`, \`yarn nx\`, or \`pnpm nx\`.\n`;
---`,
h1(command.name),
formatDescription(command.description, command.deprecated),
h2('Usage'),
codeBlock(`nx ${command.commandString}`, 'shell'),
'Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`, `yarn nx`, or `pnpm nx`.',
];
if (examples[command.name] && examples[command.name].length > 0) {
template += `\n### Examples\n`;
templateLines.push(h3('Examples'));
examples[command.name].forEach((example) => {
template += `${example.description}:\n\`\`\`shell\n nx ${example.command}\n\`\`\`\n`;
templateLines.push(
example.description + ':',
codeBlock(` nx ${example.command}`, 'shell')
);
});
}
template += generateOptionsMarkdown(command);
templateLines.push(generateOptionsMarkdown(command));
if (command.subcommands?.length) {
templateLines.push(h2('Subcommands'));
for (const subcommand of command.subcommands) {
templateLines.push(
h3(subcommand.name),
formatDescription(subcommand.description, subcommand.deprecated),
codeBlock(
`nx ${command.commandString} ${subcommand.commandString}`,
'shell'
),
generateOptionsMarkdown(subcommand, 2)
);
}
}
return {
name: command.name
.replace(':', '-')
.replace(' ', '-')
.replace(/[\]\[.]+/gm, ''),
template,
template: lines(templateLines),
};
}

View File

@ -1,4 +1,5 @@
import { outputFileSync } from 'fs-extra';
import { bold, h, lines as mdLines, strikethrough } from 'markdown-factory';
import { join } from 'path';
import { format, resolveConfig } from 'prettier';
@ -65,7 +66,7 @@ export async function formatWithPrettier(filePath: string, content: string) {
return format(content, options);
}
export function formatDeprecated(
export function formatDescription(
description: string,
deprecated: boolean | string
) {
@ -73,12 +74,8 @@ export function formatDeprecated(
return description;
}
return deprecated === true
? `**Deprecated:** ${description}`
: `
**Deprecated:** ${deprecated}
${description}
`;
? `${bold('Deprecated:')} ${description}`
: mdLines(`${bold('Deprecated:')} ${deprecated}`, description);
}
export function getCommands(command: any) {
@ -87,9 +84,12 @@ export function getCommands(command: any) {
export interface ParsedCommandOption {
name: string;
type: string;
description: string;
default: string;
deprecated: boolean | string;
hidden: boolean;
choices?: string[];
}
export interface ParsedCommand {
@ -98,6 +98,7 @@ export interface ParsedCommand {
description: string;
deprecated: string;
options?: Array<ParsedCommandOption>;
subcommands?: Array<ParsedCommand>;
}
const YargsTypes = ['array', 'count', 'string', 'boolean', 'number'];
@ -142,6 +143,12 @@ export async function parseCommand(
);
return acc;
}, {});
const subcommands = await Promise.all(
Object.entries(getCommands(builder)).map(
([subCommandName, subCommandConfig]) =>
parseCommand(subCommandName, subCommandConfig)
)
);
return {
name,
@ -160,39 +167,44 @@ export async function parseCommand(
deprecated: builderDeprecatedOptions[key],
hidden: builderOptions.hiddenOptions.includes(key),
})) || null,
subcommands,
};
}
export function generateOptionsMarkdown(command: any): string {
let response = '';
export function generateOptionsMarkdown(
command: ParsedCommand,
extraHeadingLevels = 0
): string {
const lines: string[] = [];
if (Array.isArray(command.options) && !!command.options.length) {
response += '\n## Options\n';
lines.push(h(2 + extraHeadingLevels, 'Options'));
command.options
.sort((a: any, b: any) => sortAlphabeticallyFunction(a.name, b.name))
.filter(({ hidden }: any) => !hidden)
.forEach((option: any) => {
response += `\n### ${
option.deprecated ? `~~${option.name}~~` : option.name
}\n`;
.sort((a, b) => sortAlphabeticallyFunction(a.name, b.name))
.filter(({ hidden }) => !hidden)
.forEach((option) => {
lines.push(
h(
3 + extraHeadingLevels,
option.deprecated ? strikethrough(option.name) : option.name
)
);
if (option.type !== undefined && option.type !== '') {
response += `\nType: \`${option.type}\`\n`;
lines.push(`Type: \`${option.type}\``);
}
if (option.choices !== undefined) {
const choices = option.choices
.map((c: any) => JSON.stringify(c).replace(/"/g, ''))
.join(', ');
response += `\nChoices: [${choices}]\n`;
lines.push(`Choices: [${choices}]`);
}
if (option.default !== undefined && option.default !== '') {
response += `\nDefault: \`${JSON.stringify(option.default).replace(
/"/g,
''
)}\`\n`;
lines.push(
`Default: \`${JSON.stringify(option.default).replace(/"/g, '')}\``
);
}
response +=
'\n' + formatDeprecated(option.description, option.deprecated);
lines.push(formatDescription(option.description, option.deprecated));
});
}
return response;
return mdLines(lines);
}