Li-Yu Yu | 83b1b30 | 2023-02-22 20:39:00 +0800 | [diff] [blame] | 1 | # Copyright 2023 The ChromiumOS Authors |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
| 5 | """Wrap the clang-format binary from gs://chromium-clang-format""" |
| 6 | |
| 7 | import contextlib |
| 8 | import os |
| 9 | from typing import ContextManager, Sequence |
| 10 | import urllib.parse |
| 11 | |
| 12 | from chromite.lib import cache |
| 13 | from chromite.lib import cros_build_lib |
| 14 | from chromite.lib import path_util |
| 15 | |
| 16 | |
| 17 | CLANG_FORMAT_BUCKET = "gs://chromium-clang-format" |
| 18 | |
| 19 | # The SHA-1 checksum of the clang-format binary. |
| 20 | # Refer to clang-format.sha1 to see what chromium uses: |
| 21 | # https://chromium.googlesource.com/chromium/src/+/HEAD/buildtools/linux64/clang-format.sha1 |
| 22 | CLANG_FORMAT_SHA1 = "6ef2183a178a53e47e4448dbe192b1d8d5290222" |
| 23 | |
| 24 | |
| 25 | class ClangFormatCache(cache.RemoteCache): |
| 26 | """Supports caching the clang-format executable.""" |
| 27 | |
| 28 | def _Fetch( |
| 29 | self, url: str, local_path: str |
| 30 | ): # pylint: disable=arguments-differ |
| 31 | expected_sha1 = urllib.parse.urlparse(url).path.lstrip("/") |
| 32 | super()._Fetch(url, local_path, hash_sha1=expected_sha1, mode=0o755) |
| 33 | |
| 34 | |
| 35 | def GetClangFormatCache() -> ClangFormatCache: |
| 36 | """Returns the cache instance for the clang-format binary.""" |
| 37 | cache_dir = os.path.join(path_util.FindCacheDir(), "chromium-clang-format") |
| 38 | return ClangFormatCache(cache_dir) |
| 39 | |
| 40 | |
| 41 | @contextlib.contextmanager |
| 42 | def ClangFormat() -> ContextManager[str]: |
| 43 | """Context manager returning the clang-format binary.""" |
| 44 | key = (CLANG_FORMAT_SHA1,) |
| 45 | url = f"{CLANG_FORMAT_BUCKET}/{CLANG_FORMAT_SHA1}" |
| 46 | with GetClangFormatCache().Lookup(key) as ref: |
| 47 | if not ref.Exists(lock=True): |
| 48 | ref.SetDefault(url, lock=True) |
| 49 | yield ref.path |
| 50 | |
| 51 | |
| 52 | def main(argv: Sequence[str] = ()) -> int: |
| 53 | with ClangFormat() as clang_format: |
| 54 | return cros_build_lib.run( |
| 55 | ["clang-format", *argv], |
| 56 | executable=clang_format, |
| 57 | print_cmd=False, |
| 58 | check=False, |
| 59 | ).returncode |