{"id":17055027,"url":"https://github.com/hyiso/lint_staged","last_synced_at":"2025-10-08T15:26:35.010Z","repository":{"id":65742095,"uuid":"598517177","full_name":"hyiso/lint_staged","owner":"hyiso","description":" Run linters on git staged files for your Flutter and Dart projects. Inspired by JavaScript lint-staged library","archived":false,"fork":false,"pushed_at":"2024-06-11T03:16:29.000Z","size":160,"stargazers_count":8,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-01T04:47:58.728Z","etag":null,"topics":["dart","flutter","flutter-apps","flutter-package","git","githooks","lint-staged"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/lint_staged","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hyiso.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-02-07T09:20:50.000Z","updated_at":"2025-03-26T07:39:22.000Z","dependencies_parsed_at":"2024-06-11T04:41:57.047Z","dependency_job_id":null,"html_url":"https://github.com/hyiso/lint_staged","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/hyiso/lint_staged","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyiso%2Flint_staged","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyiso%2Flint_staged/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyiso%2Flint_staged/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyiso%2Flint_staged/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyiso","download_url":"https://codeload.github.com/hyiso/lint_staged/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyiso%2Flint_staged/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278967048,"owners_count":26077184,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","flutter","flutter-apps","flutter-package","git","githooks","lint-staged"],"created_at":"2024-10-14T10:16:30.484Z","updated_at":"2025-10-08T15:26:34.976Z","avatar_url":"https://github.com/hyiso.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lint_staged\n\n[![Pub Version](https://img.shields.io/pub/v/lint_staged?color=blue)](https://pub.dev/packages/lint_staged)\n[![popularity](https://img.shields.io/pub/popularity/lint_staged?logo=dart)](https://pub.dev/packages/lint_staged/score)\n[![likes](https://img.shields.io/pub/likes/lint_staged?logo=dart)](https://pub.dev/packages/lint_staged/score)\n[![CI](https://github.com/hyiso/lint_staged/actions/workflows/ci.yml/badge.svg)](https://github.com/hyiso/lint_staged/actions/workflows/ci.yml)\n\nRun linters on git staged files for your Flutter and Dart projects.\n\nInspired by Javascript [lint-staged](https://github.com/okonet/lint-staged)\n\n## Why\n\nLinting makes more sense when run before committing your code. By doing so you can ensure no errors go into the repository and enforce code style. But running a lint process on a whole project is slow, and linting results can be irrelevant. Ultimately you only want to lint files that will be committed.\n\nThis project contains a script that will run arbitrary shell tasks with a list of staged files as an argument, filtered by a specified glob pattern.\n\n## Installation and setup\n\nTo install *lint_staged* in the recommended way, you need to:\n\n1. Install *lint_staged* itself:\n   - `dart pub add --dev lint_staged`\n1. Set up the `pre-commit` git hook to run *lint_staged*\n   - [Husky](https://github.com/hyiso/husky) is a recommended choice for configuring git hooks\n   - Read more about git hooks [here](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)\n1. Configure *lint_staged* to run linters and other tasks:\n   - for example, add following in `pubspec.yaml`: \n   ```yaml\n   lint_staged:\n     'lib/**.dart': dart format --fix \u0026\u0026 dart fix --apply\n   ```\n   to automatically format \u0026 fix all staged dart files.\n   - See [Configuration](#Configuration) for more info\n\nDon't forget to commit changes to `pubspec.yaml` and `.husky` to share this setup with your team!\n\nNow change a few files, `git add` or `git add --patch` some of them to your commit, and try to `git commit` them.\n\nSee [examples](#examples) and [configuration](#configuration) for more information.\n\n## Changelog\n\nSee [CHANGELOG.md](https://github.com/hyiso/lint_staged/blob/main/CHANGELOG.md).\n\n## Command line flags\n\n```\n❯ dart lint_staged --help\nUsage: lint_staged [options]\n\nOptions:\n  --allow-empty                      allow empty commits when tasks revert all staged changes (default: false)\n  --diff [string]                    override the default \"--staged\" flag of \"git diff\" to get list of files. Implies\n                                     \"--no-stash\".\n  --diff-filter [string]             override the default \"--diff-filter=ACMR\" flag of \"git diff\" to get list of files\n  --no-stash                         disable the backup stash, and do not revert in case of errors\n  --processes [int]                  limit the maximum processes can run at the same time.\n```\n\n- **`--allow-empty`**: By default, when linter tasks undo all staged changes, lint_staged will exit with an error and abort the commit. Use this flag to allow creating empty git commits.\n- **`--diff`**: By default linters are filtered against all files staged in git, generated from `git diff --staged`. This option allows you to override the `--staged` flag with arbitrary revisions. For example to get a list of changed files between two branches, use `--diff=\"branch1...branch2\"`. You can also read more from about [git diff](https://git-scm.com/docs/git-diff) and [gitrevisions](https://git-scm.com/docs/gitrevisions). This option also implies `--no-stash`.\n- **`--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](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203).\n- **`--no-stash`**: By default a backup stash will be created before running the tasks, and all task modifications will be reverted in case of an error. This option will disable creating the stash, and instead leave all modifications in the index when aborting the commit. Can be re-enabled with `--stash`\n\n## Configuration\n\n*Lint_staged* must be configured in your `pubspec.yaml`\n\n#### `pubspec.yaml` example:\n\n```yaml\nlint_staged:\n  'lib/**.dart': your-cmd\n```\n\nThis config will execute `your-cmd` with staged dart files passed as arguments.\n\n## Filtering files\n\nLinter commands work on a subset of all staged files, defined by a _glob pattern_. lint_staged uses [glob](https://github.com/dart-lang/glob) for matching files with the following [syntax](https://github.com/dart-lang/glob/blob/master/README.md#syntax):\n### Match any characters in a filename: `*`\n\nThe `*` character matches zero or more of any character other than `/`. This\nmeans that it can be used to match all files in a given directory that match a\npattern without also matching files in a subdirectory. For example, `lib/*.dart`\nwill match `lib/glob.dart` but not `lib/src/utils.dart`.\n\n### Match any characters across directories: `**`\n\n`**` is like `*`, but matches `/` as well. It's useful for matching files or\nlisting directories recursively. For example, `lib/**.dart` will match both\n`lib/glob.dart` and `lib/src/utils.dart`.\n\nIf `**` appears at the beginning of a glob, it won't match absolute paths or\npaths beginning with `../`. For example, `**.dart` won't match `/foo.dart`,\nalthough `/**.dart` will. This is to ensure that listing a bunch of paths and\nchecking whether they match a glob produces the same results as listing that\nglob. In the previous example, `/foo.dart` wouldn't be listed for `**.dart`, so\nit shouldn't be matched by it either.\n\nThis is an extension to Bash glob syntax that's widely supported by other glob\nimplementations.\n\n### Match any single character: `?`\n\nThe `?` character matches a single character other than `/`. Unlike `*`, it\nwon't match any more or fewer than one character. For example, `test?.dart` will\nmatch `test1.dart` but not `test10.dart` or `test.dart`.\n\n### Match a range of characters: `[...]`\n\nThe `[...]` construction matches one of several characters. It can contain\nindividual characters, such as `[abc]`, in which case it will match any of those\ncharacters; it can contain ranges, such as `[a-zA-Z]`, in which case it will\nmatch any characters that fall within the range; or it can contain a mix of\nboth. It will only ever match a single character. For example,\n`test[a-zA-Z_].dart` will match `testx.dart`, `testA.dart`, and `test_.dart`,\nbut not `test-.dart`.\n\nIf it starts with `^` or `!`, the construction will instead match all characters\n_not_ mentioned. For example, `test[^a-z].dart` will match `test1.dart` but not\n`testa.dart`.\n\nThis construction never matches `/`.\n\n### Match one of several possibilities: `{...,...}`\n\nThe `{...,...}` construction matches one of several options, each of which is a\nglob itself. For example, `lib/{*.dart,src/*}` matches `lib/glob.dart` and\n`lib/src/data.txt`. It can contain any number of options greater than one, and\ncan even contain nested options.\n\nThis is an extension to Bash glob syntax, although it is supported by other\nlayers of Bash and is often used in conjunction with globs.\n\n### Escaping a character: `\\`\n\nThe `\\` character can be used in any context to escape a character that would\notherwise be semantically meaningful. For example, `\\*.dart` matches `*.dart`\nbut not `test.dart`.\n\n### Syntax errors\n\nBecause they're used as part of the shell, almost all strings are valid Bash\nglobs. This implementation is more picky, and performs some validation to ensure\nthat globs are meaningful. For instance, unclosed `{` and `[` are disallowed.\n\n### Reserved syntax: `(...)`\n\nParentheses are reserved in case this package adds support for Bash extended\nglobbing in the future. For the time being, using them will throw an error\nunless they're escaped.\n\n### Exclude pattern: `!`\n\nFor any files you wish to exclude, use the same glob pattern but prepend it with `!`\n\n```\nlint_staged:\n  'lib/**.dart': your-cmd\n  '!lib/**.g.dart': your-cmd\n```\n\nThis would include all .dart files, but exclude .g.dart files.\n\n\n## What commands are supported?\n\nSupported are any executables installed locally or globally via `pub` as well as any executable from your \\$PATH.\n\n\u003e Using globally installed scripts is discouraged, since lint_staged may not work for someone who doesn't have it installed.\n\n`lint_staged` uses `Process.run` to locate locally installed scripts.\n\nPass arguments to your commands separated by space as you would do in the shell. See [examples](#examples) below.\n\n## Running multiple commands in a sequence\n\nYou can run multiple commands in a sequence on every glob. To do so, pass a list of commands joined with ` \u0026\u0026 `. This is useful for running autoformatting tools like `dart format` or `dart analyze` but can be used for any arbitrary sequences.\n\nFor example:\n\n```yaml\nlint_staged:\n  'lib/**.dart': dart format --fix \u0026\u0026 dart fix --apply\n```\n\ngoing to execute `dart format --fix` and if it exits with `0` code, it will execute `dart fix --apply` on all staged dart files.\n\n## Examples\n\nAll examples assume you've already set up lint_staged in the `pubspec.yaml` file and [husky](https://github.com/hyiso/husky) in its own config file.\n\n```yaml\n  lint_staged:\n```\n\nIn `.husky/pre-commit`\n\n```shell\n#!/usr/bin/env sh\n. \"$(dirname \"$0\")/_/husky.sh\"\n\ndart run lint_staged\n```\n\n_Note: we don't pass a path as an argument for the runners. This is important since lint_staged will do this for you._\n\n### Automatically fix analyze issues for `.dart` running as a pre-commit hook\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to expand\u003c/summary\u003e\n\n```yaml\nlint_staged:\n  'lib/**.dart': dart fix --apply\n```\n\n\u003c/details\u003e\n\n### Automatically fix code format and add to commit\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to expand\u003c/summary\u003e\n\n```yaml\nlint_staged:\n  'lib/**.dart': dart format --fix\n```\n\nThis will run `dart format --fix` and automatically add changes to the commit.\n\n\u003c/details\u003e\n\n## Frequently Asked Questions\n\n### Can I use `lint_staged` via dart code?\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to expand\u003c/summary\u003e\n\nYes!\n\n```dart\nimport 'package:lint_staged/lint_staged.dart';\n\ntry {\n  final success = await lintStaged()\n  print(success ? 'Linting was successful!' : 'Linting failed!')\n} catch (e) {\n  print(e);\n}\n```\n\nParameters to `lintStaged` are equivalent to their CLI counterparts:\n\n```js\nconst success = await lintStaged({\n  allowEmpty: false,\n  stash: true,\n})\n```\n\n\u003c/details\u003e\n\n### Using with JetBrains IDEs _(WebStorm, PyCharm, IntelliJ IDEA, RubyMine, etc.)_\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to expand\u003c/summary\u003e\n\n_**Update**_: The latest version of JetBrains IDEs now support running hooks as you would expect.\n\nWhen using the IDE's GUI to commit changes with the `precommit` hook, you might see inconsistencies in the IDE and command line. This is [known issue](https://youtrack.jetbrains.com/issue/IDEA-135454) at JetBrains so if you want this fixed, please vote for it on YouTrack.\n\nUntil the issue is resolved in the IDE, you can use the following config to work around it:\n\n```json\n{\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"lint_staged\",\n      \"post-commit\": \"git update-index --again\"\n    }\n  }\n}\n```\n\n_Thanks to [this comment](https://youtrack.jetbrains.com/issue/IDEA-135454#comment=27-2710654) for the fix!_\n\n\u003c/details\u003e\n\n### Can I run `lint_staged` in CI, or when there are no staged files?\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to expand\u003c/summary\u003e\n\nLint_staged will by default run against files staged in git, and should be run during the git pre-commit hook, for example. It's also possible to override this default behaviour and run against files in a specific diff, for example\nall changed files between two different branches. If you want to run *lint_staged* in the CI, maybe you can set it up to compare the branch in a _Pull Request_/_Merge Request_ to the target branch.\n\nTry out the `git diff` command until you are satisfied with the result, for example:\n\n```\ngit diff --diff-filter=ACMR --name-only master...my-branch\n```\n\nThis will print a list of _added_, _changed_, _modified_, and _renamed_ files between `master` and `my-branch`.\n\nYou can then run lint_staged against the same files with:\n\n```\ndart run lint_staged --diff=\"master...my-branch\"\n```\n\n\u003c/details\u003e\n\n### The output of commit hook looks weird (no colors, duplicate lines, verbose output on Windows, …)\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to expand\u003c/summary\u003e\n\nGit 2.36.0 introduced a change to hooks where they were no longer run in the original TTY.\nThis was fixed in 2.37.0:\n\nhttps://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/2.37.0.txt\n\n\u003e - In Git 2.36 we revamped the way how hooks are invoked. One change\n\u003e   that is end-user visible is that the output of a hook is no longer\n\u003e   directly connected to the standard output of \"git\" that spawns the\n\u003e   hook, which was noticed post release. This is getting corrected.\n\u003e   (merge [a082345372](https://github.com/git/git/commit/a082345372) ab/hooks-regression-fix later to maint).\n\nIf updating Git doesn't help, you can try to manually redirect the output in your Git hook; for example:\n\n```shell\n# .husky/pre-commit\n\n#!/usr/bin/env sh\n. \"$(dirname -- \"$0\")/_/husky.sh\"\n\nif sh -c \": \u003e/dev/tty\" \u003e/dev/null 2\u003e/dev/null; then exec \u003e/dev/tty 2\u003e\u00261; fi\n\ndart run lint_staged\n```\n\n\u003c/details\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyiso%2Flint_staged","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyiso%2Flint_staged","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyiso%2Flint_staged/lists"}