1
1
import path from 'path' ;
2
+ import fs from 'fs-extra' ;
2
3
import semver from 'semver' ;
3
4
import chalk from 'chalk' ;
4
5
import findUp from 'find-up' ;
5
6
import inquirer from 'inquirer' ;
6
7
7
- import { fetchConfigAtPath } from '@codeshift/fetcher' ;
8
+ import { CodeshiftConfig } from '@codeshift/types' ;
9
+ import { fetchConfigAtPath , fetchConfigs } from '@codeshift/fetcher' ;
8
10
import { PluginManager } from 'live-plugin-manager' ;
9
11
// @ts -ignore Run transform(s) on path https://github.com/facebook/jscodeshift/issues/398
10
12
import * as jscodeshift from 'jscodeshift/src/Runner' ;
11
13
12
14
import { Flags } from './types' ;
13
15
import { InvalidUserInputError } from './errors' ;
14
16
import { fetchPackageConfig } from './fetch-package' ;
15
- import { getTransformPrompt } from './prompt' ;
17
+ import { getConfigPrompt , getMultiConfigPrompt } from './prompt' ;
16
18
17
19
export 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
+
18
26
const packageManager = new PluginManager ( {
19
27
pluginsPath : path . join ( __dirname , 'node_modules' ) ,
20
28
} ) ;
@@ -24,47 +32,94 @@ export default async function main(paths: string[], flags: Flags) {
24
32
if ( ! flags . transform && ! flags . packages ) {
25
33
console . log (
26
34
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) ' ,
28
36
) ,
29
37
) ;
30
38
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 ) ;
47
49
}
48
50
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
+ ) ;
53
65
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
+ }
56
71
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
+ }
63
108
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
+ }
68
123
}
69
124
70
125
if ( flags . transform ) {
@@ -125,7 +180,7 @@ export default async function main(paths: string[], flags: Flags) {
125
180
} ) ;
126
181
127
182
if ( presetIds . length === 0 && transformIds . length === 0 ) {
128
- const res = await inquirer . prompt ( [ getTransformPrompt ( config ) ] ) ;
183
+ const res = await inquirer . prompt ( [ getConfigPrompt ( config ) ] ) ;
129
184
130
185
if ( semver . valid ( semver . coerce ( res . transform ) ) ) {
131
186
transformIds . push ( res . transform ) ;
0 commit comments