Skip to content

Commit

Permalink
feat: convert time flags
Browse files Browse the repository at this point in the history
  • Loading branch information
mshanemc committed Dec 21, 2022
1 parent 87299ae commit d8e39c3
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { noOclifFlagsCommandImport } from './rules/no-oclif-flags-command-import
import { noBuiltinFlags } from './rules/migration/no-builtin-flags';
import { dashO } from './rules/dash-o';
import { readOnlyProperties } from './rules/read-only-properties';
import { noTimeFlags } from './rules/migration/no-time-flags';

const recommended = {
plugins: ['sf-plugin'],
Expand Down Expand Up @@ -67,6 +68,7 @@ export = {
'sf-plugin/no-this-org': 'error',
'sf-plugin/no-this-flags': 'error',
'sf-plugin/no-builtin-flags': 'error',
'sf-plugin/no-time-flags': 'error',
},
},
},
Expand Down Expand Up @@ -96,5 +98,6 @@ export = {
'no-builtin-flags': noBuiltinFlags,
'dash-o': dashO,
'read-only-properties': readOnlyProperties,
'no-time-flags': noTimeFlags,
},
};
59 changes: 59 additions & 0 deletions src/rules/migration/no-time-flags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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 { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';
import { ancestorsContainsSfCommand, isInCommandDirectory } from '../../shared/commands';
import { isFlag } from '../../shared/flags';

const timeFlags = ['seconds', 'minutes', 'milliseconds'];

export const noTimeFlags = ESLintUtils.RuleCreator.withoutDocs({
meta: {
docs: {
description: 'Migrate time flags to Flags.duration',
recommended: 'error',
},
messages: {
message: 'flags for {{time}} should use the Flags.duration (and specify the unit)',
},
type: 'problem',
fixable: 'code',
schema: [],
},
defaultOptions: [],
create(context) {
return isInCommandDirectory(context)
? {
Property(node): void {
if (isFlag(node) && ancestorsContainsSfCommand(context.getAncestors())) {
if (
node.key.type === AST_NODE_TYPES.Identifier &&
node.value.type === AST_NODE_TYPES.CallExpression &&
node.value.callee.type === AST_NODE_TYPES.MemberExpression &&
node.value.callee.property.type === AST_NODE_TYPES.Identifier &&
timeFlags.includes(node.value.callee.property.name)
) {
const original = context.getSourceCode().getText(node);
const unit = node.value.callee.property.name;
const fixed = original
.replace(`Flags.${unit}({`, `Flags.duration({ unit: '${unit}',`)
.replace('default:', 'defaultValue:')
.replace(new RegExp(`Duration.${unit}\\((.*)\\)`, 'g'), '$1');
context.report({
node,
messageId: 'message',
data: { time: node.value.callee.property.name },
fix: (fixer) => {
return fixer.replaceText(node, fixed);
},
});
}
}
},
}
: {};
},
});
File renamed without changes.
80 changes: 80 additions & 0 deletions test/rules/migration/no-time-flags.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* 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 path from 'path';
import { ESLintUtils } from '@typescript-eslint/utils';
import { noTimeFlags } from '../../../src/rules/migration/no-time-flags';

const ruleTester = new ESLintUtils.RuleTester({
parser: '@typescript-eslint/parser',
});

ruleTester.run('noTimeFlags', noTimeFlags, {
valid: [
{
name: 'duration flag',
filename: path.normalize('src/commands/foo.ts'),
code: `
export default class EnvCreateScratch extends SfCommand<ScratchCreateResponse> {
public static flags = {
wait: Flags.duration({
char: 'w',
unit: 'minutes',
default: Duration.minutes(DeployCommand.DEFAULT_WAIT_MINUTES),
min: Duration.minutes(1),
description: messages.getMessage('flags.wait'),
longDescription: messages.getMessage('flagsLong.wait'),
})
}
}
`,
},
{
name: 'not in command directory',
filename: path.normalize('foo.ts'),
code: `
export default class EnvCreateScratch extends SfCommand<Foo> {
public static flags = {
wait: Flags.minutes({
default: Duration.minutes(DeployCommand.DEFAULT_WAIT_MINUTES),
min: Duration.minutes(1),
}),
}
}
`,
},
],
invalid: [
{
name: 'has a minutes flag',
filename: path.normalize('src/commands/foo.ts'),
errors: [{ messageId: 'message', data: { time: 'minutes' } }],
code: `
export default class EnvCreateScratch extends SfCommand<Foo> {
public static flags = {
wait: Flags.minutes({
default: Duration.minutes(DeployCommand.DEFAULT_WAIT_MINUTES),
min: Duration.minutes(1),
min: Duration.minutes(8),
}),
}
}
`,
output: `
export default class EnvCreateScratch extends SfCommand<Foo> {
public static flags = {
wait: Flags.duration({ unit: 'minutes',
defaultValue: DeployCommand.DEFAULT_WAIT_MINUTES,
min: 1,
min: 8,
}),
}
}
`,
},
],
});

0 comments on commit d8e39c3

Please sign in to comment.