Repo Browser: Pre-commit hooks You need to enable JavaScript to run this app.
Gruntwork Website
Pre-commit hooks A collection of pre-commit hooks for Terraform, bash, Go, and more.
Pre-commit hooks
This repo defines Git pre-commit hooks intended for use with pre-commit . The currently
supported hooks are:
terraform-fmt : Automatically run terraform fmt
on all Terraform code (*.tf
files).
terraform-validate : Automatically run terraform validate
on all Terraform code (*.tf
files).
tflint : Automatically run tflint
on all Terraform code (*.tf
files).
shellcheck : Run shellcheck
to lint files that contain a bash shebang .
gofmt : Automatically run gofmt
on all Golang code (*.go
files).
golint : Automatically run golint
on all Golang code (*.go
files).
yapf : Automatically run yapf
on all python code (*.py
files).
helmlint Automatically run helm lint
on your Helm chart files. See caveats here .
markdown-link-check Automatically run markdown-link-check on
markdown doc files.
General Usage
In each of your repos, add a file called .pre-commit-config.yaml
with the following contents:
repos:
- repo: https://github.com/gruntwork-io/pre-commit
rev: <VERSION>
hooks:
- id: terraform -fmt
- id: terraform -validate
- id: tflint
- id: shellcheck
- id: gofmt
- id: golint
Next, have every developer:
Install pre-commit . E.g. brew install pre-commit
.
Run pre-commit install
in the repo.
That’s it! Now every time you commit a code change (.tf
file), the hooks in the hooks:
config will execute.
Running Against All Files At Once
Example: Formatting all files
If you'd like to format all of your code at once (rather than one file at a time), you can run:
pre-commit run terraform -fmt --all-files
Example: Enforcing in CI
If you'd like to enforce all your hooks, you can configure your CI build to fail if the code doesn't pass checks by
adding the following to your build scripts:
pip install pre-commit
pre-commit install
pre-commit run
If all the hooks pass, the last command will exit with an exit code of 0. If any of the hooks make changes (e.g.,
because files are not formatted), the last command will exit with a code of 1, causing the build to fail.
Helm Lint Caveats
Detecting charts
The helmlint
pre-commit hook runs helm lint
on the charts that have been changed by the commit. It will run once per
changed chart that it detects.
Note that charts are detected by walking up the directory tree of the changed file and looking for a Chart.yaml
file
that exists on the path.
linter_values.yaml
helm lint
requires input values to look for configuration errors in your helm chart. However, this means that the
linter needs a complete values file. Because we want to develop charts that define required values that the operator
should provide, we don't want to specify defaults for all the values the chart expects in the default values.yaml
file.
Therefore, to support this, this pre-commit hook looks for a special linter_values.yaml
file defined in the chart
path. This will be combined with the values.yaml
file before running helm lint
. In your charts, you should define
the required values in linter_values.yaml
.
For example, suppose you had a helm chart that defined two input values: containerImage
and containerTag
. Suppose
that your chart required containerImage
to be defined, but not containerTag
. To enforce this, you created the
following values.yaml
file for your chart:
containerTag: latest
If you run helm lint
on this chart, it will fail because somewhere in your chart you will reference
.Values.containerImage
which will be undefined with this values.yaml
file. To handle this, you can define a
linter_values.yaml
file that defines containerImage
:
containerImage: nginx
Now when the pre-commit hook runs, it will call helm lint
with both linter_values.yaml
and values.yaml
:
helm lint -f values .yaml -f linter_values .yaml .
Shellcheck Arguments
To enable optional shellcheck features you can use the --enable
flag.
Other shellcheck flags can not be passed through.
repos:
- repo: https: //github.com /gruntwork-io/pre -commit
rev: <VERSION>
hooks:
- id: shellcheck
args: ["--enable require-variable-braces,deprecate-which" ]
License
This code is released under the Apache 2.0 License. Please see LICENSE and NOTICE for more details.
Copyright © 2019 Gruntwork, Inc.
Questions? Ask away. We're here to talk about our services, answer any questions, give advice, or just to chat.
Ready to hand off the Gruntwork? "https://cdn.gruntwork.io/gruntwork-website/"
{"index":{"js":"https://cdn.gruntwork.io/gruntwork-website/index.bundle.c7884255553b53fbca3a.js","map":"https://cdn.gruntwork.io/gruntwork-website/index.bundle.1b14c1b7d19f1f5eb35d6e118e838255.map"},"styles":{"css":"https://cdn.gruntwork.io/gruntwork-website/styles.bundle.f22938926651ddec7c49.css","js":"https://cdn.gruntwork.io/gruntwork-website/styles.bundle.e782420e74a20dcb8691.js","map":"https://cdn.gruntwork.io/gruntwork-website/styles.bundle.d5e2af49807c6ca33f8367d621ece507.map"},"vendors":{"css":"https://cdn.gruntwork.io/gruntwork-website/vendors.bundle.29f7d0366a0978763f96.css","js":"https://cdn.gruntwork.io/gruntwork-website/vendors.bundle.fa8174a130797d75d12c.js","map":"https://cdn.gruntwork.io/gruntwork-website/vendors.bundle.57243d94deeeb29d5061288a338b4eb6.map"}}
{"treedata":{"name":"root","toggled":true,"children":[{"name":".circleci","children":[{"name":"config.yml","path":".circleci/config.yml","sha":"40af7fc6f32fef1e268ae53986c8fb9c38d1357b"}]},{"name":".gitignore","path":".gitignore","sha":"c43e113d01a33a2cc5e66379ac0cc3853039fd88"},{"name":".pre-commit-hooks.yaml","path":".pre-commit-hooks.yaml","sha":"fd18c20f351b55dc4aa81759ddd1663622cbe518"},{"name":"CODEOWNERS","path":"CODEOWNERS","sha":"6bddb3ff6e1b3dfaba7cf180e56bca12c245be56"},{"name":"LICENSE","path":"LICENSE","sha":"7a4a3ea2424c09fbe48d455aed1eaa94d9124835"},{"name":"NOTICE","path":"NOTICE","sha":"c40e9bf1d01d32adc60f0e375bf55224002020ec"},{"name":"README.md","path":"README.md","sha":"94c830a6dee9036294ab4d2c4932bc1b581deacb","toggled":true},{"name":"hooks","children":[{"name":"check_skip_env.py","path":"hooks/check_skip_env.py","sha":"28eb25e5fe583b76940c72bbd80e4e2ee56da364"},{"name":"gofmt.sh","path":"hooks/gofmt.sh","sha":"b13e03ca66e47e983066e3d6ca2898cc4d42d46d"},{"name":"goimports.sh","path":"hooks/goimports.sh","sha":"1e77fb9645b7f54fe80ef500f5329ba79a267725"},{"name":"golint.sh","path":"hooks/golint.sh","sha":"e74ea4da285fee9d45b4cac6426657cfc504de6d"},{"name":"helmlint.sh","path":"hooks/helmlint.sh","sha":"98bce6e892b2e7f224bd0e50fd80695efa7eebc4"},{"name":"mdlink-check.sh","path":"hooks/mdlink-check.sh","sha":"af314b147c8862ea7a141371797a0852b91aeb72"},{"name":"shellcheck.sh","path":"hooks/shellcheck.sh","sha":"6bb98e32c137603ed43ba08915a4f9b92f620682"},{"name":"terraform-fmt.sh","path":"hooks/terraform-fmt.sh","sha":"9a01b1edbd05ad94fa5d30a42a6b9fb585063794"},{"name":"terraform-validate.sh","path":"hooks/terraform-validate.sh","sha":"eaf74560b33095480a570ca0770b3acd15c1916c"},{"name":"terragrunt-hclfmt.sh","path":"hooks/terragrunt-hclfmt.sh","sha":"1f107267f79f95ed013d848e0c0a3a88796f7521"},{"name":"tflint.sh","path":"hooks/tflint.sh","sha":"e9d4b497218a010cd83d41455eb4ba5cb0e45b84"},{"name":"yapf.sh","path":"hooks/yapf.sh","sha":"a7029349698bd8038a99559e0e3cb20b44030ed7"}]},{"name":"test","children":[{"name":".python-version","path":"test/.python-version","sha":"22848486038ccb97317e77cd491aab93950bb66a"},{"name":"check_skip_env_test.py","path":"test/check_skip_env_test.py","sha":"26c04c0a3970b056f87da3463f3ed3ef664088d6"},{"name":"fixtures","children":[{"name":"everything_commented_test.go","path":"test/fixtures/everything_commented_test.go","sha":"feb81f5aec891090a7bdc3b897f9c363da2f36a3"},{"name":"multiple_skip_uncommented_test.go","path":"test/fixtures/multiple_skip_uncommented_test.go","sha":"2f93ea21dd41d92eb341707d858c1824a17ccb94"},{"name":"nested_uncommented_test.go","path":"test/fixtures/nested_uncommented_test.go","sha":"8031f7f5c90d5fc72ceb868d0246010b536a4de5"},{"name":"non_skip_uncommented_test.go","path":"test/fixtures/non_skip_uncommented_test.go","sha":"516cf631593dae8bde9881bb43798144559cff09"},{"name":"skip_uncommented_test.go","path":"test/fixtures/skip_uncommented_test.go","sha":"0c9a9736aa40bbc986e058ce4a857c89f8331033"},{"name":"terratest_region_uncommented_test.go","path":"test/fixtures/terratest_region_uncommented_test.go","sha":"7c31712ec2f332c4b0a62f10559b1d64f051735e"}]},{"name":"tox.ini","path":"test/tox.ini","sha":"3c96243996b761219103344f7ff37f052add0850"}]}]},"detailsContent":"<p><a href=\"https://gruntwork.io/?ref=repo_pre-commit\" class=\"preview__body--description--blue\" target=\"_blank\"><img src=\"https://img.shields.io/badge/maintained%20by-gruntwork.io-%235849a6.svg\" alt=\"Maintained by Gruntwork.io\" class=\"preview__body--diagram\"></a></p>\n<h1 class=\"preview__body--title\" id=\"pre-commit-hooks\">Pre-commit hooks</h1><div class=\"preview__body--border\"></div><p>This repo defines Git pre-commit hooks intended for use with <a href=\"http://pre-commit.com/\" class=\"preview__body--description--blue\" target=\"_blank\">pre-commit</a>. The currently\nsupported hooks are:</p>\n<ul>\n<li><strong>terraform-fmt</strong>: Automatically run <code>terraform fmt</code> on all Terraform code (<code>*.tf</code> files).</li>\n<li><strong>terraform-validate</strong>: Automatically run <code>terraform validate</code> on all Terraform code (<code>*.tf</code> files).</li>\n<li><strong>tflint</strong>: Automatically run <a href=\"https://github.com/terraform-linters/tflint\" class=\"preview__body--description--blue\" target=\"_blank\"><code>tflint</code></a> on all Terraform code (<code>*.tf</code> files).</li>\n<li><strong>shellcheck</strong>: Run <a href=\"https://www.shellcheck.net/\" class=\"preview__body--description--blue\" target=\"_blank\"><code>shellcheck</code></a> to lint files that contain a bash <a href=\"https://en.wikipedia.org/wiki/Shebang_(Unix)\" class=\"preview__body--description--blue\" target=\"_blank\">shebang</a>.</li>\n<li><strong>gofmt</strong>: Automatically run <code>gofmt</code> on all Golang code (<code>*.go</code> files).</li>\n<li><strong>golint</strong>: Automatically run <code>golint</code> on all Golang code (<code>*.go</code> files).</li>\n<li><strong>yapf</strong>: Automatically run <a href=\"https://github.com/google/yapf\" class=\"preview__body--description--blue\" target=\"_blank\"><code>yapf</code></a> on all python code (<code>*.py</code> files).</li>\n<li><strong>helmlint</strong> Automatically run <a href=\"https://github.com/helm/helm/blob/master/docs/helm/helm_lint.md\" class=\"preview__body--description--blue\" target=\"_blank\"><code>helm lint</code></a> on your Helm chart files. <a href=\"#helm-lint-caveats\" class=\"preview__body--description--blue\">See caveats here</a>.</li>\n<li><strong>markdown-link-check</strong> Automatically run <a href=\"https://github.com/tcort/markdown-link-check\" class=\"preview__body--description--blue\" target=\"_blank\">markdown-link-check</a> on\nmarkdown doc files.</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"general-usage\">General Usage</h2>\n<p>In each of your repos, add a file called <code>.pre-commit-config.yaml</code> with the following contents:</p>\n<pre>repos:\n - repo: https://github.com/gruntwork-io/pre-commit\n rev: <VERSION> <span class=\"hljs-comment\"># Get the latest from: https://github.com/gruntwork-io/pre-commit/releases</span>\n hooks:\n - id: <span class=\"hljs-keyword\">terraform</span>-fmt\n - id: <span class=\"hljs-keyword\">terraform</span>-validate\n - id: tflint\n - id: shellcheck\n - id: gofmt\n - id: golint\n</pre>\n<p>Next, have every developer:</p>\n<ol>\n<li>Install <a href=\"http://pre-commit.com/\" class=\"preview__body--description--blue\" target=\"_blank\">pre-commit</a>. E.g. <code>brew install pre-commit</code>.</li>\n<li>Run <code>pre-commit install</code> in the repo.</li>\n</ol>\n<p>That’s it! Now every time you commit a code change (<code>.tf</code> file), the hooks in the <code>hooks:</code> config will execute.</p>\n<h2 class=\"preview__body--subtitle\" id=\"running-against-all-files-at-once\">Running Against All Files At Once</h2>\n<h3 class=\"preview__body--subtitle\" id=\"example-formatting-all-files\">Example: Formatting all files</h3>\n<p>If you'd like to format all of your code at once (rather than one file at a time), you can run:</p>\n<pre>pre-commit run <span class=\"hljs-keyword\">terraform</span>-fmt --all-files\n</pre>\n<h3 class=\"preview__body--subtitle\" id=\"example-enforcing-in-ci\">Example: Enforcing in CI</h3>\n<p>If you'd like to enforce all your hooks, you can configure your CI build to fail if the code doesn't pass checks by\nadding the following to your build scripts:</p>\n<pre>pip <span class=\"hljs-keyword\">install</span> pre-<span class=\"hljs-keyword\">commit</span>\npre-<span class=\"hljs-keyword\">commit</span> <span class=\"hljs-keyword\">install</span>\npre-<span class=\"hljs-keyword\">commit</span> run <span class=\"hljs-comment\">--all-files</span>\n</pre>\n<p>If all the hooks pass, the last command will exit with an exit code of 0. If any of the hooks make changes (e.g.,\nbecause files are not formatted), the last command will exit with a code of 1, causing the build to fail.</p>\n<h2 class=\"preview__body--subtitle\" id=\"helm-lint-caveats\">Helm Lint Caveats</h2>\n<h3 class=\"preview__body--subtitle\" id=\"detecting-charts\">Detecting charts</h3>\n<p>The <code>helmlint</code> pre-commit hook runs <code>helm lint</code> on the charts that have been changed by the commit. It will run once per\nchanged chart that it detects.</p>\n<p>Note that charts are detected by walking up the directory tree of the changed file and looking for a <code>Chart.yaml</code> file\nthat exists on the path.</p>\n<h3 class=\"preview__body--subtitle\" id=\"linter-values-yaml\">linter_values.yaml</h3>\n<p><code>helm lint</code> requires input values to look for configuration errors in your helm chart. However, this means that the\nlinter needs a complete values file. Because we want to develop charts that define required values that the operator\nshould provide, we don't want to specify defaults for all the values the chart expects in the default <code>values.yaml</code>\nfile.</p>\n<p>Therefore, to support this, this pre-commit hook looks for a special <code>linter_values.yaml</code> file defined in the chart\npath. This will be combined with the <code>values.yaml</code> file before running <code>helm lint</code>. In your charts, you should define\nthe required values in <code>linter_values.yaml</code>.</p>\n<p>For example, suppose you had a helm chart that defined two input values: <code>containerImage</code> and <code>containerTag</code>. Suppose\nthat your chart required <code>containerImage</code> to be defined, but not <code>containerTag</code>. To enforce this, you created the\nfollowing <code>values.yaml</code> file for your chart:</p>\n<pre><span class=\"hljs-comment\"># values.yaml</span>\n\n<span class=\"hljs-comment\"># containerImage is required and defines which image to use</span>\n\n<span class=\"hljs-comment\"># containerTag specifies the image tag to use. Defaults to latest.</span>\ncontainerTag: latest\n</pre>\n<p>If you run <code>helm lint</code> on this chart, it will fail because somewhere in your chart you will reference\n<code>.Values.containerImage</code> which will be undefined with this <code>values.yaml</code> file. To handle this, you can define a\n<code>linter_values.yaml</code> file that defines <code>containerImage</code>:</p>\n<pre><span class=\"hljs-comment\"># linter_values.yaml</span>\ncontainerImage: nginx\n</pre>\n<p>Now when the pre-commit hook runs, it will call <code>helm lint</code> with both <code>linter_values.yaml</code> and <code>values.yaml</code>:</p>\n<pre><span class=\"hljs-selector-tag\">helm</span> <span class=\"hljs-selector-tag\">lint</span> <span class=\"hljs-selector-tag\">-f</span> <span class=\"hljs-selector-tag\">values</span><span class=\"hljs-selector-class\">.yaml</span> <span class=\"hljs-selector-tag\">-f</span> <span class=\"hljs-selector-tag\">linter_values</span><span class=\"hljs-selector-class\">.yaml</span> .\n</pre>\n<h2 class=\"preview__body--subtitle\" id=\"shellcheck-arguments\">Shellcheck Arguments</h2>\n<p>To enable optional shellcheck features you can use the <code>--enable</code> flag.\nOther shellcheck flags can not be passed through.</p>\n<pre>repo<span class=\"hljs-variable\">s:</span>\n - repo: http<span class=\"hljs-variable\">s:</span>//github.<span class=\"hljs-keyword\">com</span>/gruntwork-io/<span class=\"hljs-keyword\">pre</span>-commit\n re<span class=\"hljs-variable\">v:</span> <span class=\"hljs-symbol\"><VERSION></span>\n hook<span class=\"hljs-variable\">s:</span>\n - id: shellcheck\n arg<span class=\"hljs-variable\">s:</span> [<span class=\"hljs-string\">\"--enable require-variable-braces,deprecate-which\"</span>]\n</pre>\n<h2 class=\"preview__body--subtitle\" id=\"license\">License</h2>\n<p>This code is released under the Apache 2.0 License. Please see <a href=\"/repos/v0.1.10/pre-commit/LICENSE\" class=\"preview__body--description--blue\">LICENSE</a> and <a href=\"/repos/v0.1.10/pre-commit/NOTICE\" class=\"preview__body--description--blue\">NOTICE</a> for more details.</p>\n<p>Copyright © 2019 Gruntwork, Inc.</p>\n","repoName":"pre-commit","repoRef":"v0.1.10","serviceDescriptor":{"serviceName":"Pre-commit hooks","serviceRepoName":"pre-commit","serviceRepoOrg":"gruntwork-io","cloudProviders":["aws","gcp"],"description":"A collection of pre-commit hooks for Terraform, bash, Go, and more.","imageUrl":"grunt.png","licenseType":"subscriber","technologies":["Bash"],"compliance":[],"tags":[""]},"serviceCategoryName":"CI / CD","fileName":"README.md","filePath":"","title":"Repo Browser: Pre-commit hooks","description":"Browse the repos in the Gruntwork Infrastructure as Code Library."}