| diff --git a/buildifier/buildifier.bzl b/buildifier/buildifier.bzl |
| index 42445e7..0957f94 100644 |
| --- a/buildifier/buildifier.bzl |
| +++ b/buildifier/buildifier.bzl |
| @@ -34,8 +34,25 @@ def buildifier(**kwargs): |
| def _buildifier_test_impl(ctx): |
| return [buildifier_impl_factory(ctx, test_rule = True)] |
| |
| -buildifier_test = rule( |
| +_buildifier_test = rule( |
| implementation = _buildifier_test_impl, |
| attrs = buildifier_attr_factory(True), |
| test = True, |
| ) |
| + |
| +def buildifier_test(**kwargs): |
| + """ |
| + Wrapper for the _buildifier_test rule. Optionally disables sandboxing and caching. |
| + |
| + Args: |
| + **kwargs: all parameters for _buildifier_test |
| + """ |
| + if kwargs.get("no_sandbox", False): |
| + tags = kwargs.get("tags", []) |
| + |
| + # Note: the "external" tag is a workaround for bazelbuild#15516. |
| + for t in ["no-sandbox", "no-cache", "external"]: |
| + if t not in tags: |
| + tags.append(t) |
| + kwargs["tags"] = tags |
| + _buildifier_test(**kwargs) |
| diff --git a/buildifier/internal/factory.bzl b/buildifier/internal/factory.bzl |
| index 779c789..34a4997 100644 |
| --- a/buildifier/internal/factory.bzl |
| +++ b/buildifier/internal/factory.bzl |
| @@ -46,6 +46,10 @@ def buildifier_attr_factory(test_rule = False): |
| "verbose": attr.bool( |
| doc = "Print verbose information on standard error", |
| ), |
| + "exclude_patterns": attr.string_list( |
| + allow_empty = True, |
| + doc = "A list of glob patterns passed to the find command. E.g. './vendor/*' to exclude the Go vendor directory. In test rules, this attribute requires the use of the no_sandbox attribute.", |
| + ), |
| "mode": attr.string( |
| default = "fix" if not test_rule else "diff", |
| doc = "Formatting mode", |
| @@ -80,7 +84,6 @@ def buildifier_attr_factory(test_rule = False): |
| if test_rule: |
| attrs.update({ |
| "srcs": attr.label_list( |
| - allow_empty = False, |
| allow_files = [ |
| ".bazel", |
| ".bzl", |
| @@ -91,12 +94,13 @@ def buildifier_attr_factory(test_rule = False): |
| ], |
| doc = "A list of labels representing the starlark files to include in the test", |
| ), |
| - }) |
| - else: |
| - attrs.update({ |
| - "exclude_patterns": attr.string_list( |
| - allow_empty = True, |
| - doc = "A list of glob patterns passed to the find command. E.g. './vendor/*' to exclude the Go vendor directory", |
| + "no_sandbox": attr.bool( |
| + default = False, |
| + doc = "Set to True to enable running buildifier on all files on the workspace", |
| + ), |
| + "workspace": attr.label( |
| + allow_single_file = True, |
| + doc = "Label of the WORKSPACE file; required when the no-sandbox attribute is True", |
| ), |
| }) |
| |
| @@ -147,15 +151,24 @@ def buildifier_impl_factory(ctx, test_rule = False): |
| args.append("-add_tables=%s" % ctx.file.add_tables.path) |
| |
| exclude_patterns_str = "" |
| - if not test_rule and ctx.attr.exclude_patterns: |
| + if ctx.attr.exclude_patterns: |
| + if test_rule and not ctx.attr.no_sandbox: |
| + fail("Cannot use 'exclude_patterns' in a test rule without 'no_sandbox'") |
| exclude_patterns = ["\\! -path %s" % shell.quote(pattern) for pattern in ctx.attr.exclude_patterns] |
| exclude_patterns_str = " ".join(exclude_patterns) |
| |
| + workspace = "" |
| + if test_rule and ctx.attr.no_sandbox: |
| + if not ctx.file.workspace: |
| + fail("Cannot use 'no_sandbox' without a 'workspace'") |
| + workspace = ctx.file.workspace.path |
| + |
| out_file = ctx.actions.declare_file(ctx.label.name + ".bash") |
| substitutions = { |
| "@@ARGS@@": shell.array_literal(args), |
| "@@BUILDIFIER_SHORT_PATH@@": shell.quote(ctx.executable.buildifier.short_path), |
| "@@EXCLUDE_PATTERNS@@": exclude_patterns_str, |
| + "@@WORKSPACE@@": workspace, |
| } |
| ctx.actions.expand_template( |
| template = ctx.file._runner, |
| @@ -167,6 +180,8 @@ def buildifier_impl_factory(ctx, test_rule = False): |
| runfiles = [ctx.executable.buildifier] |
| if test_rule: |
| runfiles.extend(ctx.files.srcs) |
| + if ctx.attr.no_sandbox: |
| + runfiles.append(ctx.file.workspace) |
| |
| return DefaultInfo( |
| files = depset([out_file]), |
| diff --git a/buildifier/runner.bash.template b/buildifier/runner.bash.template |
| index 17e6a4b..fbe3e75 100644 |
| --- a/buildifier/runner.bash.template |
| +++ b/buildifier/runner.bash.template |
| @@ -2,6 +2,7 @@ |
| |
| BUILDIFIER_SHORT_PATH=@@BUILDIFIER_SHORT_PATH@@ |
| ARGS=@@ARGS@@ |
| +WORKSPACE="@@WORKSPACE@@" |
| |
| # Get the absolute path to the buildifier executable |
| buildifier_short_path=$(readlink "$BUILDIFIER_SHORT_PATH") |
| @@ -9,6 +10,15 @@ buildifier_short_path=$(readlink "$BUILDIFIER_SHORT_PATH") |
| # Use TEST_WORKSPACE to determine if the script is being ran under a test |
| if [[ ! -z "${TEST_WORKSPACE+x}" && -z "${BUILD_WORKSPACE_DIRECTORY+x}" ]]; then |
| FIND_FILE_TYPE="l" |
| + # If WORKSPACE was provided, then the script is being run under a test in no_sandbox mode |
| + # cd to the directory contatining the WORKSPACE file |
| + if [[ ! -z "${WORKSPACE+x}" ]]; then |
| + FIND_FILE_TYPE="f" |
| + WORKSPACE_PATH="$(dirname "$(realpath ${WORKSPACE})")" |
| + if ! cd "$WORKSPACE_PATH" ; then |
| + echo "Unable to change to workspace (WORKSPACE_PATH: ${WORKSPACE_PATH})" |
| + fi |
| + fi |
| else |
| # Change into the workspace directory if this is _not_ a test |
| if ! cd "$BUILD_WORKSPACE_DIRECTORY"; then |