@@ -4,6 +4,7 @@ import * as path from 'path';
44import * as meow from 'meow' ;
55import { init } from './init' ;
66import { clean } from './clean' ;
7+ import { migrate } from './migrate' ;
78import { isYarnUsed , readJSON } from './util' ;
89import * as execa from 'execa' ;
910import { PackageJSON as PackageJson } from '@npm/types' ;
@@ -51,6 +52,7 @@ const cli = meow({
5152 check Alias for lint. Kept for backward compatibility.
5253 fix Fixes formatting and linting issues (if possible).
5354 clean Removes all files generated by the build.
55+ migrate Migrates legacy mwts/eslintrc setup to flat config.
5456
5557 Options
5658 --help Prints this help message.
@@ -65,6 +67,7 @@ const cli = meow({
6567 $ mwts lint
6668 $ mwts fix
6769 $ mwts fix src/file1.ts src/file2.ts
70+ $ mwts migrate
6871 $ mwts clean` ,
6972 flags : {
7073 help : { type : 'boolean' } ,
@@ -124,12 +127,27 @@ function usage(msg?: string): void {
124127 cli . showHelp ( 1 ) ;
125128}
126129
127- function hasLocalEslintConfig ( targetRootDir : string ) : boolean {
128- return (
129- fs . existsSync ( path . join ( targetRootDir , 'eslint.config.js' ) ) ||
130- fs . existsSync ( path . join ( targetRootDir , 'eslint.config.cjs' ) ) ||
131- fs . existsSync ( path . join ( targetRootDir , 'eslint.config.mjs' ) )
132- ) ;
130+ function findNearestEslintConfig ( targetRootDir : string ) : string | undefined {
131+ const configNames = [
132+ 'eslint.config.js' ,
133+ 'eslint.config.cjs' ,
134+ 'eslint.config.mjs' ,
135+ ] ;
136+ let currentDir = path . resolve ( targetRootDir ) ;
137+ while ( true ) {
138+ for ( const configName of configNames ) {
139+ const configPath = path . join ( currentDir , configName ) ;
140+ if ( fs . existsSync ( configPath ) ) {
141+ return configPath ;
142+ }
143+ }
144+
145+ const parentDir = path . dirname ( currentDir ) ;
146+ if ( parentDir === currentDir ) {
147+ return undefined ;
148+ }
149+ currentDir = parentDir ;
150+ }
133151}
134152
135153export async function run ( verb : string , files : string [ ] ) : Promise < boolean > {
@@ -179,11 +197,11 @@ export async function run(verb: string, files: string[]): Promise<boolean> {
179197 case 'lint' :
180198 case 'check' : {
181199 const eslintFlags = [ ...flags ] ;
182- if ( ! hasLocalEslintConfig ( options . targetRootDir ) ) {
183- eslintFlags . unshift (
184- '-- config' ,
185- path . join ( options . mwtsRootDir , 'eslint.config.js' )
186- ) ;
200+ const resolvedEslintConfig =
201+ findNearestEslintConfig ( options . targetRootDir ) ||
202+ path . join ( options . mwtsRootDir , 'eslint. config.js' ) ;
203+ if ( resolvedEslintConfig ) {
204+ eslintFlags . unshift ( '--config' , resolvedEslintConfig ) ;
187205 }
188206 try {
189207 await execa ( 'eslint' , eslintFlags , {
@@ -210,11 +228,11 @@ export async function run(verb: string, files: string[]): Promise<boolean> {
210228 }
211229 const fixFlag = options . dryRun ? '--fix-dry-run' : '--fix' ;
212230 const eslintFlags = [ fixFlag , ...flags ] ;
213- if ( ! hasLocalEslintConfig ( options . targetRootDir ) ) {
214- eslintFlags . unshift (
215- '-- config' ,
216- path . join ( options . mwtsRootDir , 'eslint.config.js' )
217- ) ;
231+ const resolvedEslintConfig =
232+ findNearestEslintConfig ( options . targetRootDir ) ||
233+ path . join ( options . mwtsRootDir , 'eslint. config.js' ) ;
234+ if ( resolvedEslintConfig ) {
235+ eslintFlags . unshift ( '--config' , resolvedEslintConfig ) ;
218236 }
219237 try {
220238 await execa ( 'eslint' , eslintFlags , {
@@ -228,6 +246,8 @@ export async function run(verb: string, files: string[]): Promise<boolean> {
228246 }
229247 case 'clean' :
230248 return clean ( options ) ;
249+ case 'migrate' :
250+ return migrate ( options ) ;
231251 default :
232252 usage ( `Unknown verb: ${ verb } ` ) ;
233253 return false ;
0 commit comments