Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lint-staged does not detect changed files, skips scripts #1415

Closed
trusktr opened this issue May 14, 2024 · 4 comments
Closed

lint-staged does not detect changed files, skips scripts #1415

trusktr opened this issue May 14, 2024 · 4 comments

Comments

@trusktr
Copy link

trusktr commented May 14, 2024

Description

lint-staged is not running scripts for modified files.

Steps to reproduce

Here's my husky `pre-commit` hook:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# If a previous commit attempt's stash still exists, notify, and exit.
(git stash list | grep COMMIT_HOOK_STASH) && echo "A previous git stash named "COMMIT_HOOK_STASH" exists. Please handle and remove the stash then try again." && exit 1

echo ""
echo "Undo dist changes..."
echo ""
git reset dist
git checkout dist

echo ""
echo "Stash unstaged/untracked files if any..."
echo ""
# commit staged changes temporarily
git commit --no-verify -m "TMP_COMMIT_HOOK_COMMIT"
# stash only untstaged and untracked files
git stash save -u COMMIT_HOOK_STASH
git reset --soft HEAD~

echo ""
echo "Status after stash:"
echo ""
git status

# See .lintstagedrc.js for the steps that will run at this point.
npx lint-staged --verbose --debug

# NOTE: After this, the post-commit hook will unstash the COMMIT_HOOK_STASH. See .husky/post-commit.
Here's my `.lintstagedrc.js` file:
const buildSteps = [
	"echo; echo 'Building src/'; echo",
	'npm run build:clean',
	"echo; echo 'Status after src/ build:'; echo",
	'git status',
	"echo; echo 'Staging dist/'; echo",
	'git add dist',
	"echo; echo 'Status after staging:'; echo",
	'git status',
	'exit 1',
]

export default {
	'./src/**/*': () => buildSteps,
	'./packages/**/*': () => ['npm run typecheck'],
}
Here's my husky `pre-commit` hook:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# unstash only if there was a stash
(git stash list | grep COMMIT_HOOK_STASH) && git stash pop

Debug Logs

Here's the output of `git commit`, which includes all output from the pre-commit hook, lint-staged, and the post-commit hook
❯ git commit -m "update cli to fix it from deleting JSX types in dist/, delete unused src/lib/ files" 

Undo dist changes...

Unstaged changes after reset:
D       dist/lib/three/examples/jsm/curves/NURBSCurve.d.ts
D       dist/lib/three/examples/jsm/curves/NURBSCurve.d.ts.map
D       dist/lib/three/examples/jsm/curves/NURBSCurve.js
D       dist/lib/three/examples/jsm/curves/NURBSCurve.js.map
D       dist/lib/three/examples/jsm/curves/NURBSUtils.d.ts
D       dist/lib/three/examples/jsm/curves/NURBSUtils.d.ts.map
D       dist/lib/three/examples/jsm/curves/NURBSUtils.js
D       dist/lib/three/examples/jsm/curves/NURBSUtils.js.map
Updated 8 paths from the index

Stash unstaged/untracked files if any...

[fix-dist-had-no-jsx-types e6518699] TMP_COMMIT_HOOK_COMMIT
 10 files changed, 188 insertions(+), 618 deletions(-)
 delete mode 100644 src/lib/three/README.md
 delete mode 100755 src/lib/three/examples/jsm/curves/NURBSCurve.d.ts
 delete mode 100644 src/lib/three/examples/jsm/curves/NURBSCurve.js
 delete mode 100755 src/lib/three/examples/jsm/curves/NURBSUtils.d.ts
 delete mode 100644 src/lib/three/examples/jsm/curves/NURBSUtils.js
Saved working directory and index state On fix-dist-had-no-jsx-types: COMMIT_HOOK_STASH

Status after stash:

On branch fix-dist-had-no-jsx-types
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   .husky/pre-commit
        modified:   .lintstagedrc.js
        modified:   package.json
        modified:   packages/cli
        deleted:    src/lib/three/README.md
        deleted:    src/lib/three/examples/jsm/curves/NURBSCurve.d.ts
        deleted:    src/lib/three/examples/jsm/curves/NURBSCurve.js
        deleted:    src/lib/three/examples/jsm/curves/NURBSUtils.d.ts
        deleted:    src/lib/three/examples/jsm/curves/NURBSUtils.js
        modified:   yarn.lock

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
  (commit or discard the untracked or modified content in submodules)
        modified:   packages/docsifyjs+docsify (untracked content)
        modified:   packages/element-behaviors (modified content)

  lint-staged:bin Running `lint-staged@15.2.2` on Node.js v20.6.1 (darwin) +0ms
  lint-staged:bin Options parsed from command-line: {
  allowEmpty: false,
  concurrent: true,
  configPath: undefined,
  cwd: undefined,
  debug: true,
  diff: undefined,
  diffFilter: undefined,
  maxArgLength: undefined,
  quiet: false,
  relative: false,
  shell: false,
  stash: true,
  hidePartiallyStaged: true,
  verbose: true
} +0ms
  lint-staged:validateOptions Validating options... +0ms
  lint-staged:validateOptions Validated options! +0ms
  lint-staged Unset GIT_LITERAL_PATHSPECS (was `undefined`) +0ms
  lint-staged:runAll Running all linter scripts... +0ms
  lint-staged:runAll Using working directory `/Users/trusktr/src/lume+lume` +0ms
  lint-staged:resolveGitRepo Resolving git repo from `/Users/trusktr/src/lume+lume` +0ms
  lint-staged:resolveGitRepo Unset GIT_DIR (was `undefined`) +0ms
  lint-staged:resolveGitRepo Unset GIT_WORK_TREE (was `undefined`) +0ms
  lint-staged:execGit Running git command [ 'rev-parse', '--show-prefix' ] +0ms
  lint-staged:resolveGitRepo Resolved git directory to be `/Users/trusktr/src/lume+lume` +7ms
  lint-staged:resolveGitRepo Resolved git config directory to be `/Users/trusktr/src/lume+lume/.git` +1ms
  lint-staged:execGit Running git command [ 'log', '-1' ] +8ms
  lint-staged:execGit Running git command [ 'diff', '--name-only', '-z', '--diff-filter=ACMR', '--staged' ] +5ms
  lint-staged:runAll Loaded list of staged files in git:
  lint-staged:runAll [
  lint-staged:runAll   '/Users/trusktr/src/lume+lume/.husky/pre-commit',
  lint-staged:runAll   '/Users/trusktr/src/lume+lume/.lintstagedrc.js',
  lint-staged:runAll   '/Users/trusktr/src/lume+lume/package.json',
  lint-staged:runAll   '/Users/trusktr/src/lume+lume/packages/cli',
  lint-staged:runAll   '/Users/trusktr/src/lume+lume/yarn.lock'
  lint-staged:runAll ] +20ms
  lint-staged:searchConfigs Searching for configuration files... +0ms
  lint-staged:execGit Running git command [ 'ls-files', '-z', '--full-name', '-t' ] +7ms
  lint-staged:execGit Running git command [
  'ls-files',
  '-z',
  '--full-name',
  '-t',
  '--others',
  '--exclude-standard'
] +1ms
  lint-staged:searchConfigs Found possible config files: [
  '/Users/trusktr/src/lume+lume/examples/react-typescript/package.json',
  '/Users/trusktr/src/lume+lume/examples/react/package.json',
  '/Users/trusktr/src/lume+lume/.lintstagedrc.js',
  '/Users/trusktr/src/lume+lume/package.json'
] +9ms
  lint-staged:loadConfig Loading configuration from `/Users/trusktr/src/lume+lume/examples/react-typescript/package.json`... +0ms
  lint-staged:loadConfig Loading configuration from `/Users/trusktr/src/lume+lume/examples/react/package.json`... +0ms
  lint-staged:loadConfig Loading configuration from `/Users/trusktr/src/lume+lume/.lintstagedrc.js`... +0ms
  lint-staged:loadConfig Loading configuration from `/Users/trusktr/src/lume+lume/package.json`... +0ms
  lint-staged:loadConfig Successfully loaded config from `/Users/trusktr/src/lume+lume/package.json`:
  lint-staged:loadConfig null +0ms
  lint-staged:loadConfig Successfully loaded config from `/Users/trusktr/src/lume+lume/examples/react/package.json`:
  lint-staged:loadConfig null +2ms
  lint-staged:loadConfig Successfully loaded config from `/Users/trusktr/src/lume+lume/examples/react-typescript/package.json`:
  lint-staged:loadConfig null +0ms
  lint-staged:loadConfig Successfully loaded config from `/Users/trusktr/src/lume+lume/.lintstagedrc.js`:
  lint-staged:loadConfig {
  lint-staged:loadConfig   './src/**/*': [Function: ./src/**/*],
  lint-staged:loadConfig   './packages/**/*': [Function: ./packages/**/*]
  lint-staged:loadConfig } +2ms
  lint-staged:validateConfig Validating config from `/Users/trusktr/src/lume+lume/.lintstagedrc.js`... +0ms
  lint-staged:validateConfig Validated config from `/Users/trusktr/src/lume+lume/.lintstagedrc.js`: +0ms
  lint-staged:validateConfig {
  lint-staged:validateConfig   './src/**/*': [Function: ./src/**/*],
  lint-staged:validateConfig   './packages/**/*': [Function: ./packages/**/*]
  lint-staged:validateConfig } +0ms
  lint-staged:searchConfigs Found 1 config files +4ms
  lint-staged:groupFilesByConfig Grouping 5 files by 1 configurations +0ms
  lint-staged:chunkFiles Resolved an argument string length of 215 characters from 5 files +0ms
  lint-staged:chunkFiles Creating 1 chunks for maxArgLength of 131072 +0ms
  lint-staged:generateTasks Generating linter tasks +0ms
  lint-staged:generateTasks Generated task: 
  lint-staged:generateTasks {
  lint-staged:generateTasks   pattern: './src/**/*',
  lint-staged:generateTasks   commands: [Function: ./src/**/*],
  lint-staged:generateTasks   fileList: []
  lint-staged:generateTasks } +1ms
  lint-staged:generateTasks Generated task: 
  lint-staged:generateTasks {
  lint-staged:generateTasks   pattern: './packages/**/*',
  lint-staged:generateTasks   commands: [Function: ./packages/**/*],
  lint-staged:generateTasks   fileList: [ '/Users/trusktr/src/lume+lume/packages/cli' ]
  lint-staged:generateTasks } +0ms
  lint-staged:makeCmdTasks Creating listr tasks for commands [Function: ./src/**/*] +0ms
  lint-staged:makeCmdTasks Creating listr tasks for commands [Function: ./packages/**/*] +0ms
  lint-staged:resolveTaskFn cmd: echo; +0ms
  lint-staged:resolveTaskFn args: [ 'echo', 'Building src/', ';', 'echo' ] +0ms
  lint-staged:resolveTaskFn execaOptions: {
  cwd: '/Users/trusktr/src/lume+lume',
  preferLocal: true,
  reject: false,
  shell: false,
  stdin: 'ignore'
} +0ms
  lint-staged:resolveTaskFn cmd: npm +0ms
  lint-staged:resolveTaskFn args: [ 'run', 'build:clean' ] +0ms
  lint-staged:resolveTaskFn execaOptions: {
  cwd: '/Users/trusktr/src/lume+lume',
  preferLocal: true,
  reject: false,
  shell: false,
  stdin: 'ignore'
} +0ms
  lint-staged:resolveTaskFn cmd: echo; +0ms
  lint-staged:resolveTaskFn args: [ 'echo', 'Status after src/ build:', ';', 'echo' ] +0ms
  lint-staged:resolveTaskFn execaOptions: {
  cwd: '/Users/trusktr/src/lume+lume',
  preferLocal: true,
  reject: false,
  shell: false,
  stdin: 'ignore'
} +0ms
  lint-staged:resolveTaskFn cmd: git +0ms
  lint-staged:resolveTaskFn args: [ 'status' ] +0ms
  lint-staged:resolveTaskFn execaOptions: {
  cwd: '/Users/trusktr/src/lume+lume',
  preferLocal: true,
  reject: false,
  shell: false,
  stdin: 'ignore'
} +0ms
  lint-staged:resolveTaskFn cmd: echo; +0ms
  lint-staged:resolveTaskFn args: [ 'echo', 'Staging dist/', ';', 'echo' ] +0ms
  lint-staged:resolveTaskFn execaOptions: {
  cwd: '/Users/trusktr/src/lume+lume',
  preferLocal: true,
  reject: false,
  shell: false,
  stdin: 'ignore'
} +0ms
  lint-staged:resolveTaskFn cmd: git +0ms
  lint-staged:resolveTaskFn args: [ 'add', 'dist' ] +0ms
  lint-staged:resolveTaskFn execaOptions: {
  cwd: '/Users/trusktr/src/lume+lume',
  preferLocal: true,
  reject: false,
  shell: false,
  stdin: 'ignore'
} +0ms
  lint-staged:resolveTaskFn cmd: echo; +0ms
  lint-staged:resolveTaskFn args: [ 'echo', 'Status after staging:', ';', 'echo' ] +0ms
  lint-staged:resolveTaskFn execaOptions: {
  cwd: '/Users/trusktr/src/lume+lume',
  preferLocal: true,
  reject: false,
  shell: false,
  stdin: 'ignore'
} +0ms
  lint-staged:resolveTaskFn cmd: git +0ms
  lint-staged:resolveTaskFn args: [ 'status' ] +0ms
  lint-staged:resolveTaskFn execaOptions: {
  cwd: '/Users/trusktr/src/lume+lume',
  preferLocal: true,
  reject: false,
  shell: false,
  stdin: 'ignore'
} +0ms
  lint-staged:resolveTaskFn cmd: exit +0ms
  lint-staged:resolveTaskFn args: [ '1' ] +0ms
  lint-staged:resolveTaskFn execaOptions: {
  cwd: '/Users/trusktr/src/lume+lume',
  preferLocal: true,
  reject: false,
  shell: false,
  stdin: 'ignore'
} +0ms
  lint-staged:resolveTaskFn cmd: npm +0ms
  lint-staged:resolveTaskFn args: [ 'run', 'typecheck' ] +0ms
  lint-staged:resolveTaskFn execaOptions: {
  cwd: '/Users/trusktr/src/lume+lume',
  preferLocal: true,
  reject: false,
  shell: false,
  stdin: 'ignore'
} +0ms
  lint-staged:chunkFiles Resolved an argument string length of 41 characters from 1 files +2ms
  lint-staged:chunkFiles Creating 1 chunks for maxArgLength of 131072 +0ms
[STARTED] Preparing lint-staged...
  lint-staged:GitWorkflow Backing up original state... +0ms
  lint-staged:GitWorkflow Getting partially staged files... +0ms
  lint-staged:execGit Running git command [ 'status', '-z' ] +18ms
  lint-staged:GitWorkflow Found partially staged files: [] +98ms
  lint-staged:GitWorkflow Backing up merge state... +0ms
  lint-staged:file Reading file `/Users/trusktr/src/lume+lume/.git/MERGE_HEAD` +0ms
  lint-staged:file Reading file `/Users/trusktr/src/lume+lume/.git/MERGE_MODE` +0ms
  lint-staged:file Reading file `/Users/trusktr/src/lume+lume/.git/MERGE_MSG` +0ms
  lint-staged:file File `/Users/trusktr/src/lume+lume/.git/MERGE_HEAD` doesn't exist, ignoring... +0ms
  lint-staged:file File `/Users/trusktr/src/lume+lume/.git/MERGE_MODE` doesn't exist, ignoring... +0ms
  lint-staged:file File `/Users/trusktr/src/lume+lume/.git/MERGE_MSG` doesn't exist, ignoring... +0ms
  lint-staged:GitWorkflow Done backing up merge state! +0ms
  lint-staged:GitWorkflow Getting deleted files... +0ms
  lint-staged:execGit Running git command [ 'ls-files', '--deleted' ] +98ms
  lint-staged:GitWorkflow Found deleted files: [] +5ms
  lint-staged:execGit Running git command [ 'stash', 'create' ] +5ms
  lint-staged:execGit Running git command [
  'stash',
  'store',
  '--quiet',
  '--message',
  'lint-staged automatic backup',
  '1de95f7cff14c923beaeae6e9ee8c2559fd04a1d'
] +88ms
  lint-staged:GitWorkflow Done backing up original state! +92ms
[COMPLETED] Preparing lint-staged...
[STARTED] Running tasks for staged files...
[STARTED] .lintstagedrc.js — 5 files
[STARTED] ./src/**/* — 0 files
[STARTED] ./packages/**/* — 1 file
[SKIPPED] ./src/**/* — no files
[STARTED] npm run typecheck
[COMPLETED] npm run typecheck
[COMPLETED] ./packages/**/* — 1 file
[COMPLETED] .lintstagedrc.js — 5 files
[COMPLETED] Running tasks for staged files...
[STARTED] Applying modifications from tasks...
  lint-staged:GitWorkflow Adding task modifications to index... +2s
  lint-staged:execGit Running git command [ 'add', '--', '/Users/trusktr/src/lume+lume/packages/cli' ] +2s
  lint-staged:GitWorkflow Done adding task modifications to index! +9ms
  lint-staged:execGit Running git command [ 'diff', '--name-only', '-z', '--diff-filter=ACMR', '--staged' ] +9ms
[COMPLETED] Applying modifications from tasks...
[STARTED] Cleaning up temporary files...
  lint-staged:GitWorkflow Dropping backup stash... +5ms
  lint-staged:execGit Running git command [ 'stash', 'list' ] +5ms
  lint-staged:execGit Running git command [ 'stash', 'drop', '--quiet', '0' ] +7ms
  lint-staged:GitWorkflow Done dropping backup stash! +12ms
[COMPLETED] Cleaning up temporary files...
  lint-staged Tasks were executed successfully! +2s

→ npm run typecheck:

> lume@0.3.0-alpha.42 typecheck
> lume typecheck

stash@{0}: On fix-dist-had-no-jsx-types: COMMIT_HOOK_STASH
Already up to date.
On branch fix-dist-had-no-jsx-types
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
  (commit or discard the untracked or modified content in submodules)
        modified:   packages/docsifyjs+docsify (untracked content)
        modified:   packages/element-behaviors (modified content)

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        dist/behaviors/mesh-behaviors/materials/types.d.ts dist/lights/index.react-jsx.d.ts
        dist/cameras/CameraRig.react-jsx.d.ts              dist/meshes/Box.react-jsx.d.ts
        dist/cameras/PerspectiveCamera.react-jsx.d.ts      dist/meshes/InstancedMesh.react-jsx.d.ts
        dist/cameras/index.react-jsx.d.ts                  dist/meshes/Line.react-jsx.d.ts
        dist/core/ClipPlane.react-jsx.d.ts                 dist/meshes/Mesh.react-jsx.d.ts
        dist/core/Element3D.react-jsx.d.ts                 dist/meshes/MixedPlane.react-jsx.d.ts
        dist/core/Node.react-jsx.d.ts                      dist/meshes/Plane.react-jsx.d.ts
        dist/core/Scene.react-jsx.d.ts                     dist/meshes/Points.react-jsx.d.ts
        dist/core/index.react-jsx.d.ts                     dist/meshes/RoundedRectangle.react-jsx.d.ts
        dist/examples/FlickeringOrb.react-jsx.d.ts         dist/meshes/Shape.react-jsx.d.ts
        dist/examples/FlickeringOrbs.react-jsx.d.ts        dist/meshes/Sphere.react-jsx.d.ts
        dist/examples/LoadingIcon.react-jsx.d.ts           dist/meshes/Torus.react-jsx.d.ts
        dist/examples/index.react-jsx.d.ts                 dist/meshes/index.react-jsx.d.ts
        dist/index.react-jsx.d.ts                          dist/models/ColladaModel.react-jsx.d.ts
        dist/layouts/AutoLayoutNode.react-jsx.d.ts         dist/models/FbxModel.react-jsx.d.ts
        dist/layouts/Autolayout.react-jsx.d.ts             dist/models/GltfModel.react-jsx.d.ts
        dist/layouts/CubeLayout.react-jsx.d.ts             dist/models/ObjModel.react-jsx.d.ts
        dist/layouts/index.react-jsx.d.ts                  dist/models/TdsModel.react-jsx.d.ts
        dist/lights/AmbientLight.react-jsx.d.ts            dist/models/index.react-jsx.d.ts
        dist/lights/DirectionalLight.react-jsx.d.ts        dist/textures/TextureProjector.react-jsx.d.ts
        dist/lights/PointLight.react-jsx.d.ts              dist/textures/index.react-jsx.d.ts
        dist/lights/SpotLight.react-jsx.d.ts

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (186e767e6dbe9593dbb905285d1774b718bfc447)
[fix-dist-had-no-jsx-types d5dd1a23] update cli to fix it from deleting JSX types in dist/, delete unused src/lib/ files
 10 files changed, 188 insertions(+), 618 deletions(-)
 delete mode 100644 src/lib/three/README.md
 delete mode 100755 src/lib/three/examples/jsm/curves/NURBSCurve.d.ts
 delete mode 100644 src/lib/three/examples/jsm/curves/NURBSCurve.js
 delete mode 100755 src/lib/three/examples/jsm/curves/NURBSUtils.d.ts
 delete mode 100644 src/lib/three/examples/jsm/curves/NURBSUtils.js

In particular I see this:

[STARTED] ./src/**/* — 0 files
[STARTED] ./packages/**/* — 1 file
[SKIPPED] ./src/**/* — no files

and you can see in the git status output some stuff like this:

        deleted:    src/lib/three/examples/jsm/curves/NURBSCurve.d.ts

so I am expecting src/**/* to match. It looks like the packages/**/* pattern is being matched, but the src/**/* pattern is not. I expected lint-staged to fail due to the exit 1 it should run for src/**/*.

Is lint-staged not matching against deleted files?

Environment

  • OS: macOS Sonoma 14.1.1 (23B81)
  • Node.js: 20.6.1
  • npm: 10.5.2
  • lint-staged: 15.2.2
@trusktr
Copy link
Author

trusktr commented May 14, 2024

Is lint-staged not matching against deleted files?

Yep, that's the problem. lint-staged is not matching against files that have been deleted. I verified by making a modification to another file in src/, and then it runs the scripts for src/**/*.

This is not good because it means if I delete files in src/ they lint-staged is silently failing to run needed scripts (f.e. a build script needs to update dist/ based on src/).

This can lead to unexpectedly publishing versions of packages on npm with dist/ folder in incorrect state (and most people are probably not going to test deletion-only commits to realize lint-staged is ignoring them).

@trusktr trusktr changed the title lint-staged seems to not detect changed files, skips running scripts lint-staged does not detect changed files, skips scripts May 14, 2024
@trusktr
Copy link
Author

trusktr commented May 14, 2024

For now the workaround is I found some other file I could make a change to (without deleting). Now I just need to try and remember this each time I commit; the only reason I discovered it was because I was investigating why the build wasn't outputting certain files, then I decided to test the commit to ensure a version update would include files and discovered the additional lint-staged issue (first my build was discluding some files).

@iiroj
Copy link
Member

iiroj commented May 15, 2024

You can try overriding the default --diff-filter option to also include deleted files.

EDIT: from the readme:

--diff-filter: By default only files that are added, copied, modified, or renamed are included. Use this flag to override the default ACMR value with something else: added (A), copied (C), deleted (D), modified (M), renamed (R), type changed (T), unmerged (U), unknown (X), or pairing broken (B). See also the git diff docs for --diff-filter.

@iiroj
Copy link
Member

iiroj commented May 15, 2024

We don't include deleted files by default because the most common linters ESLint and Prettier don't really work when supplied paths that don't exist anymore.

@iiroj iiroj closed this as completed May 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants