chore(lint-staged): rewritten in JS (#2676)
- simpler code, no need to hack around the shell - no more double formatting - no longer use git stash, simply cache files in memory
This commit is contained in:
parent
2ff25d1f61
commit
7ef314d9f4
@ -1,52 +1,75 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env node
|
||||
|
||||
set -eu
|
||||
|
||||
format_files () {
|
||||
prettier --write "$@"
|
||||
eslint --ignore-pattern '!*' --fix "$@"
|
||||
}
|
||||
test_files () {
|
||||
jest --findRelatedTests --passWithNoTests "$@"
|
||||
const formatFiles = files => {
|
||||
run('./node_modules/.bin/prettier', ['--write'].concat(files))
|
||||
run(
|
||||
'./node_modules/.bin/eslint',
|
||||
['--ignore-pattern', '!*', '--fix'].concat(files)
|
||||
)
|
||||
}
|
||||
const testFiles = files =>
|
||||
run(
|
||||
'./node_modules/.bin/jest',
|
||||
['--findRelatedTests', '--passWithNoTests'].concat(files)
|
||||
)
|
||||
|
||||
# compute the list of staged files we are interested in
|
||||
set --
|
||||
buf=$(mktemp -u)
|
||||
git diff-index --cached --diff-filter=AM --name-only HEAD > "$buf"
|
||||
while IFS= read -r file
|
||||
do
|
||||
case "$file" in
|
||||
*.js)
|
||||
set -- "$@" "$file";;
|
||||
esac
|
||||
done < "$buf"
|
||||
rm -f "$buf"
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
exit
|
||||
fi
|
||||
const { execFileSync, spawnSync } = require('child_process')
|
||||
const { readFileSync, writeFileSync } = require('fs')
|
||||
|
||||
format_files "$@"
|
||||
|
||||
# stash unstaged changes
|
||||
if stash=$(git stash create --keep-index --quiet)
|
||||
then
|
||||
# remove those changes from the worktree
|
||||
git checkout .
|
||||
|
||||
format_files "$@"
|
||||
|
||||
# unstash on exit
|
||||
on_exit () {
|
||||
git read-tree HEAD
|
||||
git checkout $stash "$@"
|
||||
const run = (command, args) => {
|
||||
const { status } = spawnSync(command, args, { stdio: 'inherit' })
|
||||
if (status !== 0) {
|
||||
process.exit(status)
|
||||
}
|
||||
trap 'GIT_INDEX_FILE=$buf on_exit "$@"; rm -f "$buf"' EXIT
|
||||
fi
|
||||
}
|
||||
|
||||
test_files "$@"
|
||||
const gitDiff = (what, args = []) =>
|
||||
execFileSync(
|
||||
'git',
|
||||
[
|
||||
'diff-' + what,
|
||||
'--diff-filter=AM',
|
||||
'--ignore-submodules',
|
||||
'--name-only',
|
||||
].concat(args),
|
||||
{ encoding: 'utf8' }
|
||||
)
|
||||
.split('\n')
|
||||
.filter(_ => _ !== '')
|
||||
const gitDiffFiles = (files = []) => gitDiff('files', files)
|
||||
const gitDiffIndex = () => gitDiff('index', ['--cached', 'HEAD'])
|
||||
|
||||
# add any changes made by the commands
|
||||
git add "$@"
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const files = gitDiffIndex().filter(_ => _.endsWith('.js'))
|
||||
if (files.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
// save the list of files with unstaged changes
|
||||
let unstaged = gitDiffFiles(files)
|
||||
|
||||
// format all files
|
||||
formatFiles(files)
|
||||
|
||||
if (unstaged.length !== 0) {
|
||||
// refresh the list of files with unstaged changes, maybe the
|
||||
// changes have been reverted by the formatting
|
||||
run('git', ['update-index', '-q', '--refresh'])
|
||||
unstaged = gitDiffFiles(unstaged)
|
||||
|
||||
if (unstaged.length !== 0) {
|
||||
const contents = unstaged.map(name => readFileSync(name))
|
||||
process.on('exit', () =>
|
||||
unstaged.map((name, i) => writeFileSync(name, contents[i]))
|
||||
)
|
||||
run('git', ['checkout'].concat(unstaged))
|
||||
formatFiles(unstaged)
|
||||
}
|
||||
}
|
||||
|
||||
testFiles(files)
|
||||
|
||||
run('git', ['add'].concat(files))
|
||||
|
Loading…
Reference in New Issue
Block a user