SOLFIND
Web Lens
Portal home

pre-commit

https://pre-commit.com/ • 144 KB fetched
Open original page


pre-commit * Documentation * Supported hooks * Demo * Download on GitHub pre-commit A framework for managing and maintaining multi-language pre-commit hooks. Star Introduction Installation Adding plugins Usage Creating new hooks Command line interface Advanced features Contributing Introduction ¶ Git hook scripts are useful for identifying simple issues before submission to code review. We run our hooks on every commit to automatically point out issues in code such as missing semicolons, trailing whitespace, and debug statements. By pointing these issues out before code review, this allows a code reviewer to focus on the architecture of a change while not wasting time with trivial style nitpicks. As we created more libraries and projects we recognized that sharing our pre-commit hooks across projects is painful. We copied and pasted unwieldy bash scripts from project to project and had to manually change the hooks to work for different project structures. We believe that you should always use the best industry standard linters. Some of the best linters are written in languages that you do not use in your project or have installed on your machine. For example scss-lint is a linter for SCSS written in Ruby. If you’re writing a project in node you should be able to use scss-lint as a pre-commit hook without adding a Gemfile to your project or understanding how to get scss-lint installed. We built pre-commit to solve our hook issues. It is a multi-language package manager for pre-commit hooks. You specify a list of hooks you want and pre-commit manages the installation and execution of any hook written in any language before every commit. pre-commit is specifically designed to not require root access. If one of your developers doesn’t have node installed but modifies a JavaScript file, pre-commit automatically handles downloading and building node to run eslint without root. Installation ¶ Before you can run hooks, you need to have the pre-commit package manager installed. Using pip: pip install pre-commit In a python project, add the following to your requirements.txt (or requirements-dev.txt): pre-commit As a 0-dependency zipapp : * locate and download the .pyz file from the github releases * run python pre-commit-#.#.#.pyz ... in place of pre-commit ... Quick start ¶ 1. Install pre-commit ¶ * follow the install instructions above * pre-commit --version should show you what version you're using $ pre-commit --version pre-commit 4.6.2 2. Add a pre-commit configuration ¶ * create a file named .pre-commit-config.yaml * you can generate a very basic configuration using pre-commit sample-config * the full set of options for the configuration are listed below * this example uses a formatter for python code, however pre-commit works for any programming language * other supported hooks are available repos : - repo : https://github.com/pre-commit/pre-commit-hooks rev : v2.3.0 hooks : - id : check-yaml - id : end-of-file-fixer - id : trailing-whitespace - repo : https://github.com/psf/black rev : 22.10.0 hooks : - id : black 3. Install the git hook scripts ¶ * run pre-commit install to set up the git hook scripts $ pre-commit install pre-commit installed at .git/hooks/pre-commit * now pre-commit will run automatically on git commit ! 4. (optional) Run against all the files ¶ * it's usually a good idea to run the hooks against all of the files when adding new hooks (usually pre-commit will only run on the changed files during git hooks) $ pre-commit run --all-files [INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks. [INFO] Initializing environment for https://github.com/psf/black. [INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... [INFO] Installing environment for https://github.com/psf/black. [INFO] Once installed this environment will be reused. [INFO] This may take a few minutes... Check Yaml............................................................... Passed Fix End of Files......................................................... Passed Trim Trailing Whitespace................................................. Failed - hook id: trailing-whitespace - exit code: 1 Files were modified by this hook. Additional output: Fixing sample.py black.................................................................... Passed * oops! looks like I had some trailing whitespace * consider running that in CI too Adding pre-commit plugins to your project ¶ Once you have pre-commit installed, adding pre-commit plugins to your project is done with the .pre-commit-config.yaml configuration file. Add a file called .pre-commit-config.yaml to the root of your project. The pre-commit config file describes what repositories and hooks are installed. .pre-commit-config.yaml - top level ¶ repos A list of repository mappings . default_install_hook_types (optional: default [pre-commit] ) a list of --hook-type s which will be used by default when running pre-commit install . default_language_version (optional: default {} ) a mapping from language to the default language_version that should be used for that language. This will only override individual hooks that do not set language_version . For example to use python3.7 for language: python hooks: default_language_version : python : python3.7 default_stages (optional: default (all stages)) a configuration-wide default for the stages property of hooks. This will only override individual hooks that do not set stages . For example: default_stages : [ pre-commit , pre-push ] files (optional: default '' ) global file include pattern. exclude (optional: default ^$ ) global file exclude pattern. fail_fast (optional: default false ) set to true to have pre-commit stop running hooks after the first failure. minimum_pre_commit_version (optional: default '0' ) require a minimum version of pre-commit. A sample top-level: exclude : '^$' fail_fast : false repos : - ... .pre-commit-config.yaml - repos ¶ The repository mapping tells pre-commit where to get the code for the hook from. repo the repository url to git clone from or one of the special sentinel values: local , meta . rev the revision or tag to clone at. hooks A list of hook mappings . A sample repository: repos : - repo : https://github.com/pre-commit/pre-commit-hooks rev : v1.2.3 hooks : - ... .pre-commit-config.yaml - hooks ¶ The hook mapping configures which hook from the repository is used and allows for customization. All optional keys will receive their default from the repository's configuration. id which hook from the repository to use. alias (optional) allows the hook to be referenced using an additional id when using pre-commit run <hookid> . name (optional) override the name of the hook - shown during hook execution. language_version (optional) override the language version for the hook. See Overriding Language Version . files (optional) override the default pattern for files to run on. exclude (optional) file exclude pattern. types (optional) override the default file types to run on (AND). See Filtering files with types . types_or (optional) override the default file types to run on (OR). See Filtering files with types . exclude_types (optional) file types to exclude. args (optional) list of additional parameters to pass to the hook. stages (optional) selects which git hook(s) to run for. See Confining hooks to run at certain stages . additional_dependencies (optional) a list of dependencies that will be installed in the environment where this hook gets run. One useful application is to install plugins for hooks such as eslint . always_run (optional) if true , this hook will run even if there are no matching files. verbose (optional) if true , forces the output of the hook to be printed even when the hook passes. log_file (optional) if present, the hook output will additionally be written to a file when the hook fails or verbose is true . One example of a complete configuration: repos : - repo : https://github.com/pre-commit/pre-commit-hooks rev : v1.2.3 hooks : - id : trailing-whitespace This configuration says to download the pre-commit-hooks project and run its trailing-whitespace hook. Updating hooks automatically ¶ You can update your hooks to the latest version automatically by running pre-commit autoupdate . By default, this will bring the hooks to the latest tag on the default branch. Usage ¶ Run pre-commit install to install pre-commit into your git hooks. pre-commit will now run on every commit. Every time you clone a project using pre-commit running pre-commit install should always be the first thing you do. If you want to manually run all pre-commit hooks on a repository, run pre-commit run --all-files . To run individual hooks use pre-commit run <hook_id> . The first time pre-commit runs on a file it will automatically download, install, and run the hook. Note that running a hook for the first time may be slow. For example: If the machine does not have node installed, pre-commit will download and build a copy of node. $ pre-commit install pre-commit installed at /home/asottile/workspace/pytest/.git/hooks/pre-commit $ git commit -m "Add super awesome feature" black.................................................................... Passed blacken-docs.........................................(no files to check) Skipped Trim Trailing Whitespace................................................. Passed Fix End of Files......................................................... Passed Check Yaml...........................................(no files to check) Skipped Debug Statements (Python)................................................ Passed Flake8................................................................... Passed Reorder python imports................................................... Passed pyupgrade................................................................ Passed rst ``code`` is two backticks........................(no files to check) Skipped rst..................................................(no files to check) Skipped changelog filenames..................................(no files to check) Skipped [main 146c6c2c] Add super awesome feature 1 file changed, 1 insertion(+) Creating new hooks ¶ pre-commit currently supports hooks written in many languages . As long as your git repo is an installable package (gem, npm, pypi, etc.) or exposes an executable, it can be used with pre-commit. Each git repo can support as many languages/hooks as you want. new in 2.5.0 : pre-commit sets the PRE_COMMIT=1 environment variable during hook execution. The hook must exit nonzero on failure or modify files. A git repo containing pre-commit plugins must contain a .pre-commit-hooks.yaml file that tells pre-commit: id the id of the hook - used in pre-commit-config.yaml. name the name of the hook - shown during hook execution. entry the entry point - the executable to run. entry can also contain arguments that will not be overridden such as entry: autopep8 -i . language the language of the hook - tells pre-commit how to install the hook. files (optional: default '' ) the pattern of files to run on. exclude (optional: default ^$ ) exclude files that were matched by files . types (optional: default [file] ) list of file types to run on (AND). See Filtering files with types . types_or (optional: default [] ) list of file types to run on (OR). See Filtering files with types . exclude_types (optional: default [] ) the pattern of files to exclude. always_run (optional: default false ) if true this hook will run even if there are no matching files. fail_fast (optional: default false ) if true pre-commit will stop running hooks if this hook fails. verbose (optional: default false ) if true , forces the output of the hook to be printed even when the hook passes. pass_filenames (optional: default true ) if false no filenames will be passed to the hook. require_serial (optional: default false ) if true this hook will execute using a single process instead of in parallel. description (optional: default '' ) description of the hook. used for metadata purposes only. language_version (optional: default default ) see Overriding language version . minimum_pre_commit_version (optional: default '0' ) allows one to indicate a minimum compatible pre-commit version. args (optional: default [] ) list of additional parameters to pass to the hook. stages (optional: default (all stages)) selects which git hook(s) to run for. See Confining hooks to run at certain stages . For example: - id : trailing-whitespace name : Trim Trailing Whitespace description : This hook trims trailing whitespace. entry : trailing-whitespace-fixer language : python types : [ text ] Developing hooks interactively ¶ Since the repo property of .pre-commit-config.yaml can refer to anything that git clone ... understands, it's often useful to point it at a local directory while developing hooks. pre-commit try-repo streamlines this process by enabling a quick way to try out a repository. Here's how one might work interactively: note : you may need to provide --commit-msg-filename when using this command with hook types prepare-commit-msg and commit-msg . a commit is not necessary to try-repo on a local directory. pre-commit will clone any tracked uncommitted changes. ~/work/hook-repo $ git checkout origin/main -b feature # ... make some changes # In another terminal or tab ~/work/other-repo $ pre-commit try-repo ../hook-repo foo --verbose --all-files =============================================================================== Using config: =============================================================================== repos: - repo: ../hook-repo rev: 84f01ac09fcd8610824f9626a590b83cfae9bcbd hooks: - id: foo =============================================================================== [INFO] Initializing environment for ../hook-repo. Foo...................................................................... Passed - hook id: foo - duration: 0.02s Hello from foo hook! Supported languages ¶ * conda * coursier * dart * docker * docker_image * dotnet * fail * golang * haskell * julia * lua * node * perl * python * r * ruby * rust * swift * pygrep * unsupported * unsupported_script conda ¶ The hook repository must contain an environment.yml file which will be used via conda env create --file environment.yml ... to create the environment. The conda language also supports additional_dependencies and will pass any of the values directly into conda install . This language can therefore be used with local hooks. mamba or micromamba can be used to install instead via the PRE_COMMIT_USE_MAMBA=1 or PRE_COMMIT_USE_MICROMAMBA=1 environment variables. Support: conda hooks work as long as there is a system-installed conda binary (such as miniconda ). It has been tested on linux, macOS, and windows. coursier ¶ The hook repository must have a .pre-commit-channel folder and that folder must contain the coursier application descriptors for the hook to install. For configuring coursier hooks, your entry should correspond to an executable installed from the repository's .pre-commit-channel folder. Support: coursier hooks are known to work on any system which has the cs or coursier package manager installed. The specific coursier applications you install may depend on various versions of the JVM, consult the hooks' documentation for clarification. It has been tested on linux. pre-commit also supports the coursier naming of the package manager executable. new in 3.0.0 : language: coursier hooks now support repo: local and additional_dependencies . dart ¶ The hook repository must have a pubspec.yaml -- this must contain an executables section which will list the binaries that will be available after installation. Match the entry to an executable. pre-commit will build each executable using dart compile exe bin/{executable}.dart . language: dart also supports additional_dependencies . to specify a version for a dependency, separate the package name by a : : additional_dependencies : [ 'hello_world_dart:1.0.0' ] Support: dart hooks are known to work on any system which has the dart sdk installed. It has been tested on linux, macOS, and windows. docker ¶ The hook repository must have a Dockerfile . It will be installed via docker build . . Running Docker hooks requires a running Docker engine on your host. For configuring Docker hooks, your entry should correspond to an executable inside the Docker container, and will be used to override the default container entrypoint. Your Docker CMD will not run when pre-commit passes a file list as arguments to the run container command. Docker allows you to use any language that's not supported by pre-commit as a builtin. pre-commit will automatically mount the repository source as a volume using -v $PWD:/src:rw,Z and set the working directory using --workdir /src . Support: docker hooks are known to work on any system which has a working docker executable. It has been tested on linux and macOS. Hooks that are run via boot2docker are known to be unable to make modifications to files. See this repository for an example Docker-based hook. docker_image ¶ A more lightweight approach to docker hooks. The docker_image "language" uses existing docker images to provide hook executables. docker_image hooks can be conveniently configured as local hooks. The entry specifies the docker tag to use. If an image has an ENTRYPOINT defined, nothing special is needed to hook up the executable. If the container does not specify an ENTRYPOINT or you want to change the entrypoint you can specify it as well in your entry . For example: - id : dockerfile-provides-entrypoint name

Links found on this page

  1. Documentation [direct]
  2. Supported hooks [direct]
  3. Demo [direct]
  4. Download on GitHub [direct]
  5. Introduction [direct]
  6. zipapp [direct]
  7. github releases [direct]
  8. miniconda [direct]
  9. application descriptors [direct]
  10. this repository [direct]
  11. this [direct]
  12. Pkg REPL mode syntax [direct]
  13. [email protected] [direct]
  14. cpan [direct]
  15. install argument formats understood by cpan [direct]
  16. renv::restore() [direct]
  17. renv::install() [direct]
  18. R [direct]
  19. Cargo [direct]
  20. example [direct]
  21. git commit-msg docs [direct]
  22. git 2.54 [direct]
  23. identify [direct]
  24. tags by extension / naming convention [direct]
  25. tags by shebang ( #! ) [direct]
  26. regular expressions [direct]
  27. pep394 [direct]
  28. nodeenv [direct]
  29. ruby-build [direct]
  30. go.dev/dl [direct]
  31. XDG Base Directory Specification [direct]
  32. pre-commit.ci [direct]
  33. [email protected] [direct]
  34. @chriselion [direct]
  35. official pre-commit github action [direct]
  36. Gitlab caching best practices [direct]
  37. tox [direct]
  38. GitHub Sponsors (asottile) [direct]
  39. Open Collective [direct]
  40. stackoverflow tagged pre-commit.com [direct]
  41. pre-commit/pre-commit [direct]
  42. asottile's twitch discord [direct]
  43. Molly Finkle [direct]
  44. Anthony Sottile [direct]
  45. Ken Struys [direct]
  46. Chris Kuehl [direct]
  47. framework contributors [direct]
  48. core hook contributors [direct]