Skip to content

Commit

Permalink
feat: add init command, find-only cli output
Browse files Browse the repository at this point in the history
  • Loading branch information
jedwards1211 committed Apr 10, 2021
1 parent 3d37817 commit 2f43744
Show file tree
Hide file tree
Showing 6 changed files with 322 additions and 148 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
"babel-parse-wild-code": "^1.1.1",
"chalk": "^4.1.0",
"debug": "^4.3.1",
"dedent-js": "^1.0.1",
"diff": "^5.0.0",
"fs-extra": "^9.0.1",
"glob-gitignore": "^1.0.14",
Expand Down
139 changes: 3 additions & 136 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,141 +2,8 @@

/* eslint-disable no-console */

import chalk from 'chalk'
import path from 'path'
import fs from 'fs-extra'
import yargs from 'yargs'
import inquirer from 'inquirer'
import isEmpty from 'lodash/isEmpty'
import runTransform from '../runTransform'
import { Transform } from '../runTransformOnFile'
import formatDiff from '../util/formatDiff'
import transform from './transform'
import init from './init'

const argv = yargs
.option('transform', {
alias: 't',
describe: 'path to the transform file. Can be either a local path or url',
})
.options('parser', {
describe: 'parser to use',
type: 'string',
})
.option('find', {
alias: 'f',
describe: 'search pattern',
type: 'string',
})
.option('replace', {
alias: 'r',
describe: 'replace pattern',
type: 'string',
}).usage(`Usage:
$0 -f <code> -r <code> [<files...>] [<directories...>]
Quick search and replace in the given files and directories
(make sure to quote code)
Example:
astx -f 'rmdir($path, $force)' -r 'rmdir($path, { force: $force })' src
$0 -t <transformFile> [<files ...>] [<directories ...>]
Applies a transform file to the given files and directories
$0 [<files ...>] [<directories ...>]
Applies the default transform file (astx.js in working directory)
to the given files and directories
`).argv

const paths = argv._.filter((x) => typeof x === 'string') as string[]
if (!paths.length) {
yargs.showHelp()
process.exit(1)
}

function getTransform(): Transform {
const { transform, find, replace, parser }: any = argv
// eslint-disable-next-line @typescript-eslint/no-var-requires
if (transform) return require(path.resolve(transform))
if (find && replace) {
const getOpt = (regex: RegExp): string | undefined => {
const index = process.argv.findIndex((a) => regex.test(a))
return index >= 0 ? process.argv[index + 1] : undefined
}
// yargs Eats quotes, not cool...
const find = getOpt(/^(-f|--find)$/)
const replace = getOpt(/^(-r|--replace)$/)
return { find, replace, parser }
}
// eslint-disable-next-line @typescript-eslint/no-var-requires
return require(path.resolve('./astx.js'))
}

const transform: Transform = getTransform()

async function go() {
const results: Record<string, string> = {}
for await (const {
file,
source,
transformed,
reports,
error,
} of runTransform(transform, {
paths,
})) {
if (error) {
console.error(
chalk.blue(`
==========================================
${file}
==========================================
`)
)
console.error(chalk.red(error.stack))
} else if (source && transformed && source !== transformed) {
results[file] = transformed
console.error(
chalk.blue(`
==========================================
${file}
==========================================
`)
)
console.log(formatDiff(source, transformed))
} else {
console.error(chalk.yellow(`no changes: ${file}`))
}

if (reports?.length) {
console.error(chalk.blue`
Reports
-------
`)
reports?.forEach((r) => console.error(...r))
}
}

if (!isEmpty(results)) {
const { apply } = await inquirer.prompt([
{
type: 'confirm',
name: 'apply',
message: 'Apply changes',
default: false,
},
])
if (apply) {
for (const file in results) {
await fs.writeFile(file, results[file], 'utf8')
console.error(`Wrote ${file}`)
}
}
if (process.send) process.send({ exit: 0 })
}
}

go()
yargs.command(transform).command(init).argv
72 changes: 72 additions & 0 deletions src/cli/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Arguments, Argv, CommandModule } from 'yargs'
import fs from 'fs-extra'
import dedent from 'dedent-js'
import inquirer from 'inquirer'

/* eslint-disable no-console */

type Options = {
file?: string
style?: string
}

const init: CommandModule<Options> = {
command: 'init [file]',
describe: 'create a transform file',
builder: (yargs: Argv<Options>) =>
yargs
.positional('file', {
describe: `name of the transform file to create`,
type: 'string',
default: 'astx.js',
})
.option('style', {
alias: 's',
type: 'string',
choices: ['find-replace', 'function'],
}),
handler: async ({
file = 'astx.js',
style,
}: Arguments<Options>): Promise<void> => {
if (await fs.pathExists(file)) {
console.error(
`Path already exists: ${/^[./]/.test(file) ? file : './' + file}`
)
process.exit(1)
}
if (!style) {
;({ style } = await inquirer.prompt([
{
name: 'style',
type: 'list',
choices: ['find-replace', 'function'],
},
]))
}
const content =
style === 'function'
? dedent`
exports.astx = ({ astx, j, root, expression, statement, statements }) => {
// example: astx.find\`$foo\`.replace\`$foo\`
}
`
: dedent`
exports.find = \`
\`
exports.where = {
}
exports.replace = \`
\`
`
await fs.writeFile(file, content, 'utf8')
console.error(`Wrote ${/^[./]/.test(file) ? file : './' + file}`)
},
}

export default init
Loading

0 comments on commit 2f43744

Please sign in to comment.