Skip to content
This repository was archived by the owner on Oct 19, 2020. It is now read-only.

Commit 5aacb41

Browse files
committed
add basic implementation
1 parent e6ab7dc commit 5aacb41

File tree

7 files changed

+1201
-0
lines changed

7 files changed

+1201
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/node_modules
2+
/npm-debug.log

bin/sass-lint-vue

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/usr/bin/env node
2+
require('../lib/cli')(process.argv)

lib/cli.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env node
2+
const program = require('commander')
3+
const packageDetails = require('./../package.json')
4+
const Linter = require('./linter.js')
5+
6+
const run = (args) => {
7+
program
8+
.version(packageDetails.version)
9+
.description(packageDetails.description)
10+
.usage('[options] <paths ...>')
11+
.arguments('<paths>')
12+
.parse(process.argv)
13+
14+
if (!program.args.length) {
15+
program.help()
16+
}
17+
18+
const linter = new Linter()
19+
20+
linter.checkPaths(program.args)
21+
}
22+
23+
module.exports = run

lib/linter.js

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
const walk = require('walk')
2+
const fs = require('fs')
3+
const path = require('path')
4+
const htmlparser = require('htmlparser')
5+
const cheerio = require('cheerio')
6+
const sassLint = require('sass-lint')
7+
const Reporter = require('./reporter.js')
8+
9+
class Linter {
10+
constructor (options) {
11+
this.lintErrors = []
12+
}
13+
14+
checkPaths (pathsToCheck) {
15+
pathsToCheck.forEach((pathToCheck) => {
16+
this.checkPath(pathToCheck)
17+
})
18+
}
19+
20+
checkPath (arg) {
21+
const walker = walk.walk(arg, { followLinks: false })
22+
walker.on('file', this.walkerFileHandler.bind(this))
23+
walker.on('end', this.walkerEndHandler.bind(this))
24+
}
25+
26+
walkerFileHandler (root, fileStat, next) {
27+
const filename = `${root}/${fileStat.name}`
28+
29+
if (filename.substr(-3) !== 'vue') {
30+
return next()
31+
}
32+
33+
fs.readFile(path.resolve(root, fileStat.name), (error, fileData) => {
34+
if (error) {
35+
return console.log(error)
36+
}
37+
38+
const fileTemplates = this.extractFileTemplates(fileData)
39+
40+
fileTemplates.forEach((template) => {
41+
const fileErrors = sassLint.lintText({
42+
text: template,
43+
filename: filename,
44+
format: 'scss'
45+
})
46+
47+
if (fileErrors.messages.length) {
48+
this.lintErrors = this.lintErrors.concat(fileErrors)
49+
}
50+
})
51+
52+
next()
53+
})
54+
}
55+
56+
walkerEndHandler () {
57+
const reporter = new Reporter()
58+
reporter.report(this.lintErrors)
59+
}
60+
61+
extractFileTemplates (fileData) {
62+
let templates = []
63+
64+
const handler = new htmlparser.DefaultHandler((error, dom) => {
65+
if (error) {
66+
return console.log(error)
67+
}
68+
69+
const $ = cheerio.load(dom)
70+
templates = templates.concat($('style[lang="sass"]').text())
71+
templates = templates.concat($('style[lang="scss"]').text())
72+
})
73+
74+
var parser = new htmlparser.Parser(handler)
75+
parser.parseComplete(fileData)
76+
return templates
77+
}
78+
}
79+
80+
module.exports = Linter

lib/reporter.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const table = require('text-table')
2+
const chalk = require('chalk')
3+
4+
class Reporter {
5+
report (results) {
6+
let output = '\n'
7+
let totalErrors = 0
8+
let totalWarnings = 0
9+
10+
results.forEach((result) => {
11+
totalErrors += result.errorCount
12+
totalWarnings += result.warningCount
13+
14+
output += chalk.underline(result.filePath) + '\n'
15+
16+
output += table(result.messages.map((msg) => {
17+
return [
18+
'',
19+
`${msg.line}:${msg.column}`,
20+
(msg.severity === 2) ? chalk.red(msg.ruleId) : chalk.yellow(msg.ruleId),
21+
msg.message
22+
]
23+
}))
24+
25+
output += '\n\n'
26+
})
27+
28+
if (totalErrors > 0) {
29+
output += chalk.red.bold(`\u2716 errors: ${totalErrors}`)
30+
output += ' | '
31+
output += chalk.yellow.bold(`warnings ${totalWarnings}`)
32+
console.log(output)
33+
process.exit(1)
34+
}
35+
}
36+
}
37+
38+
module.exports = Reporter

package.json

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "sass-lint-vue",
3+
"version": "0.1.0",
4+
"description": "Command line tool to lint Sass styles in Vue single file components.",
5+
"keywords": [
6+
"lint",
7+
"linting",
8+
"linter",
9+
"sass",
10+
"scss",
11+
"vue"
12+
],
13+
"homepage": "https://github.com/sourceboat/sass-lint-vue",
14+
"bugs": "https://github.com/sourceboat/sass-lint-vue/issues",
15+
"author": "Sourceboat <[email protected]>",
16+
"contributors": [
17+
"Phil-Bastian Berndt <[email protected]> (https://pbb.io/)"
18+
],
19+
"license": "MIT",
20+
"repository": {
21+
"url": "https://github.com/sourceboat/sass-lint-vue",
22+
"type": "git"
23+
},
24+
"main": "lib/linter.js",
25+
"bin": {
26+
"sass-lint-vue": "./bin/sass-lint-vue"
27+
},
28+
"dependencies": {
29+
"chalk": "^1.1.3",
30+
"cheerio": "^0.22.0",
31+
"commander": "^2.9.0",
32+
"htmlparser": "^1.7.7",
33+
"sass-lint": "^1.10.2",
34+
"text-table": "^0.2.0",
35+
"walk": "^2.3.9"
36+
}
37+
}

0 commit comments

Comments
 (0)