Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
###############################################################################
## Bazel Configuration Flags
##
## `.bazelrc` is a Bazel configuration file.
## https://bazel.build/docs/best-practices#bazelrc-file
###############################################################################

test --test_output=errors
test --verbose_failures

# Fix the excessive rebuilding when using anything that depends on protobuf rules
# See https://github.com/bazelbuild/buildtools/issues/744
common --incompatible_strict_action_env
common --enable_bzlmod

try-import user.bazelrc

# To update these lines, execute
# `bazel run @rules_bazel_integration_test//tools:update_deleted_packages`
build --deleted_packages=examples/check_glob,examples/optional_attributes
Expand All @@ -15,3 +21,26 @@ query --deleted_packages=examples/check_glob,examples/optional_attributes
# Enable the aspect
build --aspects=//shellcheck:shellcheck_aspect.bzl%shellcheck_aspect
build --output_groups=+shellcheck_checks

###############################################################################
## Incompatibility flags
###############################################################################

# https://github.com/bazelbuild/bazel/issues/8195
build --incompatible_disallow_empty_glob=true

# https://github.com/bazelbuild/bazel/issues/12821
build --nolegacy_external_runfiles

# https://github.com/bazelbuild/bazel/issues/23043.
build --incompatible_autoload_externally=

###############################################################################
## Custom user flags
##
## This should always be the last thing in the `.bazelrc` file to ensure
## consistent behavior when setting flags in that file as `.bazelrc` files are
## evaluated top to bottom.
###############################################################################

try-import user.bazelrc
7 changes: 6 additions & 1 deletion .bcr/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
bcr_test_module:
module_path: "examples/check_glob"
matrix:
platform: ["debian10", "macos", "ubuntu2004"]
platform:
- "debian10"
- "macos"
- "macos_arm64"
- "ubuntu2004"
- "ubuntu2004_arm64"
bazel: [7.*, 8.*, 9.*]
tasks:
run_tests:
Expand Down
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.sh text eol=lf
.shellcheckrc text eol=lf
6 changes: 3 additions & 3 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ jobs:
include:
- os: macos-latest
- os: ubuntu-latest
- os: ubuntu-24.04-arm
- os: windows-latest

steps:
- uses: actions/checkout@v6

- name: Test fetch
run: bazel fetch //...

- name: Test
run: bazel test //...

- name: Create release archive and notes
if: startswith(runner.os, 'Windows') != true
# Set by GH actions, see
# https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables
run: ./ci/package.sh "${{ github.ref_name }}"
Expand Down
9 changes: 4 additions & 5 deletions shellcheck/internal/aspect_runner.bat
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/bin/sh
@ECHO OFF

set -eu

echo "" > "${SHELLCHECK_ASPECT_OUTPUT}"
exec $@
echo "" > "%SHELLCHECK_ASPECT_OUTPUT%"
call %*
exit /b %ERRORLEVEL%
2 changes: 1 addition & 1 deletion shellcheck/internal/aspect_runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
set -eu

echo "" > "${SHELLCHECK_ASPECT_OUTPUT}"
exec $@
exec "$@"
52 changes: 41 additions & 11 deletions shellcheck/internal/rules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,21 @@ _SHELL_CONTENT = """\

set -eu

{shellcheck} {args}
"{shellcheck}" {args}{post}
"""

_BATCH_CONTENT = """\
@ECHO OFF

{shellcheck} {args}
"{shellcheck}" {args}{post}
"""

def _quote_for_shell(value):
return "\"{}\"".format(value.replace("\"", "\\\""))

def _quote_for_batch(value):
return "\"{}\"".format(value.replace("\"", "\"\""))

def shellcheck_test_impl(ctx, expect_fail = False):
"""The implementation of the `shellcheck_test` rule.

Expand Down Expand Up @@ -48,21 +54,27 @@ def shellcheck_test_impl(ctx, expect_fail = False):
shellcheck_rc = toolchain.shellcheckrc.short_path
srcs = [f.short_path for f in ctx.files.data]
if is_windows:
shellcheck_path.replace("/", "\\")
shellcheck_rc.replace("/", "\\")
shellcheck_path = shellcheck_path.replace("/", "\\")
shellcheck_rc = shellcheck_rc.replace("/", "\\")
srcs = [src.replace("/", "\\") for src in srcs]

cmd.append("--rcfile={}".format(shellcheck_rc))
cmd.extend(srcs)
if is_windows:
cmd.append("--rcfile={}".format(_quote_for_batch(shellcheck_rc)))
cmd.extend([_quote_for_batch(src) for src in srcs])
else:
cmd.append("--rcfile={}".format(_quote_for_shell(shellcheck_rc)))
cmd.extend([_quote_for_shell(src) for src in srcs])

post = ""
if expect_fail:
cmd.append("|| exit 0; exit 1")
post = " && exit /b 1 || exit /b 0" if is_windows else " || exit 0\nexit 1"

ctx.actions.write(
output = executable,
content = (_BATCH_CONTENT if is_windows else _SHELL_CONTENT).format(
shellcheck = shellcheck_path,
args = " ".join(cmd),
post = post,
),
is_executable = True,
)
Expand Down Expand Up @@ -148,6 +160,12 @@ _shellcheck_srcs_aspect = aspect(
implementation = _shellcheck_srcs_aspect_impl,
)

def _unix_path_arg(value):
return value.path

def _windows_path_arg(value):
return value.path.replace("/", "\\")

def _shellcheck_aspect_impl(target, ctx):
if target.label.workspace_root.startswith("external"):
return []
Expand Down Expand Up @@ -177,6 +195,9 @@ def _shellcheck_aspect_impl(target, ctx):
return []

toolchain = ctx.toolchains[TOOLCHAIN_TYPE]
is_windows = ctx.target_platform_has_constraint(
ctx.attr._windows_constraint[platform_common.ConstraintValueInfo],
)

inputs_direct = [toolchain.shellcheckrc] + getattr(ctx.rule.files, "data", [])
inputs_transitive = [src_info.srcs, src_info.transitive_srcs]
Expand All @@ -188,15 +209,21 @@ def _shellcheck_aspect_impl(target, ctx):
])

format = ctx.attr._format[BuildSettingInfo].value
severity = ctx.attr._format[BuildSettingInfo].value
severity = ctx.attr._severity[BuildSettingInfo].value

output = ctx.actions.declare_file("{}.shellcheck.ok".format(target.label.name))

tools = depset([toolchain.shellcheck], transitive = [toolchain.all_files])

shellcheck_path = toolchain.shellcheck.path
shellcheck_rc_path = toolchain.shellcheckrc.path
if is_windows:
shellcheck_path = shellcheck_path.replace("/", "\\")
shellcheck_rc_path = shellcheck_rc_path.replace("/", "\\")

args = ctx.actions.args()
args.add(toolchain.shellcheck)
args.add(toolchain.shellcheckrc, format = "--rcfile=%s")
args.add(shellcheck_path)
args.add(shellcheck_rc_path, format = "--rcfile=%s")
args.add_all(src_info.source_paths, format_each = "--source-path=%s")

if format:
Expand All @@ -205,7 +232,7 @@ def _shellcheck_aspect_impl(target, ctx):
if severity:
args.add(severity, format = "--severity=%s")

args.add_all(srcs)
args.add_all(srcs, map_each = _windows_path_arg if is_windows else _unix_path_arg)

ctx.actions.run(
mnemonic = "Shellcheck",
Expand Down Expand Up @@ -240,6 +267,9 @@ shellcheck_aspect = aspect(
"_severity": attr.label(
default = Label("//shellcheck/settings:severity"),
),
"_windows_constraint": attr.label(
default = Label("@platforms//os:windows"),
),
},
toolchains = [TOOLCHAIN_TYPE],
requires = [_shellcheck_srcs_aspect],
Expand Down
Loading