generated from salesforcecli/plugin-template-sf
-
Notifications
You must be signed in to change notification settings - Fork 3
/
flag.ts
95 lines (76 loc) · 3.45 KB
/
flag.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
* Copyright (c) 2022, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import path from 'node:path';
import os from 'node:os';
import fs from 'node:fs/promises';
import select from '@inquirer/select';
import shelljs from 'shelljs';
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
import { Messages } from '@salesforce/core';
import { toStandardizedId } from '@oclif/core';
import fg from 'fast-glob';
import { askQuestions } from '../../../prompts/series/flagPrompts.js';
import { fileExists, build, apply } from '../../../util.js';
import { FlagAnswers } from '../../../types.js';
import { stringToChoice } from '../../../prompts/functions.js';
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
export const messages = Messages.loadMessages('@salesforce/plugin-dev', 'dev.generate.flag');
export default class DevGenerateFlag extends SfCommand<void> {
public static enableJsonFlag = false;
public static readonly summary = messages.getMessage('summary');
public static readonly description = messages.getMessage('description');
public static readonly examples = messages.getMessages('examples');
public static readonly flags = {
'dry-run': Flags.boolean({
summary: messages.getMessage('flags.dry-run.summary'),
char: 'd',
aliases: ['dryrun'],
}),
};
public async run(): Promise<void> {
const { flags } = await this.parse(DevGenerateFlag);
if (!(await fileExists('package.json'))) throw messages.createError('error.InvalidDir');
const command = await select({
message: messages.getMessage('question.SelectCommand'),
choices: (await findExistingCommands(this.config.topicSeparator)).map(stringToChoice),
});
const standardizedCommandId = toStandardizedId(command, this.config);
const answers = await askQuestions(standardizedCommandId);
const commandFilePath = `${path.join('.', 'src', 'commands', ...standardizedCommandId.split(':'))}.ts`;
const newFlag = build(answers);
if (flags['dry-run']) {
this.styledHeader('New flag:');
this.log(newFlag.join(os.EOL));
return;
}
const existing = await fs.readFile(commandFilePath, 'utf-8');
const updatedFile = apply({ flagParts: newFlag, existing });
await fs.writeFile(commandFilePath, updatedFile);
await updateMarkdownFile(answers, standardizedCommandId);
shelljs.exec(`yarn prettier --write ${commandFilePath}`);
shelljs.exec('yarn compile');
this.log(`Added ${answers.name} flag to ${commandFilePath}`);
}
}
const findExistingCommands = async (topicSeparator: string): Promise<string[]> =>
(await fg('src/commands/**/*.ts'))
.map((file) => {
// fast-glob always returns posix paths so no need to use path.join here
const p = path.parse(file.replace('src/commands', ''));
const topics = p.dir.split('/');
const command = p.name !== 'index' && p.name;
const id = [...topics, command].filter((f) => f).join(topicSeparator);
return id === '' ? '.' : id;
})
.sort();
const updateMarkdownFile = async (answers: FlagAnswers, commandName: string): Promise<void> =>
answers.summary
? fs.appendFile(
path.join('messages', `${commandName.split(':').join('.')}.md`),
`${os.EOL}# flags.${answers.name}.summary${os.EOL}${os.EOL}${answers.summary}${os.EOL}`
)
: undefined;