From 67aedbdc549c63c7040241568da197e4773ea2e8 Mon Sep 17 00:00:00 2001 From: JUDIT GRESKOVITS Date: Wed, 21 Jun 2017 15:33:14 +0100 Subject: [PATCH] feat: Lint changed before commit, except if partially staged --- scripts/format | 7 +++- scripts/run-staged-pkg | 85 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/scripts/format b/scripts/format index f084da6d..f657d239 100755 --- a/scripts/format +++ b/scripts/format @@ -1,7 +1,7 @@ #!/usr/bin/env node const { config } = require('../package.json'); -const { exists, access } = require('mz/fs'); +const { exists } = require('mz/fs'); const sgf = require('staged-git-files'); const forceArray = require('force-array'); const awaitify = require('apr-awaitify'); @@ -108,7 +108,10 @@ const staged = async () => { changed, async (modifieds, file) => { const isUnstaged = unstaged.filter(f => f === file.filename).length; - if (file.status === 'Modified' && isUnstaged) { + if ( + (file.status === 'Modified' || file.status === 'Added') && + isUnstaged + ) { modifieds.push(file); } else { await add(file.filename); diff --git a/scripts/run-staged-pkg b/scripts/run-staged-pkg index e6191094..49dc7bad 100755 --- a/scripts/run-staged-pkg +++ b/scripts/run-staged-pkg @@ -1,16 +1,19 @@ #!/usr/bin/env node const { packages } = require('../lerna.json'); -const { readFile } = require('mz/fs'); +const { readFile, exists } = require('mz/fs'); const sgf = require('staged-git-files'); const execa = require('execa'); const awaitify = require('apr-awaitify'); +const asyncFilter = require('apr-filter'); const main = require('apr-main'); const map = require('apr-map'); +const reduce = require('apr-reduce'); const globby = require('globby'); const path = require('path'); const uniq = require('lodash.uniq'); const argv = require('yargs').argv; +const checksum = require('checksum'); const ROOT = path.join(__dirname, '..'); const getStaged = awaitify(sgf); @@ -42,6 +45,71 @@ const run = async scope => { } }; +const runLint = async scope => { + await lint(scope); +}; + +const runTest = async scope => { + await test(scope); +}; + +const getUnstaged = async () => { + const unstaged = await execa('git', ['ls-files', '-m']); + return unstaged.stdout.split('\n'); +}; + +const asyncChecksum = awaitify(checksum.file); + +const add = async filename => execa('git', ['add', filename]); + +const runLintAndGitAdd = async (staged, pkgs) => { + const unstaged = (await getUnstaged()).map(file => path.resolve(ROOT, file)); + + const existing = await asyncFilter( + staged, + async ({ filename }) => await exists(filename) + ); + + const checksums = await map(existing, async file => { + const checksum = await asyncChecksum(file.filename); + return Object.assign({}, file, { checksum }); + }); + + await map(pkgs.map(({ name }) => name), runLint); + + const changed = await asyncFilter( + checksums, + async ({ filename, checksum }) => { + const newChecksum = await asyncChecksum(filename); + return checksum != newChecksum; + } + ); + + const modifieds = await reduce( + changed, + async (modifieds, file) => { + const isUnstaged = unstaged.filter(f => f === file.filename).length; + if ( + (file.status === 'Modified' || file.status === 'Added') && + isUnstaged + ) { + modifieds.push(file); + } else { + await add(file.filename); + } + return modifieds; + }, + [] + ); + + if (modifieds.length) { + modifieds.forEach(modified => + console.log('PARTIALLY STAGED FILE ', modified.filename) + ); + process.exit(1); + } +}; + const gather = async () => { const locations = await globby(packages, { cwd: ROOT @@ -49,19 +117,28 @@ const gather = async () => { const staged = (await getStaged()) .filter(({ status }) => statuses.indexOf(status) >= 0) - .map(({ filename }) => path.resolve(ROOT, filename)); + // .map(({ filename }) => path.resolve(ROOT, filename)); + .map(file => + Object.assign({}, file, { filename: path.resolve(ROOT, file.filename) }) + ); const folders = uniq( locations .map(folder => path.resolve(ROOT, folder)) - .filter(folder => staged.some(i => i.indexOf(folder) >= 0)) + .filter(folder => staged.some(i => i.filename.indexOf(folder) >= 0)) ); const pkgs = await map(folders, async folder => JSON.parse(await readFile(path.join(folder, 'package.json'), 'utf-8')) ); - return map(pkgs.map(({ name }) => name), run); + if (argv.lint) { + await runLintAndGitAdd(staged, pkgs); + } + + if (argv.test) { + await await map(pkgs.map(({ name }) => name), runTest); + } }; main(gather());