From 2d10c6e57f24c1ab95b415b2f62256f1a1bffbb2 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Thu, 15 Jun 2023 18:27:24 +0700 Subject: [PATCH] codemod(v6): Convert all process.env usage to dot notation (#8611) --- .../v6.x.x/processEnvDotNotation/README.md | 10 +++++++ .../__testfixtures__/default.input.js | 10 +++++++ .../__testfixtures__/default.output.js | 9 ++++++ .../__tests__/processEnvDotNotation.test.ts | 5 ++++ .../processEnvDotNotation.ts | 30 +++++++++++++++++++ .../processEnvDotNotation.yargs.ts | 25 ++++++++++++++++ .../testUtils/matchInlineTransformSnapshot.ts | 3 ++ .../src/testUtils/matchTransformSnapshot.ts | 3 +- .../tasks/generateCodemod/generateCodemod.mjs | 3 +- .../templates/code/codemod.yargs.ts.template | 8 +++-- 10 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/README.md create mode 100644 packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/__testfixtures__/default.input.js create mode 100644 packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/__testfixtures__/default.output.js create mode 100644 packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/__tests__/processEnvDotNotation.test.ts create mode 100644 packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/processEnvDotNotation.ts create mode 100644 packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/processEnvDotNotation.yargs.ts diff --git a/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/README.md b/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/README.md new file mode 100644 index 000000000000..39e71d611c54 --- /dev/null +++ b/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/README.md @@ -0,0 +1,10 @@ +# Process Env Dot Notation + +Finds all cases where `process.env` is accessed via array notation (specifically string literals), and converts it to dot notation. + +```diff +- process.env['BAZINGA'] ++ process.env.BAZINGA +``` + +**NOTE** - this does not deal with dynamic access case. This is something users will need to do themselves diff --git a/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/__testfixtures__/default.input.js b/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/__testfixtures__/default.input.js new file mode 100644 index 000000000000..20072e45da94 --- /dev/null +++ b/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/__testfixtures__/default.input.js @@ -0,0 +1,10 @@ +process.env['NODE_ENV'] +process.env['ACCESS_TWO'] +process.env.ACCESS_THREE + +if (process.env['NODE_ENV'] === 'production') { + console.log('Im in production') +} + + +process.env['KITTENS'].replaceAll('claws', 'cuddles') diff --git a/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/__testfixtures__/default.output.js b/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/__testfixtures__/default.output.js new file mode 100644 index 000000000000..5b5e0b685f39 --- /dev/null +++ b/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/__testfixtures__/default.output.js @@ -0,0 +1,9 @@ +process.env.NODE_ENV +process.env.ACCESS_TWO +process.env.ACCESS_THREE + +if (process.env.NODE_ENV === 'production') { + console.log('Im in production') +} + +process.env.KITTENS.replaceAll('claws', 'cuddles') diff --git a/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/__tests__/processEnvDotNotation.test.ts b/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/__tests__/processEnvDotNotation.test.ts new file mode 100644 index 000000000000..e2a3bf99852a --- /dev/null +++ b/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/__tests__/processEnvDotNotation.test.ts @@ -0,0 +1,5 @@ +describe('processEnvDotNotation', () => { + it('Replaces array access syntax with dot notation', async () => { + await matchTransformSnapshot('processEnvDotNotation', 'default') + }) +}) diff --git a/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/processEnvDotNotation.ts b/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/processEnvDotNotation.ts new file mode 100644 index 000000000000..f9973bccd56a --- /dev/null +++ b/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/processEnvDotNotation.ts @@ -0,0 +1,30 @@ +import { FileInfo, API } from 'jscodeshift' + +export default function transform(file: FileInfo, api: API) { + const j = api.jscodeshift + const root = j(file.source) + + root + .find(j.MemberExpression, { + object: { + type: 'MemberExpression', + object: { name: 'process' }, + property: { name: 'env' }, + }, + }) + .forEach((path) => { + const envVarName = path.value.property + + // Only apply the codemod if process.env['bbb'] + // where bbb is the string literal. Otherwise it catches process.env.bbb too + if (j.StringLiteral.check(envVarName)) { + const dotNotation = j.memberExpression( + j.memberExpression(j.identifier('process'), j.identifier('env')), + j.identifier(envVarName.value) + ) + j(path).replaceWith(dotNotation) + } + }) + + return root.toSource() +} diff --git a/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/processEnvDotNotation.yargs.ts b/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/processEnvDotNotation.yargs.ts new file mode 100644 index 000000000000..e96c63111a5c --- /dev/null +++ b/packages/codemods/src/codemods/v6.x.x/processEnvDotNotation/processEnvDotNotation.yargs.ts @@ -0,0 +1,25 @@ +import path from 'path' + +import fg from 'fast-glob' +import task, { TaskInnerAPI } from 'tasuku' + +import { getPaths } from '@redwoodjs/project-config' + +import runTransform from '../../../lib/runTransform' + +export const command = 'process-env-dot-notation' +export const description = '(v6.x.x->v6.x.x) Converts world to bazinga' + +export const handler = () => { + task('Process Env Dot Notation', async ({ setOutput }: TaskInnerAPI) => { + await runTransform({ + transformPath: path.join(__dirname, 'processEnvDotNotation.js'), + targetPaths: fg.sync('**/*.{js,jsx,tsx}', { + cwd: getPaths().web.src, + absolute: true, + }), + }) + + setOutput('All done! Run `yarn rw lint --fix` to prettify your code') + }) +} diff --git a/packages/codemods/src/testUtils/matchInlineTransformSnapshot.ts b/packages/codemods/src/testUtils/matchInlineTransformSnapshot.ts index 8b71e44d5b70..a95386a5fe59 100644 --- a/packages/codemods/src/testUtils/matchInlineTransformSnapshot.ts +++ b/packages/codemods/src/testUtils/matchInlineTransformSnapshot.ts @@ -33,6 +33,9 @@ export const matchInlineTransformSnapshot = async ( await runTransform({ transformPath, targetPaths: [tempFilePath], + options: { + verbose: 1, + }, parser, }) diff --git a/packages/codemods/src/testUtils/matchTransformSnapshot.ts b/packages/codemods/src/testUtils/matchTransformSnapshot.ts index 5fb06e9ac325..f90481609182 100644 --- a/packages/codemods/src/testUtils/matchTransformSnapshot.ts +++ b/packages/codemods/src/testUtils/matchTransformSnapshot.ts @@ -43,7 +43,8 @@ export const matchTransformSnapshot: MatchTransformSnapshotFunction = async ( targetPaths: [tempFilePath], parser, options: { - verbose: true, + verbose: 1, + print: true, }, }) diff --git a/packages/codemods/tasks/generateCodemod/generateCodemod.mjs b/packages/codemods/tasks/generateCodemod/generateCodemod.mjs index 5e7a4642cb0f..e2ac106007dd 100644 --- a/packages/codemods/tasks/generateCodemod/generateCodemod.mjs +++ b/packages/codemods/tasks/generateCodemod/generateCodemod.mjs @@ -4,7 +4,8 @@ import url from 'node:url' import c from 'ansi-colors' import fse from 'fs-extra' -import { template } from 'lodash' +// lodash is commonjs +import template from 'lodash/template.js' import prompts from 'prompts' const questions = [ diff --git a/packages/codemods/tasks/generateCodemod/templates/code/codemod.yargs.ts.template b/packages/codemods/tasks/generateCodemod/templates/code/codemod.yargs.ts.template index 3a21464546f7..cef0df8d3753 100644 --- a/packages/codemods/tasks/generateCodemod/templates/code/codemod.yargs.ts.template +++ b/packages/codemods/tasks/generateCodemod/templates/code/codemod.yargs.ts.template @@ -1,5 +1,6 @@ import path from 'path' +import fg from 'fast-glob' import task, { TaskInnerAPI } from 'tasuku' import { getPaths } from '@redwoodjs/project-config' @@ -11,13 +12,16 @@ export const description = '(${version}->${version}) Converts world to bazinga' export const handler = () => { task( '${titleName}', - async ({ setOutput }: TaskInnerApi) => { + async ({ setOutput }: TaskInnerAPI) => { await runTransform({ transformPath: path.join(__dirname, '${name}.js'), // Here we know exactly which file we need to transform, but often times you won't. // If you need to transform files based on their name, location, etc, use `fast-glob`. // If you need to transform files based on their contents, use `getFilesWithPattern`. - targetPaths: [path.join(getPaths().base, 'redwood.toml')], + targetPaths: fg.sync('**/*.{js,jsx,tsx}', { + cwd: getPaths().web.src, + absolute: true, + }), }) setOutput('All done! Run `yarn rw lint --fix` to prettify your code')