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

Question: if multiple globs match do the scripts run in a reliable order? #916

Closed
lm1503109 opened this issue Oct 13, 2020 · 7 comments
Closed

Comments

@lm1503109
Copy link

lm1503109 commented Oct 13, 2020

I can't find clear documentation about this use case so I wanted to clarify:

  • If I have multiple glob patterns that match a single file, will each matching script run in a reliable sequence? (Or do they run in parallel, or in a non-reliable way).

My use case: I want to run eslint on js files, stylelint on scss files, and prettier on all files, but only after linting has finished.

So do I need to do something like this to ensure prettier runs last and on all files:

  "lint-staged": {
    "*.{js,jsx}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.scss": [
      "stylelint --fix --max-warnings 0",
      "prettier --write"
    ],
    "*.{all other file extensions that I want to run through prettier explicitly listed here}": [
      "prettier --write"
    ]
  },

Or can I rely on the later matches running after the prior matches' scripts are finished and do this:

  "lint-staged": {
    "*.{js,jsx}": [
      "eslint --fix",
    ],
    "*.scss": [
      "stylelint --fix --max-warnings 0",
    ],
    "*": [
      "prettier --write"
    ]
  },

Thank you for your help!

@lm1503109 lm1503109 changed the title Clarification: if multiple globs match do the scripts run in a reliable order? Question: if multiple globs match do the scripts run in a reliable order? Oct 13, 2020
@iiroj
Copy link
Member

iiroj commented Oct 14, 2020

Hello, you can try using the --concurrent false option to disable parallel jobs. After this, jobs should run in the order of the keys in the config object (as long as the JavaScript language nowadays ensures the order).

@lm1503109
Copy link
Author

Perfect, that should work great. Apologies for not noticing that option earlier. Thank you for the quick response!

@iiroj
Copy link
Member

iiroj commented Oct 15, 2020

That said, maybe it would be more efficient to not use that setting, and split your globs like in the first example. The inner jobs always run in order, and as long as there are no overlaps, the prettier should run last.

  "lint-staged": {
    "*.(js|jsx)": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.scss": [
      "stylelint --fix --max-warnings 0",
      "prettier --write"
    ],
    "*.!(js|jsx|scss)": [
      "prettier --write"
    ]
  },

@lm1503109
Copy link
Author

Ah that's a great point, I didn't realize exclusion was possible in globs, but this is exactly what I need. Thanks again 👍

@germanfrelo
Copy link
Contributor

germanfrelo commented Apr 19, 2024

That said, maybe it would be more efficient to not use that setting, and split your globs like in the first example. The inner jobs always run in order, and as long as there are no overlaps, the prettier should run last.

  "lint-staged": {
    "*.(js|jsx)": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.scss": [
      "stylelint --fix --max-warnings 0",
      "prettier --write"
    ],
    "*.!(js|jsx|scss)": [
      "prettier --write"
    ]
  },

I tested this and found out that the exclusion pattern "*.!(js|jsx|scss)" does not exclude files like foo.modules.js or foo.modules.scss. What worked for me was !(*.js|*.jsx|*.scss) (and **/!(*.js|*.jsx|*.scss)).

Examples

I only used .html, .css and .js files for simplicity.

Staged files with its contents:

==> foo.html <==
<!DOCTYPE html>
<html>
<head></head>
<body><h1>Foo</h1></body>
</html>
==> foo.css <==
*{display:block;}
==> foo.js <==
const foo="foo"
==> foo.modules.css <==
*{display:block;}
==> foo.modules.js <==
const foo="foo"

This did not work

package.json:

"lint-staged": {
	"*.!(css|js)": [
		"prettier --check"
	]
}

Output after git commit:

✔ Preparing lint-staged...
✔ Hiding unstaged changes to partially staged files...
⚠ Running tasks for staged files...
  ❯ package.json — 7 files
    ❯ *.!(css|js) — 5 files
      ✖ prettier --check [FAILED]
↓ Skipped because of errors from tasks.
↓ Skipped because of errors from tasks.
✔ Reverting to original state because of errors...
✔ Cleaning up temporary files...

✖ prettier --check:
[warn] foo.html
[warn] foo.modules.css
[warn] foo.modules.js
[warn] Code style issues found in 3 files. Run Prettier to fix.
Checking formatting...
husky - pre-commit script failed (code 1)

foo.css and foo.js are excluded, but not foo.modules.css and foo.modules.css.

This worked

package.json:

"lint-staged": {
	"!(*.css|*.js)": [
		"prettier --check"
	]
}

Output after git commit:

✔ Preparing lint-staged...
⚠ Running tasks for staged files...
  ❯ package.json — 7 files
    ❯ !(*.css|*.js) — 3 files
      ✖ prettier --check [FAILED]
↓ Skipped because of errors from tasks.
✔ Reverting to original state because of errors...
✔ Cleaning up temporary files...

✖ prettier --check:
[warn] foo.html
[warn] Code style issues found in the above file. Run Prettier to fix.
Checking formatting...
husky - pre-commit script failed (code 1)

All .css and .js files are excluded.

@iiroj Could you please confirm that?

I also suggest adding this example to the README. I have spent some time searching for this here, in the micromatch repo, and with Google, have but not found anything clear. I think it might be useful for others with the same or similar case.

@iiroj
Copy link
Member

iiroj commented Apr 20, 2024

Thanks @germanfrelo, feel free to open a PR for updating the README!

@germanfrelo
Copy link
Contributor

Here is the PR #1405.

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

3 participants