blob: cef3d72382b707ac86b3fea2ffbb06ee4f49d44c [file] [log] [blame]
Li-Yu Yu83b1b302023-02-22 20:39:00 +08001# 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
7import contextlib
8import os
9from typing import ContextManager, Sequence
10import urllib.parse
11
12from chromite.lib import cache
13from chromite.lib import cros_build_lib
14from chromite.lib import path_util
15
16
17CLANG_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
22CLANG_FORMAT_SHA1 = "6ef2183a178a53e47e4448dbe192b1d8d5290222"
23
24
25class 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
35def 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
42def 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
52def 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