SimenB/stylint

View on GitHub
docs/utils_setConfig.js.html

Summary

Maintainability
Test Coverage
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: utils/setConfig.js</title>

    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">

    <h1 class="page-title">Source: utils/setConfig.js</h1>






    <section>
        <article>
            <pre class="prettyprint source linenums"><code>'use strict'

var fs = require( 'fs' )
var path = require( 'path' )
var userHome = require( 'user-home' )
var stripJsonComments = require( 'strip-json-comments' )
var Glob = require( 'glob' ).Glob

// @TODO i just this sloppy just to fix some stuff
// comes back and refactor / cleanup

/**
 * @description overrides default config with a new config object
 *              many potential code paths here.
 * 1: user passed in config object via function param
 * 2: user passes location of .stylintrc file to use via cli
 * 3: user has options obj in package.json or path to
 * 4: none of the above, fallback to initial config
 * 5: user has a .stylintrc file in a dir but doesnt pass anything
 * @param {String} [configpath] If defined, the path to a config-file to read
 * @returns {Function} kick off linter again
*/
var setConfig = function( configpath ) {
    var files = []
    var customPath = ''
    // return default config if nothing passed in or found
    var returnConfig
    var cwd = process.cwd()
    var pkg = null
    try {
        pkg = require( cwd + '/package.json' )
    }
    catch ( err ) {
        // no output
    }

    /**
     * @description sets the return config if one if found
     * @param  {string} path [where to look for config]
     * @return {Object|void} [object if stylintrc found, undefined if not]
     */
    var _parseConfig = function( path ) {
        return JSON.parse(
            stripJsonComments(
                fs.readFileSync( path, 'utf-8' )
            )
        )
    }

    /**
     * @description [reverse walk from cwd to usr]
     *              [if .stylintrc found, use it]
     * @param  {Array&lt;string>} files [all files for this dir level]
     * @param  {number} level [# of dirs traversed so far]
     * @param  {string} cwd   [relative path to current directory being walked]
     * @return {?Object|?Function} [config if found, recurse if not. null if failed]
     */
    var _recurseDirectories = function( files, level, cwd ) {
        // parse stylintrc if found, stop recursion
        if ( files.indexOf( '.stylintrc' ) !== -1 ) {
            return _parseConfig( cwd + '/.stylintrc' )
        }

        // only go up to user home directory, stop recursion
        if ( userHome ) return null

        // next dir level
        var nextLevel = level + 1
        // pathArr is generated by applying our dir level
        // to cwd, and going backwards
        // ie, level = 1, pathArr = [ cwd, '..' ]
        // ie, level = 2, pathArr = [ cwd, '..', '..' ]
        // and so on
        var pathArr = [ cwd ]

        // push '..' for each dir level
        while ( level-- ) {
            pathArr.push( '..' )
        }

        // creates the path to the next directory
        var newPath = path.join.apply( null, pathArr )
        // gets the files for the next directory
        var newFiles = fs.readdirSync( newPath )
        // passes the newFiles, nextLevel, and newPath to itself
        // to start the process over again
        return _recurseDirectories( newFiles, nextLevel, newPath )
    }

    // if 1, the customConfig will be what we want
    // this only occurs if using stylint programmatically
    // ie, user passed in option object
    if ( this.customConfig ) {
        returnConfig = this.customConfig
    }
    // if 2, we pass in a path to the config
    // this only occurs if using stylint via the command line
    else if ( configpath ) {
        customPath = path.isAbsolute( configpath ) ? configpath : cwd + '/' + configpath
        try {
            returnConfig = _parseConfig( customPath )
        }
        catch ( err ) {
            throw err
        }
    }
    // 3, if user did not pass in option obj, or pass options via cli
    // check the user's package.json for either an option obj, or
    // at least a path to one
    else if ( pkg !== null &amp;&amp;
        typeof pkg.stylintrc !== 'undefined' ) {
        var rc = pkg.stylintrc

        if ( typeof rc === 'object' &amp;&amp; !( rc instanceof Array ) ) {
            returnConfig = rc
        }
        else if ( typeof rc === 'string' ) {
            returnConfig = _parseConfig( rc )
        }
    }
    // 4, nothing passed in via cli or programmatically or via pkg
    // start at cwd, walk up to user home directory, if nothing
    // found, then just use the default config
    else {
        try {
            // recurse up to user home
            files = fs.readdirSync( cwd )
            // null if .stylintrc file found anywhere
            returnConfig = _recurseDirectories( files, 1, cwd )

            // default config if nothing found
            if ( !returnConfig ) {
                returnConfig = this.config
            }
        }
        // in case there's an issue parsing or no .stylintrc found at specified location
        catch ( err ) {
            throw err
        }
    }

    returnConfig.exclude = ( returnConfig.exclude || [] ).map( function( exclude ) {
        return new Glob( exclude, {
            matchBase: true
        } ).minimatch
    } )

    // make sure indentPref is set no matter what
    returnConfig.indentPref = returnConfig.indentPref || false

    // 5, just return the default config if nothing found
    return returnConfig
}

module.exports = setConfig
</code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#blocks">blocks</a></li><li><a href="global.html#brackets">brackets</a></li><li><a href="global.html#checkPrefix">checkPrefix</a></li><li><a href="global.html#checkPseudo">checkPseudo</a></li><li><a href="global.html#colons">colons</a></li><li><a href="global.html#colors">colors</a></li><li><a href="global.html#commaSpace">commaSpace</a></li><li><a href="global.html#commentSpace">commentSpace</a></li><li><a href="global.html#config">config</a></li><li><a href="global.html#cssLiteral">cssLiteral</a></li><li><a href="global.html#depthLimit">depthLimit</a></li><li><a href="global.html#done">done</a></li><li><a href="global.html#duplicates">duplicates</a></li><li><a href="global.html#efficient">efficient</a></li><li><a href="global.html#extendPref">extendPref</a></li><li><a href="global.html#getFiles">getFiles</a></li><li><a href="global.html#hashEnd">hashEnd</a></li><li><a href="global.html#hashStart">hashStart</a></li><li><a href="global.html#indentPref">indentPref</a></li><li><a href="global.html#init">init</a></li><li><a href="global.html#keyframesEnd">keyframesEnd</a></li><li><a href="global.html#keyframesStart">keyframesStart</a></li><li><a href="global.html#leadingZero">leadingZero</a></li><li><a href="global.html#lint">lint</a></li><li><a href="global.html#mixed">mixed</a></li><li><a href="global.html#msg">msg</a></li><li><a href="global.html#namingConvention">namingConvention</a></li><li><a href="global.html#noImportant">noImportant</a></li><li><a href="global.html#none">none</a></li><li><a href="global.html#parenSpace">parenSpace</a></li><li><a href="global.html#parse">parse</a></li><li><a href="global.html#placeholders">placeholders</a></li><li><a href="global.html#prefixVarsWithDollar">prefixVarsWithDollar</a></li><li><a href="global.html#quotePref">quotePref</a></li><li><a href="global.html#read">read</a></li><li><a href="global.html#reporter">reporter</a></li><li><a href="global.html#resetOnChange">resetOnChange</a></li><li><a href="global.html#rootEnd">rootEnd</a></li><li><a href="global.html#rootStart">rootStart</a></li><li><a href="global.html#semicolons">semicolons</a></li><li><a href="global.html#setConfig">setConfig</a></li><li><a href="global.html#setContext">setContext</a></li><li><a href="global.html#setState">setState</a></li><li><a href="global.html#sortOrder">sortOrder</a></li><li><a href="global.html#splitAndStrip">splitAndStrip</a></li><li><a href="global.html#stackedProperties">stackedProperties</a></li><li><a href="global.html#startsWithComment">startsWithComment</a></li><li><a href="global.html#state">state</a></li><li><a href="global.html#stylintOff">stylintOff</a></li><li><a href="global.html#stylintOn">stylintOn</a></li><li><a href="global.html#trailingWhitespace">trailingWhitespace</a></li><li><a href="global.html#trimLine">trimLine</a></li><li><a href="global.html#universal">universal</a></li><li><a href="global.html#watch">watch</a></li><li><a href="global.html#zeroUnits">zeroUnits</a></li><li><a href="global.html#zIndexNormalize">zIndexNormalize</a></li></ul>
</nav>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.2</a> on Sun Oct 09 2016 22:18:45 GMT+0200 (CEST)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>