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