From 0ca320561a15db28029c96169e465301c6b52921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Tue, 22 Sep 2020 11:12:35 +0200 Subject: [PATCH] isolate hygiene --- build/gulpfile.hygiene.js | 436 ++++---------------------------------- build/hygiene.js | 412 +++++++++++++++++++++++++++++++++++ package.json | 2 +- 3 files changed, 456 insertions(+), 394 deletions(-) create mode 100644 build/hygiene.js diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index 4952ee1c26d..eec0ccd1834 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -3,182 +3,40 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; +"use strict"; -const gulp = require('gulp'); -const filter = require('gulp-filter'); -const es = require('event-stream'); -const gulpeslint = require('gulp-eslint'); -const tsfmt = require('typescript-formatter'); -const VinylFile = require('vinyl'); -const vfs = require('vinyl-fs'); -const path = require('path'); -const fs = require('fs'); -const pall = require('p-all'); -const task = require('./lib/task'); +const gulp = require("gulp"); +const filter = require("gulp-filter"); +const es = require("event-stream"); +const gulpeslint = require("gulp-eslint"); +const vfs = require("vinyl-fs"); +const path = require("path"); +const task = require("./lib/task"); +const { all, jsHygieneFilter, tsHygieneFilter, hygiene } = require("./hygiene"); -/** - * Hygiene works by creating cascading subsets of all our files and - * passing them through a sequence of checks. Here are the current subsets, - * named according to the checks performed on them. Each subset contains - * the following one, as described in mathematical notation: - * - * all ⊃ eol ⊇ indentation ⊃ copyright ⊃ typescript - */ - -const all = [ - '*', - 'build/**/*', - 'extensions/**/*', - 'scripts/**/*', - 'src/**/*', - 'test/**/*', - '!test/**/out/**', - '!**/node_modules/**' -]; - -const indentationFilter = [ - '**', - - // except specific files - '!**/ThirdPartyNotices.txt', - '!**/LICENSE.{txt,rtf}', - '!LICENSES.chromium.html', - '!**/LICENSE', - '!src/vs/nls.js', - '!src/vs/nls.build.js', - '!src/vs/css.js', - '!src/vs/css.build.js', - '!src/vs/loader.js', - '!src/vs/base/common/insane/insane.js', - '!src/vs/base/common/marked/marked.js', - '!src/vs/base/node/terminateProcess.sh', - '!src/vs/base/node/cpuUsage.sh', - '!test/unit/assert.js', - - // except specific folders - '!test/automation/out/**', - '!test/smoke/out/**', - '!extensions/typescript-language-features/test-workspace/**', - '!extensions/vscode-api-tests/testWorkspace/**', - '!extensions/vscode-api-tests/testWorkspace2/**', - '!build/monaco/**', - '!build/win32/**', - - // except multiple specific files - '!**/package.json', - '!**/yarn.lock', - '!**/yarn-error.log', - - // except multiple specific folders - '!**/codicon/**', - '!**/fixtures/**', - '!**/lib/**', - '!extensions/**/out/**', - '!extensions/**/snippets/**', - '!extensions/**/syntaxes/**', - '!extensions/**/themes/**', - '!extensions/**/colorize-fixtures/**', - - // except specific file types - '!src/vs/*/**/*.d.ts', - '!src/typings/**/*.d.ts', - '!extensions/**/*.d.ts', - '!**/*.{svg,exe,png,bmp,scpt,bat,cmd,cur,ttf,woff,eot,md,ps1,template,yaml,yml,d.ts.recipe,ico,icns,plist}', - '!build/{lib,download,darwin}/**/*.js', - '!build/**/*.sh', - '!build/azure-pipelines/**/*.js', - '!build/azure-pipelines/**/*.config', - '!**/Dockerfile', - '!**/Dockerfile.*', - '!**/*.Dockerfile', - '!**/*.dockerfile', - '!extensions/markdown-language-features/media/*.js' -]; - -const copyrightFilter = [ - '**', - '!**/*.desktop', - '!**/*.json', - '!**/*.html', - '!**/*.template', - '!**/*.md', - '!**/*.bat', - '!**/*.cmd', - '!**/*.ico', - '!**/*.icns', - '!**/*.xml', - '!**/*.sh', - '!**/*.txt', - '!**/*.xpm', - '!**/*.opts', - '!**/*.disabled', - '!**/*.code-workspace', - '!**/*.js.map', - '!build/**/*.init', - '!resources/linux/snap/snapcraft.yaml', - '!resources/linux/snap/electron-launch', - '!resources/win32/bin/code.js', - '!resources/web/code-web.js', - '!resources/completions/**', - '!extensions/markdown-language-features/media/highlight.css', - '!extensions/html-language-features/server/src/modes/typescript/*', - '!extensions/*/server/bin/*', - '!src/vs/editor/test/node/classification/typescript-test.ts' -]; - -const jsHygieneFilter = [ - 'src/**/*.js', - 'build/gulpfile.*.js', - '!src/vs/loader.js', - '!src/vs/css.js', - '!src/vs/nls.js', - '!src/vs/css.build.js', - '!src/vs/nls.build.js', - '!src/**/insane.js', - '!src/**/marked.js', - '!**/test/**' -]; - -const tsHygieneFilter = [ - 'src/**/*.ts', - 'test/**/*.ts', - 'extensions/**/*.ts', - '!**/fixtures/**', - '!**/typings/**', - '!**/node_modules/**', - '!extensions/typescript-basics/test/colorize-fixtures/**', - '!extensions/vscode-api-tests/testWorkspace/**', - '!extensions/vscode-api-tests/testWorkspace2/**', - '!extensions/**/*.test.ts', - '!extensions/html-language-features/server/lib/jquery.d.ts' -]; - -const copyrightHeaderLines = [ - '/*---------------------------------------------------------------------------------------------', - ' * Copyright (c) Microsoft Corporation. All rights reserved.', - ' * Licensed under the MIT License. See License.txt in the project root for license information.', - ' *--------------------------------------------------------------------------------------------*/' -]; - -gulp.task('eslint', () => { - return vfs.src(all, { base: '.', follow: true, allowEmpty: true }) +gulp.task("eslint", () => { + return vfs + .src(all, { base: ".", follow: true, allowEmpty: true }) .pipe(filter(jsHygieneFilter.concat(tsHygieneFilter))) - .pipe(gulpeslint({ - configFile: '.eslintrc.json', - rulePaths: ['./build/lib/eslint'] - })) - .pipe(gulpeslint.formatEach('compact')) - .pipe(gulpeslint.results(results => { - if (results.warningCount > 0 || results.errorCount > 0) { - throw new Error('eslint failed with warnings and/or errors'); - } - })); + .pipe( + gulpeslint({ + configFile: ".eslintrc.json", + rulePaths: ["./build/lib/eslint"], + }) + ) + .pipe(gulpeslint.formatEach("compact")) + .pipe( + gulpeslint.results((results) => { + if (results.warningCount > 0 || results.errorCount > 0) { + throw new Error("eslint failed with warnings and/or errors"); + } + }) + ); }); function checkPackageJSON(actualPath) { - const actual = require(path.join(__dirname, '..', actualPath)); - const rootPackageJSON = require('../package.json'); + const actual = require(path.join(__dirname, "..", actualPath)); + const rootPackageJSON = require("../package.json"); for (let depName in actual.dependencies) { const depVersion = actual.dependencies[depName]; @@ -188,233 +46,25 @@ function checkPackageJSON(actualPath) { continue; } if (depVersion !== rootDepVersion) { - this.emit('error', `The dependency ${depName} in '${actualPath}' (${depVersion}) is different than in the root package.json (${rootDepVersion})`); + this.emit( + "error", + `The dependency ${depName} in '${actualPath}' (${depVersion}) is different than in the root package.json (${rootDepVersion})` + ); } } } -const checkPackageJSONTask = task.define('check-package-json', () => { - return gulp.src('package.json') - .pipe(es.through(function () { - checkPackageJSON.call(this, 'remote/package.json'); - checkPackageJSON.call(this, 'remote/web/package.json'); - })); +const checkPackageJSONTask = task.define("check-package-json", () => { + return gulp.src("package.json").pipe( + es.through(function () { + checkPackageJSON.call(this, "remote/package.json"); + checkPackageJSON.call(this, "remote/web/package.json"); + }) + ); }); gulp.task(checkPackageJSONTask); - -function hygiene(some) { - let errorCount = 0; - - const productJson = es.through(function (file) { - const product = JSON.parse(file.contents.toString('utf8')); - - if (product.extensionsGallery) { - console.error('product.json: Contains "extensionsGallery"'); - errorCount++; - } - - this.emit('data', file); - }); - - const indentation = es.through(function (file) { - const lines = file.contents.toString('utf8').split(/\r\n|\r|\n/); - file.__lines = lines; - - lines - .forEach((line, i) => { - if (/^\s*$/.test(line)) { - // empty or whitespace lines are OK - } else if (/^[\t]*[^\s]/.test(line)) { - // good indent - } else if (/^[\t]* \*/.test(line)) { - // block comment using an extra space - } else { - console.error(file.relative + '(' + (i + 1) + ',1): Bad whitespace indentation'); - errorCount++; - } - }); - - this.emit('data', file); - }); - - const copyrights = es.through(function (file) { - const lines = file.__lines; - - for (let i = 0; i < copyrightHeaderLines.length; i++) { - if (lines[i] !== copyrightHeaderLines[i]) { - console.error(file.relative + ': Missing or bad copyright statement'); - errorCount++; - break; - } - } - - this.emit('data', file); - }); - - const formatting = es.map(function (file, cb) { - tsfmt.processString(file.path, file.contents.toString('utf8'), { - verify: false, - tsfmt: true, - // verbose: true, - // keep checkJS happy - editorconfig: undefined, - replace: undefined, - tsconfig: undefined, - tsconfigFile: undefined, - tsfmtFile: undefined, - vscode: undefined, - vscodeFile: undefined - }).then(result => { - let original = result.src.replace(/\r\n/gm, '\n'); - let formatted = result.dest.replace(/\r\n/gm, '\n'); - - if (original !== formatted) { - console.error('File not formatted. Run the \'Format Document\' command to fix it:', file.relative); - errorCount++; - } - cb(null, file); - - }, err => { - cb(err); - }); - }); - - let input; - - if (Array.isArray(some) || typeof some === 'string' || !some) { - const options = { base: '.', follow: true, allowEmpty: true }; - if (some) { - input = vfs.src(some, options).pipe(filter(all)); // split this up to not unnecessarily filter all a second time - } else { - input = vfs.src(all, options); - } - } else { - input = some; - } - - const productJsonFilter = filter('product.json', { restore: true }); - - const result = input - .pipe(filter(f => !f.stat.isDirectory())) - .pipe(productJsonFilter) - .pipe(process.env['BUILD_SOURCEVERSION'] ? es.through() : productJson) - .pipe(productJsonFilter.restore) - .pipe(filter(indentationFilter)) - .pipe(indentation) - .pipe(filter(copyrightFilter)) - .pipe(copyrights); - - const typescript = result - .pipe(filter(tsHygieneFilter)) - .pipe(formatting); - - const javascript = result - .pipe(filter(jsHygieneFilter.concat(tsHygieneFilter))) - .pipe(gulpeslint({ - configFile: '.eslintrc.json', - rulePaths: ['./build/lib/eslint'] - })) - .pipe(gulpeslint.formatEach('compact')) - .pipe(gulpeslint.results(results => { - errorCount += results.warningCount; - errorCount += results.errorCount; - })); - - let count = 0; - return es.merge(typescript, javascript) - .pipe(es.through(function (data) { - count++; - if (process.env['TRAVIS'] && count % 10 === 0) { - process.stdout.write('.'); - } - this.emit('data', data); - }, function () { - process.stdout.write('\n'); - if (errorCount > 0) { - this.emit('error', 'Hygiene failed with ' + errorCount + ' errors. Check \'build/gulpfile.hygiene.js\'.'); - } else { - this.emit('end'); - } - })); -} - -function createGitIndexVinyls(paths) { - const cp = require('child_process'); - const repositoryPath = process.cwd(); - - const fns = paths.map(relativePath => () => new Promise((c, e) => { - const fullPath = path.join(repositoryPath, relativePath); - - fs.stat(fullPath, (err, stat) => { - if (err && err.code === 'ENOENT') { // ignore deletions - return c(null); - } else if (err) { - return e(err); - } - - cp.exec(`git show :${relativePath}`, { maxBuffer: 2000 * 1024, encoding: 'buffer' }, (err, out) => { - if (err) { - return e(err); - } - - c(new VinylFile({ - path: fullPath, - base: repositoryPath, - contents: out, - stat - })); - }); - }); - })); - - return pall(fns, { concurrency: 4 }) - .then(r => r.filter(p => !!p)); -} - -gulp.task('hygiene', task.series(checkPackageJSONTask, () => hygiene())); - -// this allows us to run hygiene as a git pre-commit hook -if (require.main === module) { - const cp = require('child_process'); - - process.on('unhandledRejection', (reason, p) => { - console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); - process.exit(1); - }); - - if (process.argv.length > 2) { - hygiene(process.argv.slice(2)).on('error', err => { - console.error(); - console.error(err); - process.exit(1); - }); - } else { - cp.exec('git diff --cached --name-only', { maxBuffer: 2000 * 1024 }, (err, out) => { - if (err) { - console.error(); - console.error(err); - process.exit(1); - return; - } - - const some = out - .split(/\r?\n/) - .filter(l => !!l); - - if (some.length > 0) { - console.log('Reading git index versions...'); - - createGitIndexVinyls(some) - .then(vinyls => new Promise((c, e) => hygiene(es.readArray(vinyls)) - .on('end', () => c()) - .on('error', e))) - .catch(err => { - console.error(); - console.error(err); - process.exit(1); - }); - } - }); - } -} +gulp.task( + "hygiene", + task.series(checkPackageJSONTask, () => hygiene()) +); diff --git a/build/hygiene.js b/build/hygiene.js new file mode 100644 index 00000000000..66571bc6355 --- /dev/null +++ b/build/hygiene.js @@ -0,0 +1,412 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +"use strict"; + +const filter = require("gulp-filter"); +const es = require("event-stream"); +const gulpeslint = require("gulp-eslint"); +const tsfmt = require("typescript-formatter"); +const VinylFile = require("vinyl"); +const vfs = require("vinyl-fs"); +const path = require("path"); +const fs = require("fs"); +const pall = require("p-all"); + +/** + * Hygiene works by creating cascading subsets of all our files and + * passing them through a sequence of checks. Here are the current subsets, + * named according to the checks performed on them. Each subset contains + * the following one, as described in mathematical notation: + * + * all ⊃ eol ⊇ indentation ⊃ copyright ⊃ typescript + */ + +const all = [ + "*", + "build/**/*", + "extensions/**/*", + "scripts/**/*", + "src/**/*", + "test/**/*", + "!test/**/out/**", + "!**/node_modules/**", +]; +module.exports.all = all; + +const indentationFilter = [ + "**", + + // except specific files + "!**/ThirdPartyNotices.txt", + "!**/LICENSE.{txt,rtf}", + "!LICENSES.chromium.html", + "!**/LICENSE", + "!src/vs/nls.js", + "!src/vs/nls.build.js", + "!src/vs/css.js", + "!src/vs/css.build.js", + "!src/vs/loader.js", + "!src/vs/base/common/insane/insane.js", + "!src/vs/base/common/marked/marked.js", + "!src/vs/base/node/terminateProcess.sh", + "!src/vs/base/node/cpuUsage.sh", + "!test/unit/assert.js", + + // except specific folders + "!test/automation/out/**", + "!test/smoke/out/**", + "!extensions/typescript-language-features/test-workspace/**", + "!extensions/vscode-api-tests/testWorkspace/**", + "!extensions/vscode-api-tests/testWorkspace2/**", + "!build/monaco/**", + "!build/win32/**", + + // except multiple specific files + "!**/package.json", + "!**/yarn.lock", + "!**/yarn-error.log", + + // except multiple specific folders + "!**/codicon/**", + "!**/fixtures/**", + "!**/lib/**", + "!extensions/**/out/**", + "!extensions/**/snippets/**", + "!extensions/**/syntaxes/**", + "!extensions/**/themes/**", + "!extensions/**/colorize-fixtures/**", + + // except specific file types + "!src/vs/*/**/*.d.ts", + "!src/typings/**/*.d.ts", + "!extensions/**/*.d.ts", + "!**/*.{svg,exe,png,bmp,scpt,bat,cmd,cur,ttf,woff,eot,md,ps1,template,yaml,yml,d.ts.recipe,ico,icns,plist}", + "!build/{lib,download,darwin}/**/*.js", + "!build/**/*.sh", + "!build/azure-pipelines/**/*.js", + "!build/azure-pipelines/**/*.config", + "!**/Dockerfile", + "!**/Dockerfile.*", + "!**/*.Dockerfile", + "!**/*.dockerfile", + "!extensions/markdown-language-features/media/*.js", +]; + +const copyrightFilter = [ + "**", + "!**/*.desktop", + "!**/*.json", + "!**/*.html", + "!**/*.template", + "!**/*.md", + "!**/*.bat", + "!**/*.cmd", + "!**/*.ico", + "!**/*.icns", + "!**/*.xml", + "!**/*.sh", + "!**/*.txt", + "!**/*.xpm", + "!**/*.opts", + "!**/*.disabled", + "!**/*.code-workspace", + "!**/*.js.map", + "!build/**/*.init", + "!resources/linux/snap/snapcraft.yaml", + "!resources/linux/snap/electron-launch", + "!resources/win32/bin/code.js", + "!resources/web/code-web.js", + "!resources/completions/**", + "!extensions/markdown-language-features/media/highlight.css", + "!extensions/html-language-features/server/src/modes/typescript/*", + "!extensions/*/server/bin/*", + "!src/vs/editor/test/node/classification/typescript-test.ts", +]; + +const jsHygieneFilter = [ + "src/**/*.js", + "build/gulpfile.*.js", + "!src/vs/loader.js", + "!src/vs/css.js", + "!src/vs/nls.js", + "!src/vs/css.build.js", + "!src/vs/nls.build.js", + "!src/**/insane.js", + "!src/**/marked.js", + "!**/test/**", +]; +module.exports.jsHygieneFilter = jsHygieneFilter; + +const tsHygieneFilter = [ + "src/**/*.ts", + "test/**/*.ts", + "extensions/**/*.ts", + "!**/fixtures/**", + "!**/typings/**", + "!**/node_modules/**", + "!extensions/typescript-basics/test/colorize-fixtures/**", + "!extensions/vscode-api-tests/testWorkspace/**", + "!extensions/vscode-api-tests/testWorkspace2/**", + "!extensions/**/*.test.ts", + "!extensions/html-language-features/server/lib/jquery.d.ts", +]; +module.exports.tsHygieneFilter = tsHygieneFilter; + +const copyrightHeaderLines = [ + "/*---------------------------------------------------------------------------------------------", + " * Copyright (c) Microsoft Corporation. All rights reserved.", + " * Licensed under the MIT License. See License.txt in the project root for license information.", + " *--------------------------------------------------------------------------------------------*/", +]; + +function hygiene(some) { + let errorCount = 0; + + const productJson = es.through(function (file) { + const product = JSON.parse(file.contents.toString("utf8")); + + if (product.extensionsGallery) { + console.error('product.json: Contains "extensionsGallery"'); + errorCount++; + } + + this.emit("data", file); + }); + + const indentation = es.through(function (file) { + const lines = file.contents.toString("utf8").split(/\r\n|\r|\n/); + file.__lines = lines; + + lines.forEach((line, i) => { + if (/^\s*$/.test(line)) { + // empty or whitespace lines are OK + } else if (/^[\t]*[^\s]/.test(line)) { + // good indent + } else if (/^[\t]* \*/.test(line)) { + // block comment using an extra space + } else { + console.error( + file.relative + "(" + (i + 1) + ",1): Bad whitespace indentation" + ); + errorCount++; + } + }); + + this.emit("data", file); + }); + + const copyrights = es.through(function (file) { + const lines = file.__lines; + + for (let i = 0; i < copyrightHeaderLines.length; i++) { + if (lines[i] !== copyrightHeaderLines[i]) { + console.error(file.relative + ": Missing or bad copyright statement"); + errorCount++; + break; + } + } + + this.emit("data", file); + }); + + const formatting = es.map(function (file, cb) { + tsfmt + .processString(file.path, file.contents.toString("utf8"), { + verify: false, + tsfmt: true, + // verbose: true, + // keep checkJS happy + editorconfig: undefined, + replace: undefined, + tsconfig: undefined, + tsconfigFile: undefined, + tsfmtFile: undefined, + vscode: undefined, + vscodeFile: undefined, + }) + .then( + (result) => { + let original = result.src.replace(/\r\n/gm, "\n"); + let formatted = result.dest.replace(/\r\n/gm, "\n"); + + if (original !== formatted) { + console.error( + "File not formatted. Run the 'Format Document' command to fix it:", + file.relative + ); + errorCount++; + } + cb(null, file); + }, + (err) => { + cb(err); + } + ); + }); + + let input; + + if (Array.isArray(some) || typeof some === "string" || !some) { + const options = { base: ".", follow: true, allowEmpty: true }; + if (some) { + input = vfs.src(some, options).pipe(filter(all)); // split this up to not unnecessarily filter all a second time + } else { + input = vfs.src(all, options); + } + } else { + input = some; + } + + const productJsonFilter = filter("product.json", { restore: true }); + + const result = input + .pipe(filter((f) => !f.stat.isDirectory())) + .pipe(productJsonFilter) + .pipe(process.env["BUILD_SOURCEVERSION"] ? es.through() : productJson) + .pipe(productJsonFilter.restore) + .pipe(filter(indentationFilter)) + .pipe(indentation) + .pipe(filter(copyrightFilter)) + .pipe(copyrights); + + const typescript = result.pipe(filter(tsHygieneFilter)).pipe(formatting); + + const javascript = result + .pipe(filter(jsHygieneFilter.concat(tsHygieneFilter))) + .pipe( + gulpeslint({ + configFile: ".eslintrc.json", + rulePaths: ["./build/lib/eslint"], + }) + ) + .pipe(gulpeslint.formatEach("compact")) + .pipe( + gulpeslint.results((results) => { + errorCount += results.warningCount; + errorCount += results.errorCount; + }) + ); + + let count = 0; + return es.merge(typescript, javascript).pipe( + es.through( + function (data) { + count++; + if (process.env["TRAVIS"] && count % 10 === 0) { + process.stdout.write("."); + } + this.emit("data", data); + }, + function () { + process.stdout.write("\n"); + if (errorCount > 0) { + this.emit( + "error", + "Hygiene failed with " + + errorCount + + " errors. Check 'build/gulpfile.hygiene.js'." + ); + } else { + this.emit("end"); + } + } + ) + ); +} + +module.exports.hygiene = hygiene; + +function createGitIndexVinyls(paths) { + const cp = require("child_process"); + const repositoryPath = process.cwd(); + + const fns = paths.map((relativePath) => () => + new Promise((c, e) => { + const fullPath = path.join(repositoryPath, relativePath); + + fs.stat(fullPath, (err, stat) => { + if (err && err.code === "ENOENT") { + // ignore deletions + return c(null); + } else if (err) { + return e(err); + } + + cp.exec( + `git show :${relativePath}`, + { maxBuffer: 2000 * 1024, encoding: "buffer" }, + (err, out) => { + if (err) { + return e(err); + } + + c( + new VinylFile({ + path: fullPath, + base: repositoryPath, + contents: out, + stat, + }) + ); + } + ); + }); + }) + ); + + return pall(fns, { concurrency: 4 }).then((r) => r.filter((p) => !!p)); +} + +// this allows us to run hygiene as a git pre-commit hook +if (require.main === module) { + const cp = require("child_process"); + + process.on("unhandledRejection", (reason, p) => { + console.log("Unhandled Rejection at: Promise", p, "reason:", reason); + process.exit(1); + }); + + if (process.argv.length > 2) { + hygiene(process.argv.slice(2)).on("error", (err) => { + console.error(); + console.error(err); + process.exit(1); + }); + } else { + cp.exec( + "git diff --cached --name-only", + { maxBuffer: 2000 * 1024 }, + (err, out) => { + if (err) { + console.error(); + console.error(err); + process.exit(1); + } + + const some = out.split(/\r?\n/).filter((l) => !!l); + + if (some.length > 0) { + console.log("Reading git index versions..."); + + createGitIndexVinyls(some) + .then( + (vinyls) => + new Promise((c, e) => + hygiene(es.readArray(vinyls)) + .on("end", () => c()) + .on("error", e) + ) + ) + .catch((err) => { + console.error(); + console.error(err); + process.exit(1); + }); + } + } + ); + } +} diff --git a/package.json b/package.json index afb7e5deef6..157a79186fd 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "watch-extensionsd": "deemon yarn watch-extensions", "kill-watch-extensionsd": "deemon --kill yarn watch-extensions", "mocha": "mocha test/unit/node/all.js --delay", - "precommit": "node build/gulpfile.hygiene.js", + "precommit": "node build/hygiene.js", "gulp": "gulp --max_old_space_size=8192", "electron": "node build/lib/electron", "7z": "7z",