From fc948d3e8334b434097478cb156c40f5c2a8e14d Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sat, 9 Jan 2021 17:08:50 +1000 Subject: [PATCH] add clang-format for backend.proto formatting --- defs.bzl | 3 ++ rslib/BUILD.bazel | 6 ++++ rslib/clang_format.bzl | 73 ++++++++++++++++++++++++++++++++++++++++++ rslib/proto_format.py | 36 +++++++++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 rslib/clang_format.bzl create mode 100755 rslib/proto_format.py diff --git a/defs.bzl b/defs.bzl index eff3d9df2..ab042a9e1 100644 --- a/defs.bzl +++ b/defs.bzl @@ -4,6 +4,7 @@ load("@io_bazel_rules_rust//rust:repositories.bzl", "rust_repositories") load("@net_ankiweb_anki//cargo:crates.bzl", "raze_fetch_remote_crates") load(":python.bzl", "setup_local_python") load(":protobuf.bzl", "setup_protobuf_binary") +load("//rslib:clang_format.bzl", "setup_clang_format") load("@build_bazel_rules_nodejs//:index.bzl", "node_repositories", "yarn_install") load("@io_bazel_rules_sass//:defs.bzl", "sass_repositories") load("@build_bazel_rules_svelte//:defs.bzl", "rules_svelte_dependencies") @@ -28,6 +29,8 @@ def setup_deps(): setup_protobuf_binary(name = "com_google_protobuf") + setup_clang_format(name = "clang_format") + native.register_toolchains("@python//:python3_toolchain") pip_import( diff --git a/rslib/BUILD.bazel b/rslib/BUILD.bazel index fdfedaa54..91284f4c1 100644 --- a/rslib/BUILD.bazel +++ b/rslib/BUILD.bazel @@ -2,6 +2,7 @@ load("@rules_proto//proto:defs.bzl", "proto_library") load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary", "rust_library", "rust_test") load("@io_bazel_rules_rust//cargo:cargo_build_script.bzl", "cargo_build_script") load(":rustfmt.bzl", "rustfmt_fix", "rustfmt_test") +load(":clang_format.bzl", "proto_format") load("//ts:sql_format.bzl", "sql_format") # Build script @@ -149,6 +150,11 @@ sql_format( srcs = glob(["**/*.sql"]), ) +proto_format( + name = "proto_format", + srcs = ["backend.proto"], +) + # fluent.proto generation ########################### # This separate step is required to make the file available to downstream consumers. diff --git a/rslib/clang_format.bzl b/rslib/clang_format.bzl new file mode 100644 index 000000000..a2fd92a69 --- /dev/null +++ b/rslib/clang_format.bzl @@ -0,0 +1,73 @@ +""" +Exposes a clang-format binary for formatting protobuf. +""" + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") +load("@rules_python//python:defs.bzl", "py_test") + +def _impl(rctx): + rctx.file("BUILD.bazel", """ +alias( + name = "clang_format", + actual = select({ + "@net_ankiweb_anki//platforms:windows_x86_64": "@clang_format_windows_x86_64//:clang-format.exe", + "@net_ankiweb_anki//platforms:macos_x86_64": "@clang_format_macos_x86_64//:clang-format", + "@net_ankiweb_anki//platforms:linux_x86_64": "@clang_format_linux_x86_64//:clang-format", + }), + visibility = ["//visibility:public"] +) +""") + +_setup_clang_format = repository_rule( + attrs = {}, + local = True, + implementation = _impl, +) + +def setup_clang_format(name): + maybe( + http_archive, + name = "clang_format_macos_x86_64", + build_file_content = """exports_files(["clang-format"])""", + sha256 = "238be68d9478163a945754f06a213483473044f5a004c4125d3d9d8d3556466e", + urls = [ + "https://github.com/ankitects/clang-format-binaries/releases/download/anki-2021-01-09/clang-format_macos_x86_64.zip", + ], + ) + + maybe( + http_archive, + name = "clang_format_linux_x86_64", + build_file_content = """exports_files(["clang-format"])""", + sha256 = "64060bc4dbca30d0d96aab9344e2783008b16e1cae019a2532f1126ca5ec5449", + urls = [ + "https://github.com/ankitects/clang-format-binaries/releases/download/anki-2021-01-09/clang-format_linux_x86_64.zip", + ], + ) + + maybe( + http_archive, + name = "clang_format_windows_x86_64", + build_file_content = """exports_files(["clang-format.exe"])""", + sha256 = "7d9f6915e3f0fb72407830f0fc37141308d2e6915daba72987a52f309fbeaccc", + urls = [ + "https://github.com/ankitects/clang-format-binaries/releases/download/anki-2021-01-09/clang-format_windows_x86_64.zip", + ], + ) + + if not native.existing_rule(name): + _setup_clang_format( + name = name, + ) + +def proto_format(name, srcs, **kwargs): + py_test( + name = name, + srcs = [ + "proto_format.py", + ], + data = ["@clang_format//:clang_format"] + srcs, + args = ["$(location @clang_format//:clang_format)"] + [native.package_name() + "/" + f for f in srcs], + **kwargs + ) diff --git a/rslib/proto_format.py b/rslib/proto_format.py new file mode 100755 index 000000000..306146a5d --- /dev/null +++ b/rslib/proto_format.py @@ -0,0 +1,36 @@ +import sys, subprocess, os, difflib + +clang_format = sys.argv[1] +workspace = os.environ.get("BUILD_WORKSPACE_DIRECTORY", "") +want_fix = bool(workspace) + +found_bad = False +for path in sys.argv[2:]: + with open(path) as file: + orig = file.read() + new = subprocess.check_output( + # [clang_format, "--style={'BasedOnStyle': 'google', 'IndentWidth': 4}", path] + [clang_format, "--style=google", path] + ).decode("utf-8") + if orig != new: + if want_fix: + with open(os.path.join(workspace, path), "w") as file: + file.write(new) + print("fixed", path) + else: + print(f"Bad formatting in {path}") + print( + "\n".join( + difflib.unified_diff( + orig.splitlines(), + new.splitlines(), + fromfile="bad", + tofile="good", + lineterm="", + ) + ) + ) + found_bad = True + +if found_bad: + sys.exit(1) \ No newline at end of file