-
Notifications
You must be signed in to change notification settings - Fork 0
/
gemstone-linter-css.js
107 lines (98 loc) · 3.85 KB
/
gemstone-linter-css.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
** GemstoneJS -- Gemstone JavaScript Technology Stack
** Copyright (c) 2016-2019 Gemstone Project <http://gemstonejs.com>
** Licensed under Apache License 2.0 <https://spdx.org/licenses/Apache-2.0>
*/
/* load external requirements */
const path = require("path")
const fs = require("mz/fs")
const clone = require("clone")
const PostCSS = require("postcss")
const PostCSSSCSS = require("postcss-scss")
const StyleLint = require("stylelint")
const GemstoneStylelintConfig = require("gemstone-config-stylelint")
/* exported API function */
module.exports = async function (filenames, opts = {}, report = { sources: {}, findings: [] }) {
let passed = true
/* interate over all source files */
if (typeof opts.progress === "function")
opts.progress(0.0, "linting CSS: starting")
for (let i = 0; i < filenames.length; i++) {
/* indicate progress */
if (typeof opts.progress === "function")
opts.progress(i / filenames.length, `linting CSS: ${filenames[i]}`)
/* read source code */
const source = await fs.readFile(filenames[i], "utf8")
/* determine name of source */
const name = path.relative(process.cwd(), filenames[i])
/* determine StyleLint configuration */
const config = clone(GemstoneStylelintConfig)
if (typeof opts.rules === "object")
Object.assign(config.rules, opts.rules)
/* lint CSS via PostCSS/SCSS/StyleLint */
const lintResult = await PostCSS([
StyleLint({ config: config })
]).process(source, {
from: name,
to: name,
parser: PostCSSSCSS
}).catch((err) => {
/* take CSS parsing errors */
if (typeof err === "object" && err.name === "CssSyntaxError") {
/* transform CssSyntaxError */
let [ ,, line, col, msg ] = err.message.match(/^(.+):(\d+):(\d+):\s*(.+)$/)
line = parseInt(line)
col = parseInt(col)
report.findings.push({
ctx: "CSS",
filename: name,
line: line,
column: col,
message: msg,
ruleProc: "postcss-scss",
ruleId: "*"
})
}
else {
/* Ops, any other unknown error? */
report.findings.push({
ctx: "CSS",
filename: name,
line: 1,
column: 1,
message: `UNKNOWN PARSING ERROR: ${err}`,
ruleProc: "postcss-scss",
ruleId: "*"
})
}
report.sources[name] = source
passed = false
})
/* take CSS styling errors */
if (typeof lintResult === "object" && lintResult.messages) {
lintResult.messages.forEach((message) => {
let msg = message.text
let ruleId = "unknown"
const m = msg.match(/^(.+)\s*\((.+)\)$/)
if (m !== null) {
msg = m[1]
ruleId = m[2]
}
report.findings.push({
ctx: "CSS",
filename: name,
line: message.line,
column: message.column,
message: msg,
ruleProc: "stylelint",
ruleId: ruleId
})
report.sources[name] = source
passed = false
})
}
}
if (typeof opts.progress === "function")
opts.progress(1.0, "y")
return passed
}