[shac] Committing shac check for cpp formatting

Change-Id: Ibade03000acc564831ab48b8cb882d086117cec2
Reviewed-on: https://fuchsia-review.googlesource.com/c/shac-project/checks-cpp/+/1010945
Reviewed-by: Oliver Newman <olivernewman@google.com>
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..afcbaf0
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "third_party/shac/checks-starlark"]
+  path = third_party/shac/checks-starlark
+  url = https://fuchsia.googlesource.com/shac-project/checks-starlark
diff --git a/README.md b/README.md
index 8d12e92..9d80757 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,12 @@
-Shac Global Checks Template Repository
-======================================
+Shac Global Checks: C/C++ Repository
+=======================================
 
-This repository is a template that we will use when creating new Shac global
-checks repositories for Fuchsia as per go/rvos-global-shac-checks-policy.
+This repository hosts a suite of checks for performing static analysis
+and code health operations on C/C++ source code.
+
+The checks are hosted in the "checks/" directory, split up based on the
+host-tool being used.
+
+Please see https://github.com/shac-project/shac for more information on the
+shac tool and framework.
+
diff --git a/checks/clang-format/clang_format.star b/checks/clang-format/clang_format.star
new file mode 100644
index 0000000..6f70332
--- /dev/null
+++ b/checks/clang-format/clang_format.star
@@ -0,0 +1,45 @@
+# Copyright 2024 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+def _clang_format(
+        ctx,
+        tool = "clang-format",
+        extra_args = [],
+        emit_level = "error",
+        emit_message = "File is not formatted.",
+
+        # For testing
+        file_filter = lambda x: True):
+    """Formats C/C++ files using clang-format."""
+
+    base_cmd = [tool]
+
+    cc_files = [
+        f
+        for f in ctx.scm.affected_files()
+        if f.endswith((".c", ".cc", ".cpp", ".h")) and
+           file_filter(f)
+    ]
+    if not cc_files:
+        return
+
+    original_contents = {}
+    procs = {}
+    for filepath in cc_files:
+        original = str(ctx.io.read_file(filepath))
+        original_contents[filepath] = original
+        procs[filepath] = ctx.os.exec(base_cmd + extra_args + [filepath])
+
+    for filepath, proc in procs.items():
+        res = proc.wait()
+        original = original_contents[filepath]
+        if res.stdout != original:
+            ctx.emit.finding(
+                filepath = filepath,
+                level = emit_level,
+                message = emit_message,
+                replacements = [res.stdout],
+            )
+
+clang_format = shac.check(_clang_format, formatter = True)
diff --git a/checks/clang-format/testdata/test_format_cpp.cpp b/checks/clang-format/testdata/test_format_cpp.cpp
new file mode 100644
index 0000000..c76a575
--- /dev/null
+++ b/checks/clang-format/testdata/test_format_cpp.cpp
@@ -0,0 +1,24 @@
+// Copyright 2024 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "foo.h"
+
+namespace bar = ::baz::testing;
+
+// TODO(2344): Fix all the bugs.
+       namespace outer {
+
+
+
+
+
+namespace inner {
+
+bool function(uint8_t number) {
+  return true;
+}
+}
+}
+
+
diff --git a/checks/clang-format/testdata/want_format_cpp.cpp b/checks/clang-format/testdata/want_format_cpp.cpp
new file mode 100644
index 0000000..196952b
--- /dev/null
+++ b/checks/clang-format/testdata/want_format_cpp.cpp
@@ -0,0 +1,16 @@
+// Copyright 2024 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "foo.h"
+
+namespace bar = ::baz::testing;
+
+// TODO(2344): Fix all the bugs.
+namespace outer {
+
+namespace inner {
+
+bool function(uint8_t number) { return true; }
+} // namespace inner
+} // namespace outer
diff --git a/checks/clang-tidy/clang_tidy.star b/checks/clang-tidy/clang_tidy.star
new file mode 100644
index 0000000..cb1e456
--- /dev/null
+++ b/checks/clang-tidy/clang_tidy.star
@@ -0,0 +1,8 @@
+# Copyright 2023 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+def _clang_tidy(ctx, tool = "clang-tidy"):
+    pass
+
+clang_tidy = shac.check(_clang_tidy)
diff --git a/register.star b/register.star
new file mode 100644
index 0000000..64eecb5
--- /dev/null
+++ b/register.star
@@ -0,0 +1,22 @@
+# Copyright 2024 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+load("checks/clang-format/clang_format.star", "clang_format")
+
+def register_clang_format(**kwargs):
+    # Available arguments:
+    #
+    #   tool: Path to buildifier host-tool
+    #     Must exist in and be rlative to the local workspace.
+    #
+    #   extra_args: Additional arguments passed directly to buildifier.
+    #     list of strings
+    #
+    #   emit_level: Level for emitting messages.
+    #     "notice" | "warning" | "error"
+    #
+    #   emit_message: Message to print in case of a found issue.
+    #     String. E.g. "Please run <> to format your code."
+
+    shac.register_check(clang_format.with_args(**kwargs), formatter = True)
diff --git a/shac.star b/shac.star
new file mode 100644
index 0000000..8d37779
--- /dev/null
+++ b/shac.star
@@ -0,0 +1,3 @@
+# Copyright 2024 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
diff --git a/shac.textproto b/shac.textproto
new file mode 100644
index 0000000..f28a104
--- /dev/null
+++ b/shac.textproto
@@ -0,0 +1,6 @@
+# Copyright 2024 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+min_shac_version: "0.1.5"
+allow_network: False