11import path from 'path' ;
2+ import fs from 'fs-extra' ;
23import semver from 'semver' ;
34import chalk from 'chalk' ;
45import findUp from 'find-up' ;
56import inquirer from 'inquirer' ;
67
7- import { fetchConfigAtPath } from '@codeshift/fetcher' ;
8+ import { CodeshiftConfig } from '@codeshift/types' ;
9+ import { fetchConfigAtPath , fetchConfigs } from '@codeshift/fetcher' ;
810import { PluginManager } from 'live-plugin-manager' ;
911// @ts -ignore Run transform(s) on path https://github.com/facebook/jscodeshift/issues/398
1012import * as jscodeshift from 'jscodeshift/src/Runner' ;
1113
1214import { Flags } from './types' ;
1315import { InvalidUserInputError } from './errors' ;
1416import { fetchPackageConfig } from './fetch-package' ;
15- import { getTransformPrompt } from './prompt' ;
17+ import { getConfigPrompt , getMultiConfigPrompt } from './prompt' ;
1618
1719export default async function main ( paths : string [ ] , flags : Flags ) {
20+ if ( paths . length === 0 ) {
21+ throw new InvalidUserInputError (
22+ 'No path provided, please specify which files your codemod should modify' ,
23+ ) ;
24+ }
25+
1826 const packageManager = new PluginManager ( {
1927 pluginsPath : path . join ( __dirname , 'node_modules' ) ,
2028 } ) ;
@@ -24,47 +32,94 @@ export default async function main(paths: string[], flags: Flags) {
2432 if ( ! flags . transform && ! flags . packages ) {
2533 console . log (
2634 chalk . green (
27- 'No transforms specified, attempting to find local codeshift.config file' ,
35+ 'No transforms specified, attempting to find local codeshift.config file(s) ' ,
2836 ) ,
2937 ) ;
3038
31- const configFilePath = await findUp ( [
32- 'codeshift.config.js' ,
33- 'codeshift.config.ts' ,
34- 'codeshift.config.tsx' ,
35- 'src/codeshift.config.js' ,
36- 'src/codeshift.config.ts' ,
37- 'src/codeshift.config.tsx' ,
38- 'codemods/codeshift.config.js' ,
39- 'codemods/codeshift.config.ts' ,
40- 'codemods/codeshift.config.tsx' ,
41- ] ) ;
42-
43- if ( ! configFilePath ) {
44- throw new InvalidUserInputError (
45- 'No transform provided, please specify a transform with either the --transform or --packages flags' ,
46- ) ;
39+ /**
40+ * Attempt to locate a root package json with a workspaces config.
41+ * If found, show a prompt with all available codemods
42+ */
43+ let rootPackageJson : any ;
44+ const packageJsonPath = await findUp ( 'package.json' ) ;
45+
46+ if ( packageJsonPath ) {
47+ const packageJsonRaw = await fs . readFile ( packageJsonPath , 'utf8' ) ;
48+ rootPackageJson = JSON . parse ( packageJsonRaw ) ;
4749 }
4850
49- console . log (
50- chalk . green ( 'Found local codeshift.config file at:' ) ,
51- configFilePath ,
52- ) ;
51+ if ( rootPackageJson && rootPackageJson . workspaces ) {
52+ const configs = await ( rootPackageJson . workspaces as any [ ] ) . reduce <
53+ Promise < { filePath : string ; config : CodeshiftConfig } [ ] >
54+ > ( async ( accum , filePath ) => {
55+ const configs = await fetchConfigs ( filePath ) ;
56+ if ( ! configs . length ) return accum ;
57+ const results = await accum ;
58+ return [ ...results , ...configs ] ;
59+ } , Promise . resolve ( [ ] ) ) ;
60+
61+ const answers = await inquirer . prompt ( [ getMultiConfigPrompt ( configs ) ] ) ;
62+ const selectedConfig = configs . find (
63+ ( { filePath } ) => answers . codemod . filePath === filePath ,
64+ ) ;
5365
54- const config = await fetchConfigAtPath ( configFilePath ) ;
55- const answers = await inquirer . prompt ( [ getTransformPrompt ( config ) ] ) ;
66+ if ( ! selectedConfig ) {
67+ throw new Error (
68+ `Unable to locate config at: ${ answers . codemod . filePath } ` ,
69+ ) ;
70+ }
5671
57- if ( config . transforms && config . transforms [ answers . transform ] ) {
58- transforms . push ( config . transforms [ answers . transform ] ) ;
59- } else if ( config . presets && config . presets [ answers . transform ] ) {
60- transforms . push ( config . presets [ answers . transform ] ) ;
61- }
62- }
72+ if (
73+ selectedConfig . config . transforms &&
74+ selectedConfig . config . transforms [ answers . codemod . selection ]
75+ ) {
76+ transforms . push (
77+ selectedConfig . config . transforms [ answers . codemod . selection ] ,
78+ ) ;
79+ } else if (
80+ selectedConfig . config . presets &&
81+ selectedConfig . config . presets [ answers . codemod . selection ]
82+ ) {
83+ transforms . push (
84+ selectedConfig . config . presets [ answers . codemod . selection ] ,
85+ ) ;
86+ }
87+ } else {
88+ /**
89+ * Otherwise, locate any config files in parent directories
90+ */
91+ const configFilePath = await findUp ( [
92+ 'codeshift.config.js' ,
93+ 'codeshift.config.ts' ,
94+ 'codeshift.config.tsx' ,
95+ 'src/codeshift.config.js' ,
96+ 'src/codeshift.config.ts' ,
97+ 'src/codeshift.config.tsx' ,
98+ 'codemods/codeshift.config.js' ,
99+ 'codemods/codeshift.config.ts' ,
100+ 'codemods/codeshift.config.tsx' ,
101+ ] ) ;
102+
103+ if ( ! configFilePath ) {
104+ throw new InvalidUserInputError (
105+ 'No transform provided, please specify a transform with either the --transform or --packages flags' ,
106+ ) ;
107+ }
63108
64- if ( paths . length === 0 ) {
65- throw new InvalidUserInputError (
66- 'No path provided, please specify which files your codemod should modify' ,
67- ) ;
109+ console . log (
110+ chalk . green ( 'Found local codeshift.config file at:' ) ,
111+ configFilePath ,
112+ ) ;
113+
114+ const config = await fetchConfigAtPath ( configFilePath ) ;
115+ const answers = await inquirer . prompt ( [ getConfigPrompt ( config ) ] ) ;
116+
117+ if ( config . transforms && config . transforms [ answers . codemod ] ) {
118+ transforms . push ( config . transforms [ answers . codemod ] ) ;
119+ } else if ( config . presets && config . presets [ answers . codemod ] ) {
120+ transforms . push ( config . presets [ answers . codemod ] ) ;
121+ }
122+ }
68123 }
69124
70125 if ( flags . transform ) {
@@ -125,7 +180,7 @@ export default async function main(paths: string[], flags: Flags) {
125180 } ) ;
126181
127182 if ( presetIds . length === 0 && transformIds . length === 0 ) {
128- const res = await inquirer . prompt ( [ getTransformPrompt ( config ) ] ) ;
183+ const res = await inquirer . prompt ( [ getConfigPrompt ( config ) ] ) ;
129184
130185 if ( semver . valid ( semver . coerce ( res . transform ) ) ) {
131186 transformIds . push ( res . transform ) ;
0 commit comments