Skip to content

Commit

Permalink
fix: add convert:script command, starting to clean it up
Browse files Browse the repository at this point in the history
  • Loading branch information
WillieRuemmele committed Apr 20, 2023
1 parent c4e24a5 commit e88ca94
Show file tree
Hide file tree
Showing 8 changed files with 15,491 additions and 21 deletions.
9 changes: 9 additions & 0 deletions command-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
[
{
"command": "convert:script",
"plugin": "@salesforce/plugin-dev",
"flags": [
"json",
"name"
],
"alias": []
},
{
"command": "dev:audit:messages",
"plugin": "@salesforce/plugin-dev",
Expand Down
20 changes: 20 additions & 0 deletions messages/convert.script.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# summary

Summary of a command.

# description

Description of a command.

# flags.script.summary

Description of a flag.

# flags.no-prompt.summary

Don't prompt for replacements

# examples

- <%= config.bin %> <%= command.id %> convert script --script myScript.yml

141 changes: 141 additions & 0 deletions src/commands/convert/script.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* Copyright (c) 2020, 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 * as fs from 'fs';
import * as os from 'os';
import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
import { Messages } from '@salesforce/core';
import { Manifest } from '../../manifest';

Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/plugin-dev', 'convert.script');

export default class ConvertScript extends SfCommand<void> {
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 = {
script: Flags.file({
summary: messages.getMessage('flags.script.summary'),
char: 's',
required: true,
}),
'no-prompt': Flags.boolean({
hidden: true,
default: false,
summary: messages.getMessage('flags.no-prompt.summary'),
}),
};

// this command will replace the 'sfdx' "deprecated" style commands, with the 'sf' commands
// it will not guarantee breaking changes, or changed json results
// it will scan a script line by line, and prompt the user to replace the command
// it will not replace the command if the user does not confirm
// it uses the command-snapshot.json file at the CLI level to determine the command to replace

public async run(): Promise<void> {
const { flags } = await this.parse(ConvertScript);

this.warn(
'This script will replace sfdx commands for sf commands. It does not guarantee breaking changes, or changed json results.'
);
this.warn(
"As an additional reminder, the sfdx commands will be available in sf and can be migrated by simpling changing 'sfdx' to 'sf'."
);
this.warn("This script assumes you've uninstalled `sf v1` and `sfdx` and are ready to use `sf v2` ");

await this.smartConfirm('Do you want to continue?', !flags['no-prompt']);

const contents = await fs.promises.readFile(flags.script, 'utf8');

const manifest = Object.values(Manifest);

const lines = contents.split(os.EOL);
const data: string[] = [];
// examples:
// sfdx force:user:password:generate -u myuser
// sfdx force:package:install -p 04t1I0000000X0P -w 10 -u myorg
// sfdx force:package:beta:version:list -p 04t1I0000000X0P -u myorg

for (let line of lines) {
try {
// if the line looks like it's a valid sfdx command
if (line.match(/sfdx \w+/g)?.length && line.includes(':') && !line.startsWith('#')) {
const commandId = line.split('sfdx ')[1]?.split(' ')[0];

let replacement = manifest.find(
(c) =>
(c.state === 'deprecated' &&
c.deprecationOptions?.to &&
c.id === commandId &&
!c.deprecationOptions.to.includes('/')) ||
c.aliases.includes(commandId)
);

if (Manifest[commandId]?.deprecationOptions?.to.includes('/')) {
this.warn(`Cannot determine appropriate replacement for ${commandId}`);
}

if (replacement) {
if (
replacement.id === commandId &&
replacement.state === 'deprecated' &&
replacement.deprecationOptions?.to
) {
const replacedWithSemiColons = replacement.deprecationOptions.to.replace(/ /g, ':');
replacement = manifest.find((c) => c.id === replacedWithSemiColons);
}
// we can only replace flags for commands we know about

if (await this.smartConfirm(`replace ${commandId} for ${replacement.id}`, !flags['no-prompt'])) {
line = line.replace(commandId, replacement.id);
}

const replacementFlags = Object.values(replacement.flags);

for (const flag of line
.match(/ -\w/g)
.concat(line.match(/ --\w(\w|-)*/g))
.filter((f) => f)) {
// trim down the flag to remove '-', '--' and optionally a '='
const flagName =
flag.replace(' -', '').replace(' --', '').split(' ')[0] ?? flag.replace(' --', '').split('=')[0];

const replacementFlag = replacementFlags.find(
(f) => f.char === flagName || f.aliases?.includes(flagName)
).name;

// don't prompt if the flag already matches the replacement
if (
replacementFlag &&
replacementFlag !== flagName &&
(await this.smartConfirm(`\treplacing ${flagName} for ${replacementFlag}`, !flags['no-prompt']))
) {
line = line.replace(flag, ` --${replacementFlag}${flag.includes('=') ? '=' : ''}`);
}
}
}
// bare minimum replace sfdx with sf, and -u -> --target-org, -v -> --target-dev-hub
line = line.replace('sfdx ', 'sf ').replace(' -u ', ' --target-org ').replace(' -v ', ' --target-dev-hub');
data.push(line);
} else {
// no changes
data.push(line);
}
} catch (e) {
line = line.replace('sfdx ', 'sf ').replace(' -u ', ' --target-org ');
line = line.concat(' # ERROR converting this line, human intervention required');
data.push(line);
}
}
fs.writeFileSync(flags.script, data.join(os.EOL));
}

private async smartConfirm(message: string, prompt = true): Promise<boolean> {
return prompt ? await this.confirm(message, 100000) : true;
}
}
Loading

0 comments on commit e88ca94

Please sign in to comment.