Hi, :hand:
After upgrading to lint-staged 9 and updated our config file from:
{
"relative": true,
"linters": {
"*.php": [
"./vagrant-wrapper.sh php bin/php-cs-fixer fix --config .php_cs.dist --diff",
"./vagrant-wrapper.sh php bin/phpstan analyse --level 7 --no-ansi --no-progress",
"git add"
],
"assets/**/*.{js,jsx,vue}": [
"eslint --fix",
"git add"
],
"*.{json,yml,yaml,md}": [
"prettier --write",
"git add"
]
}
}
to this (the old way was better, but w/e :disappointed:) :
const path = require('path');
function makeRelativePaths(absolutePaths) {
const cwd = process.cwd();
return absolutePaths.map(file => path.relative(cwd, file));
}
module.exports = {
'*.php': (absolutePaths) => {
const relativePaths = makeRelativePaths(absolutePaths);
return [
`./vagrant-wrapper.sh php bin/php-cs-fixer fix --config .php_cs.dist --diff ${relativePaths.join(' ')}`,
`./vagrant-wrapper.sh php bin/phpstan analyse --level 7 --no-ansi --no-progress ${relativePaths.join(' ')}`,
`git add ${relativePaths.join(' ')}`,
];
},
'assets/**/*.{js,jsx,vue}': (absolutePaths) => {
const relativePaths = makeRelativePaths(absolutePaths);
return [
`eslint --fix ${relativePaths.join(' ')}`,
`git add ${relativePaths.join(' ')}`,
];
},
'*.{json,yml,yaml,md}': (absolutePaths) => {
const relativePaths = makeRelativePaths(absolutePaths);
return [
`prettier --write ${relativePaths.join(' ')}`,
`git add ${relativePaths.join(' ')}`,
];
},
};
It seems that files are not added anymore to the commit after being processed by ESLint, Prettier, PHP-CS-Fixer, [...].

Running git diff, the file has been linted but not commited:

git add in my case)
husky > pre-commit (node v11.5.0)
lint-staged:bin Running `[email protected]` +0ms
lint-staged Loading config using `cosmiconfig` +0ms
lint-staged Successfully loaded config from `/path/to/app/.lintstagedrc.js`:
lint-staged { '*.php': [Function: *.php],
lint-staged 'assets/**/*.{js,jsx,vue}': [Function: assets/**/*.{js,jsx,vue}],
lint-staged '*.{json,yml,yaml,md}': [Function: *.{json,yml,yaml,md}] } +6ms
lint-staged:cfg Validating config +0ms
Running lint-staged with the following config:
{
'*.php': (absolutePaths) => {
const relativePaths = makeRelativePaths(absolutePaths);
return [
`./vagrant-wrapper.sh php bin/php-cs-fixer fix --config .php_cs.dist --diff ${relativePaths.join(' ')}`,
`./vagrant-wrapper.sh php bin/phpstan analyse --level 7 --no-ansi --no-progress ${relativePaths.join(' ')}`,
`git add ${relativePaths.join(' ')}`,
];
},
'assets/**/*.{js,jsx,vue}': (absolutePaths) => {
const relativePaths = makeRelativePaths(absolutePaths);
return [
`eslint --fix ${relativePaths.join(' ')}`,
`git add ${relativePaths.join(' ')}`,
];
},
'*.{json,yml,yaml,md}': (absolutePaths) => {
const relativePaths = makeRelativePaths(absolutePaths);
return [
`prettier --write ${relativePaths.join(' ')}`,
`git add ${relativePaths.join(' ')}`,
];
}
}
lint-staged:run Running all linter scripts +0ms
lint-staged:git Running git command [ 'rev-parse', '--show-toplevel' ] +0ms
lint-staged:run Resolved git directory to be `/path/to/app` +13ms
lint-staged:git Running git command [ 'diff', '--staged', '--diff-filter=ACM', '--name-only' ] +13ms
lint-staged:run Loaded list of staged files in git:
lint-staged:run [ 'assets/app/index.js' ] +8ms
lint-staged:gen-tasks Generating linter tasks +0ms
lint-staged:gen-tasks Generated task:
lint-staged:gen-tasks { pattern: '*.php', commands: [Function: *.php], fileList: [] } +2ms
lint-staged:gen-tasks Generated task:
lint-staged:gen-tasks { pattern: 'assets/**/*.{js,jsx,vue}',
lint-staged:gen-tasks commands: [Function: assets/**/*.{js,jsx,vue}],
lint-staged:gen-tasks fileList: [ '/path/to/app/assets/app/index.js' ] } +2ms
lint-staged:gen-tasks Generated task:
lint-staged:gen-tasks { pattern: '*.{json,yml,yaml,md}',
lint-staged:gen-tasks commands: [Function: *.{json,yml,yaml,md}],
lint-staged:gen-tasks fileList: [] } +0ms
Stashing changes... [started]
lint-staged:git Running git command [ 'status', '--porcelain' ] +16ms
Stashing changes... [skipped]
→ No partially staged files found...
Running linters... [started]
Running tasks for *.php [started]
Running tasks for assets/**/*.{js,jsx,vue} [started]
Running tasks for *.{json,yml,yaml,md} [started]
Running tasks for *.php [skipped]
→ No staged files match *.php
lint-staged:make-cmd-tasks Creating listr tasks for commands [Function: assets/**/*.{js,jsx,vue}] +0ms
Running tasks for *.{json,yml,yaml,md} [skipped]
→ No staged files match *.{json,yml,yaml,md}
eslint --fix [file] [started]
lint-staged:task cmd: eslint +0ms
lint-staged:task args: [ '--fix', 'assets/app/index.js' ] +0ms
lint-staged:task execaOptions: { preferLocal: true, reject: false, shell: false } +0ms
lint-staged:task cmd: git +4ms
lint-staged:task args: [ 'add', 'assets/app/index.js' ] +0ms
lint-staged:task execaOptions: { preferLocal: true, reject: false, shell: false } +0ms
eslint --fix [file] [completed]
Running tasks for assets/**/*.{js,jsx,vue} [completed]
Running linters... [completed]
lint-staged linters were executed successfully! +2s
[chore/deps-js 1deeb9de] test
1 file changed, 3 insertions(+), 1 deletion(-)
lint-staged: 9.0.1That's weird because in debug logs we can see that git add assets/app/index.js... :thinking:
Thanks! :)
Thanks for the clear report! I’ll check it out. One thing that comes to mind is that possibly the commands are run parallel and not sequentially in this case.
Also, your example is a good example of the power of relative: true. Does your setup not work on absolute paths?
Ah, I didn't think about parallelism. That's probably the issue but I don't know how to fix it yet.
Yes relative: true was so much useful, I'm a bit sad that it disappears but that's the life. :stuck_out_tongue_closed_eyes:
Nope it does not work with absolute paths:
vagrant-wrapper.sh, but we didn't use it everywhere because.... we forgot to :smile:)relative: trueI cannot reproduce this. On the lint-staged repo, at commit 6c1e42f, when I add the following .lintstagedrc.js config:
module.exports = {
'*.{js,json,md}': ['prettier --write', 'git add'],
'*.js': files => [`npm run lint:base --fix ${files.join(' ')}`, `git add ${files.join(' ')}`],
'.*{rc, json}': ['jsonlint', 'git add']
}
adding empty lines to a JS file and staging it, running node ./index.js will remove the file from modified and staged, because npm run lint:base --fix will basically just remove the lines.
Also, adding console.log("test"); to a a file, staging it, and running node ./index.js, will leave an console.log('test') edit to staged.
EDIT: Regarding relative, I might add a --relative flag. But that's basically just moving the deprecated advanced configuration to command line flags.
Hum weird, I will take some time this evening to investigate 🧐
Regarding relative, I might add a
--relativeflag. But that's basically just moving the deprecated advanced configuration to command line flags.
That would be really nice. Was there a reason to remove the _advanced_ configuration? :thinking:
When I saw this, I was like ... "well, we will stay with lint-staged 8 forever :tired_face:" and I'm sure I'm not the only one :smile:
I think it's related to relativePaths. For git add to work, pass absolute paths to it that you're getting in the function arguments.
Before adding, --relative, we should address how resolveTaskFn sets a different working directory for git commands vs the rest. Maybe if we add --relative, all the commands should run with the git repo root as the working directory.
EDIT: Or alternatively, the git commands defined in linters could also accept the actual working directory.
I think I found an issue with how tasks are created from a function linter return an array of commands. Currently, it generates a single task with multiple promises, but I refactored it to return an array of tasks instead, hopefully fixing this issue: https://github.com/okonet/lint-staged/pull/650
Can you please re-test with [email protected]? It's hopefully fixed.
Thanks, it works really nice with 9.0.2! :)
I'm closing this issue since it's fixed