lib/cli.js
function execute(programArgs) {

    let userConfig = {}, ignore, errorReporter;

    createCliOptions(cli);
    programArgs.length === 2 ? cli.help() : cli.parse(programArgs);

    if (cli.init) {
        return setupDefaultUserConfig();
    }

    try {
        errorReporter = getErrorReporter(cli.reporter);
    } catch (e) {
        process.stderr.write(`[Fatal error] ${e.message}${EOL}`);
        process.exit(errorCodes.INVALID_PARAMS);
    }

    if (cli.soliumrc) {
        /**
         * If cli.config option is NOT specified, then resort to .soliumrc in current dir.
         * Else,
         *   If path is absolute, assign as-it-is.
         *   Else (relative pathing) join path with current dir.
         */
        const soliumrcAbsPath = cli.config ?
            (path.isAbsolute(cli.config) ? cli.config : path.join(CWD, cli.config)) :
            SOLIUMRC_FILENAME_ABSOLUTE;

        try {
            userConfig = require(soliumrcAbsPath);
        } catch (e) {
            // Check if soliumrc file exists. If yes, then the file is in an invalid format.
            if (fs.existsSync(soliumrcAbsPath)) {
                errorReporter.reportFatal(`An invalid ${SOLIUMRC_FILENAME} was provided. ${e.message}`);
            } else {
                if (cli.config) {
                    errorReporter.reportFatal(`${soliumrcAbsPath} does not exist.`);
                } else {
                    errorReporter.reportFatal(`Couldn't find ${SOLIUMRC_FILENAME} in the current directory.`);
                }
            }

            process.exit(errorCodes.NO_SOLIUMRC);
        }
    }

    //if custom rules' file is set, make sure we have its absolute path
    if (
        userConfig ["custom-rules-filename"] &&
        !path.isAbsolute(userConfig ["custom-rules-filename"])
    ) {
        userConfig ["custom-rules-filename"] = path.join(
            CWD, userConfig ["custom-rules-filename"]
        );
    }

    // Pass cli arguments that modify the behaviour of upstream functions.
    userConfig.options = {
        autofix: Boolean(cli.fix),
        autofixDryrun: Boolean(cli.fixDryRun),
        debug: Boolean(cli.debug)
    };

    if (userConfig.options.autofixDryrun) {
        if (userConfig.options.autofix) {
            return errorReporter.reportFatal("Cannot use both --fix and --fix-dry-run");
        }
        if (cli.reporter != "pretty") {
            return errorReporter.reportFatal("Option --fix-dry-run is only supported with pretty reporter");
        }
    }

    userConfig.plugins = userConfig.plugins || [];
    userConfig.rules = userConfig.rules || {};

    for (const plugin of cli.plugin) {
        userConfig.plugins.push(plugin);
    }

    for (const rule of cli.rule) {
        // If no ":" was found, it means only the rule's name was specified.
        // Treat it as an error and adopt its default configuration options.
        if (!rule.includes(":")) {
            userConfig.rules[rule] = "error";
            continue;
        }

        let [key, value] = rule.split(":").map(i => i.trim());
        try {
            value = JSON.parse(value);
        } catch (e) {
            errorReporter.reportFatal(`There was an error trying to parse '${rule}': ${e.message}`);
            process.exit(errorCodes.INVALID_PARAMS);
        }
        userConfig.rules[key] = value;
    }

    //get all files & folders to ignore from .soliumignore
    if (cli.soliumignore) {
        try {
            ignore = fs.readFileSync(SOLIUMIGNORE_FILENAME_ABSOLUTE, "utf8").split(EOL);
        } catch (e) {
            if (e.code === "ENOENT") {
                errorReporter.reportInternal(
                    "No '.soliumignore' found. Use --no-soliumignore to make this warning go away.");
            } else {
                errorReporter.reportInternal(`Failed to read '.soliumignore': ${e.message}`);
            }
        }
    }

    if (cli.hot) {
        // --hot is equivalent to --watch in functionality, is a legacy option
        cli.watch = true;
    }

    if (cli.watch) {
        if (cli.stdin) {
            return errorReporter.reportFatal("Cannot watch files when reading from stdin");
        }

        if (cli.fix) {
            return errorReporter.reportFatal("Automatic code formatting is not supported in watch mode.");
        }
    }

    let errorCount = lint(userConfig, { file: cli.file, dir: cli.dir, stdin: cli.stdin }, ignore, errorReporter);

    if (cli.watch) {

        let spy = chokidar.watch(CWD);

        spy.on("change", function() {
            console.log("\x1Bc"); // clear the console
            console.log(`File change detected. Start linting.${EOL}`);
            lint(userConfig, { file: cli.file, dir: cli.dir }, ignore, errorReporter);	//lint on subsequent changes (hot)
            console.log(`Linting complete. Watching for file changes.${EOL}`);
        });

    } else if (errorCount > 0) {
        process.exit(errorCodes.ERRORS_FOUND);
    }
}
function execute(programArgs) {

    let userConfig = {}, ignore, errorReporter;

    createCliOptions(cli);
    programArgs.length === 2 ? cli.help() : cli.parse(programArgs);

    if (cli.init) {
        return setupDefaultUserConfig();
    }

    try {
        errorReporter = getErrorReporter(cli.reporter);
    } catch (e) {
        process.stderr.write(`[Fatal error] ${e.message}${EOL}`);
        process.exit(errorCodes.INVALID_PARAMS);
    }

    if (cli.soliumrc) {
        /**
         * If cli.config option is NOT specified, then resort to .soliumrc in current dir.
         * Else,
         *   If path is absolute, assign as-it-is.
         *   Else (relative pathing) join path with current dir.
         */
        const soliumrcAbsPath = cli.config ?
            (path.isAbsolute(cli.config) ? cli.config : path.join(CWD, cli.config)) :
            SOLIUMRC_FILENAME_ABSOLUTE;

        try {
            userConfig = require(soliumrcAbsPath);
        } catch (e) {
            // Check if soliumrc file exists. If yes, then the file is in an invalid format.
            if (fs.existsSync(soliumrcAbsPath)) {
                errorReporter.reportFatal(`An invalid ${SOLIUMRC_FILENAME} was provided. ${e.message}`);
            } else {
                if (cli.config) {
                    errorReporter.reportFatal(`${soliumrcAbsPath} does not exist.`);
                } else {
                    errorReporter.reportFatal(`Couldn't find ${SOLIUMRC_FILENAME} in the current directory.`);
                }
            }

            process.exit(errorCodes.NO_SOLIUMRC);
        }
    }

    //if custom rules' file is set, make sure we have its absolute path
    if (
        userConfig ["custom-rules-filename"] &&
        !path.isAbsolute(userConfig ["custom-rules-filename"])
    ) {
        userConfig ["custom-rules-filename"] = path.join(
            CWD, userConfig ["custom-rules-filename"]
        );
    }

    // Pass cli arguments that modify the behaviour of upstream functions.
    userConfig.options = {
        autofix: Boolean(cli.fix),
        autofixDryrun: Boolean(cli.fixDryRun),
        debug: Boolean(cli.debug)
    };

    if (userConfig.options.autofixDryrun) {
        if (userConfig.options.autofix) {
            return errorReporter.reportFatal("Cannot use both --fix and --fix-dry-run");
        }
        if (cli.reporter != "pretty") {
            return errorReporter.reportFatal("Option --fix-dry-run is only supported with pretty reporter");
        }
    }

    userConfig.plugins = userConfig.plugins || [];
    userConfig.rules = userConfig.rules || {};

    for (const plugin of cli.plugin) {
        userConfig.plugins.push(plugin);
    }

    for (const rule of cli.rule) {
        // If no ":" was found, it means only the rule's name was specified.
        // Treat it as an error and adopt its default configuration options.
        if (!rule.includes(":")) {
            userConfig.rules[rule] = "error";
            continue;
        }

        let [key, value] = rule.split(":").map(i => i.trim());
        try {
            value = JSON.parse(value);
        } catch (e) {
            errorReporter.reportFatal(`There was an error trying to parse '${rule}': ${e.message}`);
            process.exit(errorCodes.INVALID_PARAMS);
        }
        userConfig.rules[key] = value;
    }

    //get all files & folders to ignore from .soliumignore
    if (cli.soliumignore) {
        try {
            ignore = fs.readFileSync(SOLIUMIGNORE_FILENAME_ABSOLUTE, "utf8").split(EOL);
        } catch (e) {
            if (e.code === "ENOENT") {
                errorReporter.reportInternal(
                    "No '.soliumignore' found. Use --no-soliumignore to make this warning go away.");
            } else {
                errorReporter.reportInternal(`Failed to read '.soliumignore': ${e.message}`);
            }
        }
    }

    if (cli.hot) {
        // --hot is equivalent to --watch in functionality, is a legacy option
        cli.watch = true;
    }

    if (cli.watch) {
        if (cli.stdin) {
            return errorReporter.reportFatal("Cannot watch files when reading from stdin");
        }

        if (cli.fix) {
            return errorReporter.reportFatal("Automatic code formatting is not supported in watch mode.");
        }
    }

    let errorCount = lint(userConfig, { file: cli.file, dir: cli.dir, stdin: cli.stdin }, ignore, errorReporter);

    if (cli.watch) {

        let spy = chokidar.watch(CWD);

        spy.on("change", function() {
            console.log("\x1Bc"); // clear the console
            console.log(`File change detected. Start linting.${EOL}`);
            lint(userConfig, { file: cli.file, dir: cli.dir }, ignore, errorReporter);	//lint on subsequent changes (hot)
            console.log(`Linting complete. Watching for file changes.${EOL}`);
        });

    } else if (errorCount > 0) {
        process.exit(errorCodes.ERRORS_FOUND);
    }
}
function execute ( programArgs ) { let userConfig = { } , ignore , errorReporter ; createCliOptions ( cli ) ; programArgs . length === 2 ? cli . help ( ) : cli . parse ( programArgs ) ; if ( cli . init ) { return setupDefaultUserConfig ( ) ; } try { errorReporter = getErrorReporter ( cli . reporter ) ; } catch ( e ) { process . stderr . write ( ` ${ e . message } ${ EOL } ` ) ; process . exit ( errorCodes . INVALID_PARAMS ) ; } if ( cli . soliumrc ) { /**
         * If cli.config option is NOT specified, then resort to .soliumrc in current dir.
         * Else,
         *   If path is absolute, assign as-it-is.
         *   Else (relative pathing) join path with current dir.
         */ const soliumrcAbsPath = cli . config ? ( path . isAbsolute ( cli . config ) ? cli . config : path . join ( CWD , cli . config ) ) : SOLIUMRC_FILENAME_ABSOLUTE ; try { userConfig = require ( soliumrcAbsPath ) ; } catch ( e ) { // Check if soliumrc file exists. If yes, then the file is in an invalid format. if ( fs . existsSync ( soliumrcAbsPath ) ) { errorReporter . reportFatal ( ` ${ SOLIUMRC_FILENAME } ${ e . message } ` ) ; } else { if ( cli . config ) { errorReporter . reportFatal ( ` ${ soliumrcAbsPath } ` ) ; } else { errorReporter . reportFatal ( ` ${ SOLIUMRC_FILENAME } ` ) ; } } process . exit ( errorCodes . NO_SOLIUMRC ) ; } } //if custom rules' file is set, make sure we have its absolute path if ( userConfig [ "custom-rules-filename" ] && ! path . isAbsolute ( userConfig [ "custom-rules-filename" ] ) ) { userConfig [ "custom-rules-filename" ] = path . join ( CWD , userConfig [ "custom-rules-filename" ] ) ; } // Pass cli arguments that modify the behaviour of upstream functions. userConfig . options = { autofix : Boolean ( cli . fix ) , autofixDryrun : Boolean ( cli . fixDryRun ) , debug : Boolean ( cli . debug ) } ; if ( userConfig . options . autofixDryrun ) { if ( userConfig . options . autofix ) { return errorReporter . reportFatal ( "Cannot use both --fix and --fix-dry-run" ) ; } if ( cli . reporter != "pretty" ) { return errorReporter . reportFatal ( "Option --fix-dry-run is only supported with pretty reporter" ) ; } } userConfig . plugins = userConfig . plugins || [ ] ; userConfig . rules = userConfig . rules || { } ; for ( const plugin of cli . plugin ) { userConfig . plugins . push ( plugin ) ; } for ( const rule of cli . rule ) { // If no ":" was found, it means only the rule's name was specified. // Treat it as an error and adopt its default configuration options. if ( ! rule . includes ( ":" ) ) { userConfig . rules [ rule ] = "error" ; continue ; } let [ key , value ] = rule . split ( ":" ) . map ( i => i . trim ( ) ) ; try { value = JSON . parse ( value ) ; } catch ( e ) { errorReporter . reportFatal ( ` ${ rule } ${ e . message } ` ) ; process . exit ( errorCodes . INVALID_PARAMS ) ; } userConfig . rules [ key ] = value ; } //get all files & folders to ignore from .soliumignore if ( cli . soliumignore ) { try { ignore = fs . readFileSync ( SOLIUMIGNORE_FILENAME_ABSOLUTE , "utf8" ) . split ( EOL ) ; } catch ( e ) { if ( e . code === "ENOENT" ) { errorReporter . reportInternal ( "No '.soliumignore' found. Use --no-soliumignore to make this warning go away." ) ; } else { errorReporter . reportInternal ( ` ${ e . message } ` ) ; } } } if ( cli . hot ) { // --hot is equivalent to --watch in functionality, is a legacy option cli . watch = true ; } if ( cli . watch ) { if ( cli . stdin ) { return errorReporter . reportFatal ( "Cannot watch files when reading from stdin" ) ; } if ( cli . fix ) { return errorReporter . reportFatal ( "Automatic code formatting is not supported in watch mode." ) ; } } let errorCount = lint ( userConfig , { file : cli . file , dir : cli . dir , stdin : cli . stdin } , ignore , errorReporter ) ; if ( cli . watch ) { let spy = chokidar . watch ( CWD ) ; spy . on ( "change" , function ( ) { console . log ( "\x1Bc" ) ; // clear the console console . log ( ` ${ EOL } ` ) ; lint ( userConfig , { file : cli . file , dir : cli . dir } , ignore , errorReporter ) ; //lint on subsequent changes (hot) console . log ( ` ${ EOL } ` ) ; } ) ; } else if ( errorCount > 0 ) { process . exit ( errorCodes . ERRORS_FOUND ) ; } }
Entry point to the CLI reponsible for initiating linting process based on command-line arguments
@param {Array} programArgs Commandline arguments
Entry point to the CLI reponsible for initiating linting process based on command - line arguments