0

hi everyone i have a git repo that house 3 folders (individual js projects).

here's my pre-commit hook

#!/bin/bash
echo -e "\033[1;92m Linting Staged Files . . . "

files=$(git diff --diff-filter=d --cached --name-only | grep -E '\.(js|jsx)$')
path=(${files[0]//// })


if [[ $files = "" ]] ; then
  echo -e "\033[1;31m You have no staged file, exiting . . "
  exit 1
fi

for file in $files
do
git show ":$file" | $("./$path/node_modules/.bin/eslint --stdin --stdin-filename $file")
 if [ $? -ne 0 ]; then
   echo -e "\033[1;31m ESLint failed on staged file '$file'. \n Code will not be committed, Please fix your code and try again."
exit 1
 fi
done

BRANCH=`git rev-parse --abbrev-ref HEAD`

if [[ "$BRANCH" == "master" || "$BRANCH" == "develop" ]]; then
 echo "\033[1;31m commiting to $BRANCH is illegal."
 echo "\033[1;31m If you really know what you're doing, then add the argument '-n' to skip this git hook."
 exit 1
fi

exit 0

but it keeps failing at this line git show ":$file" | $("./$path/node_modules/.bin/eslint --stdin --stdin-filename $file")

with an error

.git/hooks/pre-commit: line 17: ./node_modules/.bin/eslint --stdin --stdin-filename sfa/src/SFAApp.js: No such file or directory

i have no idea what i'm doing wrong please help.

Web3 Philosopher
  • 1,296
  • 2
  • 12
  • 18

3 Answers3

1

You're trying to run a command literally named:

./node_modules/.bin/eslint --stdin --stdin-filename sfa/src/SFAApp.js

rather than trying to run a command named:

./node_modules/.bin/eslint

with arguments:

--stdin

and:

--stdin-filename

and:

sfa/src/SFAApp.js

The cure is to fix your double quote placement. Once you do, you will probably have a second problem:

git show ":$file" | $(./$path/node_modules/.bin/eslint --stdin --stdin-filename "$file")

will run the command with the arguments, but then, because it is inside $(...), will take its output as a command. I know nothing of eslint, but it seems likely that this should read:

git show ":$file" | ./$path/node_modules/.bin/eslint --stdin --stdin-filename "$file"

(I'm also not at all sure what the silliness with $path is about. The line path=(${files[0]//// }) sets path to the first file path-name component of the files listed by git diff, e.g., if the output is a/b/c.js, path is set to a.)

torek
  • 448,244
  • 59
  • 642
  • 775
  • like i said the git repo has doesn't hold an actual project but other folders with different projects in them, therefore i have to get the folder name of the files modified and execute the eslint of **that** folder, with the configs of that folder. – Web3 Philosopher Jun 07 '17 at 18:50
  • Aha. Well, that's not going to work if there are changes or new files in `a/dir1/file1.js` *and* `b/dir2/file2.js`. You'd need to pick out the right path *per file* (or perhaps forbid a commit that affects multiple sub-projects). – torek Jun 07 '17 at 18:54
  • I probably need to get the folder path per file instead of just getting the first one. Thanks a lot. – Web3 Philosopher Jun 07 '17 at 18:56
0

Never Mind i fixed the problem by changing

$("./$path/node_modules/.bin/eslint --stdin --stdin-filename $file")

to

./$path/node_modules/.bin/eslint --stdin --stdin-filename $file

TODO: research what $() really means in bash.

Web3 Philosopher
  • 1,296
  • 2
  • 12
  • 18
0

You could use the npm package husky : https://www.npmjs.com/package/husky

By tapping into the git hook for pre-commit you could lint all the staged files exculding the deleted one by the line below

git diff --cached --name-only --diff-filter=d | grep ".js$" | xargs ./node_modules/.bin/eslint

Your .huskyrc will pretty much look like the one below:

module.exports = {
 'hooks': {
   'pre-commit': 'git diff --cached --name-only --diff-filter=d | grep ".js$" | xargs ./node_modules/.bin/eslint'
  }
}
varun kalra
  • 213
  • 2
  • 7