diff --git a/README.md b/README.md index fe3052c..cebffa6 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,14 @@ index.js es-check [files...] ``` +**Loose Glob Matching** + +```sh + +--loose-glob-match allows for loose glob matching, default false + +``` + ⚠️ **NOTE:** This is primarily intended as a way to override the `files` setting in the `.escheckrc` file for specific invocations. Setting both the `[...files]` argument and `--files` flag is an error. ### Global Options diff --git a/index.js b/index.js index e5bda6e..2a651e5 100755 --- a/index.js +++ b/index.js @@ -25,28 +25,30 @@ program .version(pkg.version) .argument( '[ecmaVersion]', - 'ecmaVersion to check files against. Can be: es3, es4, es5, es6/es2015, es7/es2016, es8/es2017, es9/es2018, es10/es2019, es11/es2020, es12/es2021, es2022, es2023', + 'ecmaVersion to check files against. Can be: es3, es4, es5, es6/es2015, es7/es2016, es8/es2017, es9/es2018, es10/es2019, es11/es2020, es12/es2021, es13/es2022, es14/es2023', ) .argument('[files...]', 'a glob of files to to test the EcmaScript version against') .option('--module', 'use ES modules') - .option('--allow-hash-bang', 'if the code starts with #! treat it as a comment') + .option('--allow-hash-bang', '--allowHashBang', 'if the code starts with #! treat it as a comment', false) .option('--files ', 'a glob of files to to test the EcmaScript version against (alias for [files...])') .option('--not ', 'folder or file names to skip') - .option('--no-color', 'disable use of colors in output') - .option('-v, --verbose', 'verbose mode: will also output debug messages') - .option('--quiet', 'quiet mode: only displays warn and error messages') + .option('--no-color', '--noColor', 'disable use of colors in output', false) + .option('-v, --verbose', 'verbose mode: will also output debug messages', false) + .option('--quiet', 'quiet mode: only displays warn and error messages', false) + .option('--looseGlobMatching', 'doesn\'t fail if no files are found in some globs/files', false) .option( '--silent', 'silent mode: does not output anything, giving no indication of success or failure other than the exit code', ) .action((ecmaVersionArg, filesArg, options) => { + const noColor = options?.noColor || options?.['no-color'] || false; const logger = winston.createLogger() logger.add( new winston.transports.Console({ silent: options.silent, level: options.verbose ? 'silly' : options.quiet ? 'warn' : 'info', format: winston.format.combine( - ...(supportsColor.stdout ? [winston.format.colorize()] : []), + ...(supportsColor.stdout || !noColor ? [winston.format.colorize()] : []), winston.format.simple(), ), }), @@ -70,8 +72,9 @@ program const files = filesArg && filesArg.length ? filesArg : options.files ? options.files.split(',') : [].concat(config.files) const esmodule = options.module ? options.module : config.module - const allowHashBang = options.allowHashBang ? options.allowHashBang : config.allowHashBang + const allowHashBang = options.allowHashBang || options['allow-hash-bang'] || config.allowHashBang const pathsToIgnore = options.not ? options.not.split(',') : [].concat(config.not || []) + const looseGlobMatching = options.looseGlobMatching || options?.['loose-glob-matching'] || config.looseGlobMatching || false if (!expectedEcmaVersion) { logger.error( @@ -85,6 +88,26 @@ program process.exit(1) } + if (looseGlobMatching) { + logger.debug('ES-Check: loose-glob-matching is set') + } + + const globOpts = { nodir: true } + let allMatchedFiles = [] + files.forEach((pattern) => { + const globbedFiles = glob.sync(pattern, globOpts); + if (globbedFiles.length === 0 && !looseGlobMatching) { + logger.error(`ES-Check: Did not find any files to check for ${pattern}.`) + process.exit(1) + } + allMatchedFiles = allMatchedFiles.concat(globbedFiles); + }, []); + + if (allMatchedFiles.length === 0) { + logger.error(`ES-Check: Did not find any files to check for ${files}.`) + process.exit(1) + } + /** * @note define ecmaScript version */ @@ -100,50 +123,38 @@ program ecmaVersion = '5' break case 'es6': - ecmaVersion = '6' - break - case 'es7': - ecmaVersion = '7' - break - case 'es8': - ecmaVersion = '8' - break - case 'es9': - ecmaVersion = '9' - break - case 'es10': - ecmaVersion = '10' - break - case 'es11': - ecmaVersion = '11' - break - case 'es12': - ecmaVersion = '12' - break case 'es2015': ecmaVersion = '6' break + case 'es7': case 'es2016': ecmaVersion = '7' break + case 'es8': case 'es2017': ecmaVersion = '8' break + case 'es9': case 'es2018': ecmaVersion = '9' break + case 'es10': case 'es2019': ecmaVersion = '10' break + case 'es11': case 'es2020': ecmaVersion = '2020' break + case 'es12': case 'es2021': ecmaVersion = '2021' break + case 'es13': case 'es2022': ecmaVersion = '2022' break + case 'es14': case 'es2023': ecmaVersion = '2023' break @@ -153,9 +164,20 @@ program } const errArray = [] - const globOpts = { nodir: true } const acornOpts = { ecmaVersion: parseInt(ecmaVersion, 10), silent: true } + logger.debug(`ES-Check: Going to check files using version ${ecmaVersion}`) + + if (esmodule) { + acornOpts.sourceType = 'module' + logger.debug('ES-Check: esmodule is set') + } + + if (allowHashBang) { + acornOpts.allowHashBang = true + logger.debug('ES-Check: allowHashBang is set') + } + const expandedPathsToIgnore = pathsToIgnore.reduce((result, path) => { if (path.includes('*')) { return result.concat(glob.sync(path, globOpts)) @@ -174,43 +196,22 @@ program return globbedFiles } - logger.debug(`ES-Check: Going to check files using version ${ecmaVersion}`) - - if (esmodule) { - acornOpts.sourceType = 'module' - logger.debug('ES-Check: esmodule is set') - } - - if (allowHashBang) { - acornOpts.allowHashBang = true - logger.debug('ES-Check: allowHashBang is set') - } - - files.forEach((pattern) => { - const globbedFiles = glob.sync(pattern, globOpts) - - if (globbedFiles.length === 0) { - logger.error(`ES-Check: Did not find any files to check for ${pattern}.`) - process.exit(1) - } - - const filteredFiles = filterForIgnore(globbedFiles) - - filteredFiles.forEach((file) => { - const code = fs.readFileSync(file, 'utf8') - logger.debug(`ES-Check: checking ${file}`) - try { - acorn.parse(code, acornOpts) - } catch (err) { - logger.debug(`ES-Check: failed to parse file: ${file} \n - error: ${err}`) - const errorObj = { - err, - stack: err.stack, - file, - } - errArray.push(errorObj) + const filteredFiles = filterForIgnore(allMatchedFiles) + + filteredFiles.forEach((file) => { + const code = fs.readFileSync(file, 'utf8') + logger.debug(`ES-Check: checking ${file}`) + try { + acorn.parse(code, acornOpts) + } catch (err) { + logger.debug(`ES-Check: failed to parse file: ${file} \n - error: ${err}`) + const errorObj = { + err, + stack: err.stack, + file, } - }) + errArray.push(errorObj) + } }) if (errArray.length > 0) {