diff --git a/BUILD.bazel b/BUILD.bazel index 5217c94003e51ab1c1690749b2434c3496aedf1f..85a07407bad650e384378b2db8cfe0c48c302705 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -24,6 +24,7 @@ pre_commit_hooks( srcs = [ "//buildifier", "//ruff", + "//shfmt", ], visibility = ["//visibility:public"], ) diff --git a/MODULE.bazel b/MODULE.bazel index 30174b177a911cd33c493f59b76cee3f5c8b82dc..2c47e6a96ab81bff563a3b735d1426f5bea740fe 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -21,6 +21,8 @@ python.toolchain( download_archive = use_repo_rule("@download_utils//download/archive:defs.bzl", "download_archive") +download_file = use_repo_rule("@download_utils//download/file:defs.bzl", "download_file") + # Ruff binaries [ download_archive( @@ -38,3 +40,22 @@ download_archive = use_repo_rule("@download_utils//download/archive:defs.bzl", " ("arm64-windows", "aarch64-pc-windows-msvc", ".zip", "sha256-ckodh0IeEldZ6bfbqxak0QNIks5BgKqvYePrvn5nr6I="), ) ] + +# Shfmt binaries +[ + download_file( + name = "shfmt-{}".format(name), + executable = True, + integrity = integrity, + output = "shfmt-{}".format(name), + urls = ["https://github.com/mvdan/sh/releases/download/v3.10.0/shfmt_v3.10.0_{}{}".format(couplet, ext)], + ) + for name, couplet, ext, integrity in ( + ("amd64-linux", "linux_amd64", "", "sha256-H1ejhNWVQvj6xfUD2h8+pEJC9G3/lpVp6AtSTWS3Hbw="), + ("arm64-linux", "linux_arm64", "", "sha256-nSMBPVZkDiKHMv0qBKnt4KtGvC12S/IqSjX7GxTXB6g="), + ("amd64-macos", "darwin_amd64", "", "sha256-742XCz9pWn6OfUBzDu3S2TWrlZn3ijZfMZxRW8WdTIM="), + ("arm64-macos", "darwin_arm64", "", "sha256-hgMFM6gjwKfNkt7g90CU5bkBwyd7Q972M31eGeVv5VM="), + ("amd64-windows", "windows_amd64", ".exe", "sha256-bkxqzTjee0sbqPgIK55ojfjJuGHT+LLnuxtycCAaNYc="), + # ("arm64-windows", "windows_arm64", ".exe", ""), Currently doesn't have binary for arm64 Windows. + ) +] diff --git a/e2e/shell/echo.sh b/e2e/shell/echo.sh new file mode 100644 index 0000000000000000000000000000000000000000..1f10270c2097ae1cabf3fa126fc035067f7640ea --- /dev/null +++ b/e2e/shell/echo.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +set -o errexit +set -o nounset + +builtin echo "$@" diff --git a/e2e/shfmt/BUILD.bazel b/e2e/shfmt/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..7a1190b3f8e00b0d345c4e3e72d08b18ef07af84 --- /dev/null +++ b/e2e/shfmt/BUILD.bazel @@ -0,0 +1,9 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") + +build_test( + name = "shfmt", + size = "small", + targets = [ + "@pre-commit-hooks//shfmt", + ], +) diff --git a/hooks/.pre-commit-config.yaml b/hooks/.pre-commit-config.yaml index 733365fe0189d5c604cf2e8b0be3553f33a3e75f..02c93e2cf9e9c19523f5afb04512fcdddaa9a75f 100644 --- a/hooks/.pre-commit-config.yaml +++ b/hooks/.pre-commit-config.yaml @@ -38,6 +38,16 @@ repos: entry: bazel run --config=pre-commit -- //ruff types: - python + - id: //shfmt + name: Format Shell files with `shfmt` + description: Performs formatting with `shfmt` against Shell files. + language: system + require_serial: true + stages: + - pre-commit + entry: bazel run --config=pre-commit -- //shfmt + types: + - shell - id: //hooks:config name: Update `pre-commit` config description: Keeps the `.pre-commit-config.yaml` in sync with any changes to the diff --git a/shfmt/BUILD.bazel b/shfmt/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..5791d120f42d9bc3b392be54966fd0d85e47c7d8 --- /dev/null +++ b/shfmt/BUILD.bazel @@ -0,0 +1,35 @@ +load("@pre-commit//pre-commit/hook:defs.bzl", "pre_commit_hook") +load("@toolchain_utils//toolchain/symlink/target:defs.bzl", "toolchain_symlink_target") + +alias( + name = "exe", + actual = select( + { + "@toolchain_utils//toolchain/constraint:amd64-linux": "@shfmt-amd64-linux//:shfmt-amd64-linux", + "@toolchain_utils//toolchain/constraint:arm64-linux": "@shfmt-arm64-linux//:shfmt-arm64-linux", + "@toolchain_utils//toolchain/constraint:amd64-macos": "@shfmt-amd64-macos//:shfmt-amd64-macos", + "@toolchain_utils//toolchain/constraint:arm64-macos": "@shfmt-arm64-macos//:shfmt-arm64-macos", + "@toolchain_utils//toolchain/constraint:amd64-windows": "@shfmt-amd64-windows//:shfmt-amd64-windows", + # "@toolchain_utils//toolchain/constraint:arm64-windows": "@shfmt-arm64-windows//:shfmt-arm64-windows", + }, + no_match_error = "No hermetic `shfmt` found for `//pre-commit/hook/shfmt:cli`. Please set it to a hermetic `shfmt` download in `MODULE.bazel` for the current host platform.", + ), +) + +toolchain_symlink_target( + name = "cli", + target = ":exe", +) + +pre_commit_hook( + name = "shfmt", + src = ":cli", + args = [ + "-w", + ], + description = "Performs formatting with `shfmt` against Shell files.", + stages = ["@pre-commit//pre-commit/stage:pre-commit"], + summary = "Format Shell files with `shfmt`", + types = ["@pre-commit//pre-commit/tag:shell"], + visibility = ["//visibility:public"], +)