diff --git a/BUILD b/BUILD index 4642551..d269ebd 100644 --- a/BUILD +++ b/BUILD @@ -12,7 +12,42 @@ # See the License for the specific language governing permissions and # limitations under the License. +load("@pip//:requirements.bzl", "entry_point") + exports_files([ "build_defs.bzl", "LICENSE", + "requirements.txt", ]) + +# Black formatter binary. Use with: +# bazel run //:black -- [args] +# Example to format all Python files: +# bazel run //:black -- . +alias( + name = "black", + actual = entry_point("black"), +) + +# Target to fix Python formatting issues. +# Usage: bazel run //:black_fix -- . +sh_binary( + name = "black_fix", + srcs = ["scripts/black_fix.sh"], + data = [ + ":black", + "scripts/black_common.sh", + ], +) + +# Target to check Python formatting. +# Usage: bazel run //:black_check +# This runs black --check --diff . on the workspace. +sh_binary( + name = "black_check", + srcs = ["scripts/black_check.sh"], + data = [ + ":black", + "scripts/black_common.sh", + ], +) diff --git a/MODULE.bazel b/MODULE.bazel index f5d06a2..129ac04 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -15,3 +15,11 @@ bazel_dep( repo_name = "com_google_googletest", ) bazel_dep(name = "rules_python", version = "0.31.0") + +pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") +pip.parse( + hub_name = "pip", + python_version = "3.11", + requirements_lock = "//:requirements.txt", +) +use_repo(pip, "pip") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6876f3c --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +black==24.8.0 diff --git a/scripts/black_check.sh b/scripts/black_check.sh new file mode 100755 index 0000000..0341232 --- /dev/null +++ b/scripts/black_check.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Script to check Python formatting with black. +# Usage: bazel run //:black_check +# +# This will pass if all files are correctly formatted and fail otherwise, +# printing a diff of the required changes. + +set -e + +SCRIPT_DIR="$(dirname "$0")" +source "$SCRIPT_DIR/black_common.sh" + +# Find the black binary +find_black "$SCRIPT_DIR" || exit 1 + +# Change to the workspace directory (BUILD_WORKSPACE_DIRECTORY is set by bazel run) +if [[ -n "$BUILD_WORKSPACE_DIRECTORY" ]]; then + cd "$BUILD_WORKSPACE_DIRECTORY" +fi + +# Run black in check mode +exec "$BLACK_BIN" --check --diff . diff --git a/scripts/black_common.sh b/scripts/black_common.sh new file mode 100755 index 0000000..eb3fcbd --- /dev/null +++ b/scripts/black_common.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Shared functions for black formatter scripts. +# Source this file to use the find_black function. + +# Find the black binary in the Bazel runfiles. +# Sets BLACK_BIN to the path of the black binary. +# Returns 0 on success, 1 on failure. +find_black() { + local script_dir="$1" + + # Try to find black in different possible locations + BLACK_BIN="$script_dir/black/black" + if [[ -x "$BLACK_BIN" ]]; then + return 0 + fi + + BLACK_BIN="$script_dir/../pip/bin/black/black" + if [[ -x "$BLACK_BIN" ]]; then + return 0 + fi + + # Search for black in runfiles + if [[ -n "$RUNFILES_DIR" ]]; then + BLACK_BIN="$(find "$RUNFILES_DIR" -name "black" -type f -executable 2>/dev/null | head -1)" + if [[ -n "$BLACK_BIN" ]] && [[ -x "$BLACK_BIN" ]]; then + return 0 + fi + fi + + # Could not find black + echo "Error: Could not find black binary" >&2 + echo "Searched in:" >&2 + echo " - $script_dir/black/black" >&2 + echo " - $script_dir/../pip/bin/black/black" >&2 + echo " - RUNFILES_DIR=$RUNFILES_DIR" >&2 + return 1 +} diff --git a/scripts/black_fix.sh b/scripts/black_fix.sh new file mode 100755 index 0000000..483b419 --- /dev/null +++ b/scripts/black_fix.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Script to run black formatter to fix Python files. +# Usage: bazel run //:black_fix -- [args] +# +# Example: bazel run //:black_fix -- . + +set -e + +SCRIPT_DIR="$(dirname "$0")" +source "$SCRIPT_DIR/black_common.sh" + +# Find the black binary +find_black "$SCRIPT_DIR" || exit 1 + +# Change to the workspace directory (BUILD_WORKSPACE_DIRECTORY is set by bazel run) +if [[ -n "$BUILD_WORKSPACE_DIRECTORY" ]]; then + cd "$BUILD_WORKSPACE_DIRECTORY" +fi + +# Run black with the provided arguments +exec "$BLACK_BIN" "$@"