Sasslint precommit hook (#28095)

* Remove SCSS linting from dev server

* Add sasslint to precommit hook
This commit is contained in:
Chandler Prall 2019-01-04 12:14:03 -07:00 committed by GitHub
parent d745694d23
commit dd47972cec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 131 additions and 2 deletions

View file

@ -396,8 +396,8 @@
"ts-node": "^7.0.1",
"tslint": "^5.11.0",
"tslint-config-prettier": "^1.15.0",
"tslint-plugin-prettier": "^2.0.0",
"tslint-microsoft-contrib": "^6.0.0",
"tslint-plugin-prettier": "^2.0.0",
"typescript": "^3.0.3",
"vinyl-fs": "^3.0.2",
"xml2js": "^0.4.19",

View file

@ -48,6 +48,10 @@ export class File {
return this.ext === '.ts' || this.ext === '.tsx';
}
public isSass() {
return this.ext === '.sass' || this.ext === '.scss';
}
public isFixture() {
return this.relativePath.split(sep).includes('__fixtures__');
}

View file

@ -20,6 +20,7 @@
import { run, combineErrors } from './run';
import * as Eslint from './eslint';
import * as Tslint from './tslint';
import * as Sasslint from './sasslint';
import { getFilesForCommit, checkFileCasing } from './precommit_hook';
run(async ({ log }) => {
@ -32,7 +33,7 @@ run(async ({ log }) => {
errors.push(error);
}
for (const Linter of [Eslint, Tslint]) {
for (const Linter of [Eslint, Tslint, Sasslint]) {
const filesToLint = Linter.pickFilesToLint(log, files);
if (filesToLint.length > 0) {
try {

21
src/dev/sasslint/index.js Normal file
View file

@ -0,0 +1,21 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { pickFilesToLint } from './pick_files_to_lint';
export { lintFiles } from './lint_files';

View file

@ -0,0 +1,59 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import sassLint from 'sass-lint';
import path from 'path';
import { createFailError } from '../run';
/**
* Lints a list of files with eslint. eslint reports are written to the log
* and a FailError is thrown when linting errors occur.
*
* @param {ToolingLog} log
* @param {Array<File>} files
* @return {undefined}
*/
export function lintFiles(log, files) {
const paths = files.map(file => file.getRelativePath());
const report = sassLint.lintFiles(
paths.join(', '),
{},
path.resolve(__dirname, '..', '..', '..', '.sass-lint.yml')
);
const failTypes = Object.keys(
report.reduce(
(failTypes, reportEntry) => {
if (reportEntry.warningCount > 0) failTypes.warning = true;
if (reportEntry.errorCount > 0) failTypes.errors = true;
return failTypes;
},
{}
)
);
if (!failTypes.length) {
log.success('[sasslint] %d files linted successfully', files.length);
return;
}
log.error(sassLint.format(report));
throw createFailError(`[sasslint] ${failTypes.join(' & ')}`, 1);
}

View file

@ -0,0 +1,44 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import fs from 'fs';
import { safeLoad } from 'js-yaml';
import { makeRe } from 'minimatch';
import path from 'path';
// load the include globs from .sass-lint.yml and convert them to regular expressions for filtering files
const sassLintPath = path.resolve(__dirname, '..', '..', '..', '.sass-lint.yml');
const sassLintConfig = safeLoad(fs.readFileSync(sassLintPath));
const { files: { include: includeGlobs } } = sassLintConfig;
const includeRegex = includeGlobs.map(glob => makeRe(glob));
function matchesInclude(file) {
for (let i = 0; i < includeRegex.length; i++) {
if (includeRegex[i].test(file.relativePath)) {
return true;
}
}
return false;
}
export function pickFilesToLint(log, files) {
return files
.filter(file => file.isSass())
.filter(matchesInclude);
}