xref: /aosp_15_r20/external/executorch/build/buck_util.py (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1*523fa7a6SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*523fa7a6SAndroid Build Coastguard Worker# Copyright (c) Meta Platforms, Inc. and affiliates.
3*523fa7a6SAndroid Build Coastguard Worker# All rights reserved.
4*523fa7a6SAndroid Build Coastguard Worker#
5*523fa7a6SAndroid Build Coastguard Worker# This source code is licensed under the BSD-style license found in the
6*523fa7a6SAndroid Build Coastguard Worker# LICENSE file in the root directory of this source tree.
7*523fa7a6SAndroid Build Coastguard Worker
8*523fa7a6SAndroid Build Coastguard Workerimport os
9*523fa7a6SAndroid Build Coastguard Workerimport subprocess
10*523fa7a6SAndroid Build Coastguard Workerimport sys
11*523fa7a6SAndroid Build Coastguard Worker
12*523fa7a6SAndroid Build Coastguard Workerfrom typing import Optional, Sequence
13*523fa7a6SAndroid Build Coastguard Worker
14*523fa7a6SAndroid Build Coastguard Worker
15*523fa7a6SAndroid Build Coastguard Worker# Run buck2 from the same directory (and thus repo) as this script.
16*523fa7a6SAndroid Build Coastguard WorkerBUCK_CWD: str = os.path.dirname(os.path.realpath(__file__))
17*523fa7a6SAndroid Build Coastguard Worker
18*523fa7a6SAndroid Build Coastguard Worker
19*523fa7a6SAndroid Build Coastguard Workerclass Buck2Runner:
20*523fa7a6SAndroid Build Coastguard Worker    def __init__(self, tool_path: str) -> None:
21*523fa7a6SAndroid Build Coastguard Worker        self._path = tool_path
22*523fa7a6SAndroid Build Coastguard Worker
23*523fa7a6SAndroid Build Coastguard Worker    def run(self, args: Sequence[str]) -> list[str]:
24*523fa7a6SAndroid Build Coastguard Worker        """Runs buck2 with the given args and returns its stdout as a sequence of lines."""
25*523fa7a6SAndroid Build Coastguard Worker        try:
26*523fa7a6SAndroid Build Coastguard Worker            cp: subprocess.CompletedProcess = subprocess.run(
27*523fa7a6SAndroid Build Coastguard Worker                [self._path] + args, capture_output=True, cwd=BUCK_CWD, check=True
28*523fa7a6SAndroid Build Coastguard Worker            )
29*523fa7a6SAndroid Build Coastguard Worker            return [line.strip().decode("utf-8") for line in cp.stdout.splitlines()]
30*523fa7a6SAndroid Build Coastguard Worker        except subprocess.CalledProcessError as ex:
31*523fa7a6SAndroid Build Coastguard Worker            raise RuntimeError(ex.stderr.decode("utf-8")) from ex
32*523fa7a6SAndroid Build Coastguard Worker
33*523fa7a6SAndroid Build Coastguard Worker
34*523fa7a6SAndroid Build Coastguard Workerdef get_buck2_version(path: str) -> Optional[str]:
35*523fa7a6SAndroid Build Coastguard Worker    try:
36*523fa7a6SAndroid Build Coastguard Worker        runner = Buck2Runner(path)
37*523fa7a6SAndroid Build Coastguard Worker        output = runner.run(["--version"])
38*523fa7a6SAndroid Build Coastguard Worker
39*523fa7a6SAndroid Build Coastguard Worker        # Example output:
40*523fa7a6SAndroid Build Coastguard Worker        # buck2 38f7c508bf1b87bcdc816bf56d1b9f2d2411c6be <build-id>
41*523fa7a6SAndroid Build Coastguard Worker        #
42*523fa7a6SAndroid Build Coastguard Worker        # We want the second value.
43*523fa7a6SAndroid Build Coastguard Worker
44*523fa7a6SAndroid Build Coastguard Worker        return output[0].split()[1]
45*523fa7a6SAndroid Build Coastguard Worker
46*523fa7a6SAndroid Build Coastguard Worker    except Exception as e:
47*523fa7a6SAndroid Build Coastguard Worker        print(f"Failed to retrieve buck2 version: {e}.", file=sys.stderr)
48*523fa7a6SAndroid Build Coastguard Worker        return None
49