1
0
mirror of https://github.com/thangisme/notes.git synced 2024-06-20 19:15:25 +00:00
notes/node_modules/stylelint/lib/lintSource.js
Patrick Marsceill b7b0d0d7bf
Initial commit
2017-03-09 13:16:08 -05:00

141 lines
4.7 KiB
JavaScript

/* @flow */
"use strict"
const _ = require("lodash")
const assignDisabledRanges = require("./assignDisabledRanges")
const configurationError = require("./utils/configurationError")
const path = require("path")
const ruleDefinitions = require("./rules")
// Run stylelint on a PostCSS Result, either one that is provided
// or one that we create
module.exports = function (
stylelint/*: stylelint$internalApi*/,
options/*: {
code?: string,
codeFilename?: string, // Must be an absolute file path
filePath?: string, // Must be an absolute file path
existingPostcssResult?: Object,
}*/
)/*: Promise<Object>*/ {
options = options || {}
if (!options.filePath && options.code === undefined && !options.existingPostcssResult) {
return Promise.reject(new Error("You must provide filePath, code, or existingPostcssResult"))
}
const isCodeNotFile = options.code !== undefined
const inputFilePath = isCodeNotFile ? options.codeFilename : options.filePath
if (inputFilePath !== undefined && !path.isAbsolute(inputFilePath)) {
if (isCodeNotFile) {
return Promise.reject(new Error("codeFilename must be an absolute path"))
} else {
return Promise.reject(new Error("filePath must be an absolute path"))
}
}
const getIsIgnored = stylelint.isPathIgnored(inputFilePath).catch(err => {
if (isCodeNotFile && err.code === "ENOENT") return false
throw err
})
return getIsIgnored.then(isIgnored => {
if (isIgnored) {
const postcssResult = options.existingPostcssResult || createEmptyPostcssResult(inputFilePath)
postcssResult.stylelint = postcssResult.stylelint || {}
postcssResult.stylelint.ignored = true
postcssResult.standaloneIgnored = true // TODO: remove need for this
return postcssResult
}
const configSearchPath = stylelint._options.configFile || inputFilePath
const getConfig = stylelint.getConfigForFile(configSearchPath).catch(err => {
if (isCodeNotFile && err.code === "ENOENT") return stylelint.getConfigForFile(process.cwd())
throw err
})
return getConfig.then((result) => {
const config = result.config
const existingPostcssResult = options.existingPostcssResult
if (existingPostcssResult) {
return lintPostcssResult(stylelint, existingPostcssResult, config).then(() => existingPostcssResult)
}
return stylelint._getPostcssResult({
code: options.code,
codeFilename: options.codeFilename,
filePath: inputFilePath,
codeProcessors: config.codeProcessors,
}).then(postcssResult => {
return lintPostcssResult(stylelint, postcssResult, config).then(() => postcssResult)
})
})
})
}
function lintPostcssResult(
stylelint/*: stylelint$internalApi*/,
postcssResult/*: Object*/,
config/*: stylelint$config*/
)/*: Promise<>*/ {
postcssResult.stylelint = postcssResult.stylelint || {}
postcssResult.stylelint.ruleSeverities = {}
postcssResult.stylelint.customMessages = {}
postcssResult.stylelint.quiet = config.quiet
const postcssRoot = postcssResult.root
assignDisabledRanges(postcssRoot, postcssResult)
if (stylelint._options.reportNeedlessDisables || stylelint._options.ignoreDisables) {
postcssResult.stylelint.ignoreDisables = true
}
// Promises for the rules. Although the rule code runs synchronously now,
// the use of Promises makes it compatible with the possibility of async
// rules down the line.
const performRules = []
const rules = config.rules ? Object.keys(config.rules) : []
rules.forEach(ruleName => {
const ruleFunction = ruleDefinitions[ruleName] || _.get(config, [ "pluginFunctions", ruleName ])
if (ruleFunction === undefined) {
throw configurationError(`Undefined rule ${ruleName}`)
}
const ruleSettings = _.get(config, [ "rules", ruleName ])
if (ruleSettings === null || ruleSettings[0] === null) {
return
}
const primaryOption = ruleSettings[0]
const secondaryOptions = ruleSettings[1]
// Log the rule's severity in the PostCSS result
const defaultSeverity = config.defaultSeverity || "error"
postcssResult.stylelint.ruleSeverities[ruleName] = _.get(secondaryOptions, "severity", defaultSeverity)
postcssResult.stylelint.customMessages[ruleName] = _.get(secondaryOptions, "message")
const performRule = Promise.resolve().then(() => {
ruleFunction(primaryOption, secondaryOptions)(postcssRoot, postcssResult)
})
performRules.push(performRule)
})
return Promise.all(performRules)
}
function createEmptyPostcssResult(filePath/*:: ?: string*/)/*: Object*/ {
return {
root: {
source: {
input: { file: filePath },
},
},
messages: [],
stylelint: { stylelintError: null },
}
}