aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Burgess IV <gbiv@google.com>2024-04-15 10:12:57 -0600
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2024-04-15 22:12:57 +0000
commit53ba4150fc1a28086ae239938e2201d022fabe78 (patch)
tree7318c03a618da84a670245cd6e1e9c6f731a4a7c
parentf8e584c226ae80b91180c1779afd1fdf537efce7 (diff)
downloadtoolchain-utils-53ba4150fc1a28086ae239938e2201d022fabe78.tar.gz
llvm_tools: add bb_add.py
This allows for folks (...mostly automation and the mage) to conveniently run `bb add` with 'well-known' toolchain CLs/CL stacks, like the current llvm-next CL stack, or the disable-werror CL, or similar. BUG=b:333462347 TEST=Unittests Change-Id: I43aa2f3a863a4121a6920a4e7a4adcd412057644 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/5454854 Reviewed-by: Ryan Beltran <ryanbeltran@chromium.org> Commit-Queue: George Burgess <gbiv@chromium.org> Tested-by: George Burgess <gbiv@chromium.org>
-rwxr-xr-xllvm_tools/bb_add.py91
-rwxr-xr-xllvm_tools/bb_add_test.py100
-rw-r--r--llvm_tools/cros_cls.py7
3 files changed, 196 insertions, 2 deletions
diff --git a/llvm_tools/bb_add.py b/llvm_tools/bb_add.py
new file mode 100755
index 00000000..1ff83490
--- /dev/null
+++ b/llvm_tools/bb_add.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+# Copyright 2024 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Runs `bb add`, with additional convenience features."""
+
+import argparse
+import logging
+import os
+import shlex
+import sys
+from typing import Iterable, List
+
+import cros_cls
+import llvm_next
+
+
+def generate_bb_add_command(
+ use_llvm_next: bool,
+ disable_werror: bool,
+ extra_cls: Iterable[cros_cls.ChangeListURL],
+ bots: Iterable[str],
+) -> List[str]:
+ cls: List[cros_cls.ChangeListURL] = []
+ if use_llvm_next:
+ if not llvm_next.LLVM_NEXT_TESTING_CLS:
+ raise ValueError(
+ "llvm-next testing requested, but no llvm-next CLs exist."
+ )
+ cls += llvm_next.LLVM_NEXT_TESTING_CLS
+
+ if disable_werror:
+ cls.append(llvm_next.DISABLE_WERROR_CL)
+
+ if extra_cls:
+ cls += extra_cls
+
+ cmd = ["bb", "add"]
+ for cl in cls:
+ cmd += ("-cl", cl.crrev_url_without_http())
+ cmd += bots
+ return cmd
+
+
+def main(argv: List[str]) -> None:
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.INFO,
+ )
+
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "--llvm-next",
+ action="store_true",
+ help="Add the current llvm-next patch set.",
+ )
+ parser.add_argument(
+ "--disable-werror",
+ action="store_true",
+ help="Add the 'disable -Werror' patch sets",
+ )
+ parser.add_argument(
+ "--cl",
+ action="append",
+ type=cros_cls.ChangeListURL.parse,
+ help="""
+ CL to add to the `bb add` run. May be specified multiple times. In the
+ form crrev.com/c/123456.
+ """,
+ )
+ parser.add_argument("bot", nargs="+", help="Bot(s) to run `bb add` with.")
+ opts = parser.parse_args(argv)
+
+ cmd = generate_bb_add_command(
+ use_llvm_next=opts.llvm_next,
+ disable_werror=opts.disable_werror,
+ extra_cls=opts.cl,
+ bots=opts.bot,
+ )
+ logging.info("Running `bb add` command: %s...", shlex.join(cmd))
+ # execvp raises if it fails, so no need to check.
+ os.execvp(cmd[0], cmd)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/llvm_tools/bb_add_test.py b/llvm_tools/bb_add_test.py
new file mode 100755
index 00000000..6f7fe6a7
--- /dev/null
+++ b/llvm_tools/bb_add_test.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python3
+# Copyright 2024 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tests for bb_add.py."""
+
+from typing import Iterable
+import unittest
+
+import bb_add
+import cros_cls
+import llvm_next
+
+
+_ARBITRARY_BOTS = ["chromeos/cq/amd64-generic-cq"]
+
+
+class Test(unittest.TestCase):
+ """Tests for bb_add.py."""
+
+ def set_llvm_next_cls(self, cls: Iterable[cros_cls.ChangeListURL]):
+ old_cls = llvm_next.LLVM_NEXT_TESTING_CLS
+ llvm_next.LLVM_NEXT_TESTING_CLS = cls
+
+ def restore_cls():
+ llvm_next.LLVM_NEXT_TESTING_CLS = old_cls
+
+ self.addCleanup(restore_cls)
+
+ def test_generate_bb_add_raises_if_no_llvm_next_cls(self):
+ self.set_llvm_next_cls(())
+ with self.assertRaisesRegex(
+ ValueError, "^llvm-next testing requested.*"
+ ):
+ bb_add.generate_bb_add_command(
+ use_llvm_next=True,
+ disable_werror=False,
+ extra_cls=(),
+ bots=_ARBITRARY_BOTS,
+ )
+
+ def test_generate_bb_add_adds_llvm_next_cls(self):
+ self.set_llvm_next_cls((cros_cls.ChangeListURL(123, 1),))
+ cmd = bb_add.generate_bb_add_command(
+ use_llvm_next=True,
+ disable_werror=False,
+ extra_cls=(),
+ bots=_ARBITRARY_BOTS,
+ )
+ self.assertEqual(
+ cmd, ["bb", "add", "-cl", "crrev.com/c/123/1"] + _ARBITRARY_BOTS
+ )
+
+ def test_generate_bb_add_adds_disable_werror_cl(self):
+ self.set_llvm_next_cls((cros_cls.ChangeListURL(123, 1),))
+ cmd = bb_add.generate_bb_add_command(
+ use_llvm_next=False,
+ disable_werror=True,
+ extra_cls=(),
+ bots=_ARBITRARY_BOTS,
+ )
+ self.assertEqual(
+ cmd,
+ [
+ "bb",
+ "add",
+ "-cl",
+ llvm_next.DISABLE_WERROR_CL.crrev_url_without_http(),
+ ]
+ + _ARBITRARY_BOTS,
+ )
+
+ def test_generate_bb_add_adds_extra_cls(self):
+ self.set_llvm_next_cls((cros_cls.ChangeListURL(123, 1),))
+ cmd = bb_add.generate_bb_add_command(
+ use_llvm_next=False,
+ disable_werror=False,
+ extra_cls=(
+ cros_cls.ChangeListURL(123, 1),
+ cros_cls.ChangeListURL(126),
+ ),
+ bots=_ARBITRARY_BOTS,
+ )
+ self.assertEqual(
+ cmd,
+ [
+ "bb",
+ "add",
+ "-cl",
+ "crrev.com/c/123/1",
+ "-cl",
+ "crrev.com/c/126",
+ ]
+ + _ARBITRARY_BOTS,
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/llvm_tools/cros_cls.py b/llvm_tools/cros_cls.py
index d5b5ffa0..b74132e2 100644
--- a/llvm_tools/cros_cls.py
+++ b/llvm_tools/cros_cls.py
@@ -112,13 +112,16 @@ class ChangeListURL:
raise ValueError("A patchset number must be specified.")
return result
- def __str__(self):
+ def crrev_url_without_http(self):
namespace = "i" if self.internal else "c"
- result = f"https://crrev.com/{namespace}/{self.cl_id}"
+ result = f"crrev.com/{namespace}/{self.cl_id}"
if self.patch_set is not None:
result += f"/{self.patch_set}"
return result
+ def __str__(self):
+ return f"https://{self.crrev_url_without_http()}"
+
def builder_url(build_id: BuildID) -> str:
"""Returns a builder URL given a build ID."""