176a168bcSKirill Bobyrev#!/usr/bin/env python 276a168bcSKirill Bobyrev# 376a168bcSKirill Bobyrev# ===- pipeline_helper.py - Remote Index pipeline Helper *- python -------*--===# 476a168bcSKirill Bobyrev# 576a168bcSKirill Bobyrev# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 676a168bcSKirill Bobyrev# See https://llvm.org/LICENSE.txt for license information. 776a168bcSKirill Bobyrev# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 876a168bcSKirill Bobyrev# 976a168bcSKirill Bobyrev# ===------------------------------------------------------------------------===# 1076a168bcSKirill Bobyrev 1176a168bcSKirill Bobyrevimport argparse 1276a168bcSKirill Bobyrevimport os 1376a168bcSKirill Bobyrevimport subprocess 1476a168bcSKirill Bobyrevfrom socket import socket 1576a168bcSKirill Bobyrevimport sys 1676a168bcSKirill Bobyrevimport time 17d0beda1bSKirill Bobyrevimport threading 18d0beda1bSKirill Bobyrev 19d0beda1bSKirill Bobyrev 2034593ae9SKirill Bobyrevdef kill_process_after_delay(server_process): 21d0beda1bSKirill Bobyrev time.sleep(10) 22d0beda1bSKirill Bobyrev if server_process.poll() is None: 23d0beda1bSKirill Bobyrev server_process.kill() 2476a168bcSKirill Bobyrev 2576a168bcSKirill Bobyrev 2676a168bcSKirill Bobyrevdef main(): 2776a168bcSKirill Bobyrev parser = argparse.ArgumentParser() 28*dd3c26a0STobias Hieta parser.add_argument("--input-file-name", required=True) 29*dd3c26a0STobias Hieta parser.add_argument("--project-root", required=True) 30*dd3c26a0STobias Hieta parser.add_argument("--index-file", required=True) 31*dd3c26a0STobias Hieta parser.add_argument("--server-arg", action="append", default=[]) 32*dd3c26a0STobias Hieta parser.add_argument( 33*dd3c26a0STobias Hieta "--server-log", nargs="?", type=argparse.FileType("wb"), default=os.devnull 34*dd3c26a0STobias Hieta ) 3576a168bcSKirill Bobyrev 3676a168bcSKirill Bobyrev args = parser.parse_args() 3776a168bcSKirill Bobyrev 3876a168bcSKirill Bobyrev # Grab an available port. 3976a168bcSKirill Bobyrev with socket() as s: 40*dd3c26a0STobias Hieta s.bind(("localhost", 0)) 41*dd3c26a0STobias Hieta server_address = "localhost:" + str(s.getsockname()[1]) 4276a168bcSKirill Bobyrev 43*dd3c26a0STobias Hieta print("Initializing clangd-index-server...", file=sys.stderr) 44*dd3c26a0STobias Hieta index_server_process = subprocess.Popen( 45*dd3c26a0STobias Hieta [ 46*dd3c26a0STobias Hieta "clangd-index-server", 47*dd3c26a0STobias Hieta "--server-address=" + server_address, 48*dd3c26a0STobias Hieta args.index_file, 49*dd3c26a0STobias Hieta args.project_root, 50*dd3c26a0STobias Hieta ] 51*dd3c26a0STobias Hieta + args.server_arg, 52*dd3c26a0STobias Hieta stderr=subprocess.PIPE, 53*dd3c26a0STobias Hieta ) 5476a168bcSKirill Bobyrev 55d0beda1bSKirill Bobyrev # This will kill index_server_process if it hangs without printing init 56d0beda1bSKirill Bobyrev # message. 57d0beda1bSKirill Bobyrev shutdown_thread = threading.Thread( 58*dd3c26a0STobias Hieta target=kill_process_after_delay, args=(index_server_process,) 59*dd3c26a0STobias Hieta ) 60d0beda1bSKirill Bobyrev shutdown_thread.daemon = True 61d0beda1bSKirill Bobyrev shutdown_thread.start() 62d0beda1bSKirill Bobyrev 6376a168bcSKirill Bobyrev # Wait for the server to warm-up. 6476a168bcSKirill Bobyrev found_init_message = False 65d0beda1bSKirill Bobyrev while index_server_process.poll() is None: 66686d8a09SSam McCall line = index_server_process.stderr.readline() 67686d8a09SSam McCall args.server_log.write(line) 68686d8a09SSam McCall args.server_log.flush() 69*dd3c26a0STobias Hieta if b"Server listening" in line: 70*dd3c26a0STobias Hieta print("Server initialization complete.", file=sys.stderr) 7176a168bcSKirill Bobyrev found_init_message = True 7276a168bcSKirill Bobyrev break 7376a168bcSKirill Bobyrev 7476a168bcSKirill Bobyrev if not found_init_message: 75*dd3c26a0STobias Hieta print("Server initialization failed. Shutting down.", file=sys.stderr) 7676a168bcSKirill Bobyrev sys.exit(1) 7776a168bcSKirill Bobyrev 78*dd3c26a0STobias Hieta print("Running clangd-index-server-monitor...", file=sys.stderr) 79*dd3c26a0STobias Hieta index_server_monitor_process = subprocess.Popen( 80*dd3c26a0STobias Hieta [ 81*dd3c26a0STobias Hieta "clangd-index-server-monitor", 82*dd3c26a0STobias Hieta server_address, 83*dd3c26a0STobias Hieta ], 84*dd3c26a0STobias Hieta stderr=subprocess.PIPE, 85*dd3c26a0STobias Hieta ) 8634593ae9SKirill Bobyrev 8734593ae9SKirill Bobyrev index_server_monitor_process.wait() 8834593ae9SKirill Bobyrev 8976a168bcSKirill Bobyrev in_file = open(args.input_file_name) 9076a168bcSKirill Bobyrev 91*dd3c26a0STobias Hieta print("Staring clangd...", file=sys.stderr) 92*dd3c26a0STobias Hieta clangd_process = subprocess.Popen( 93*dd3c26a0STobias Hieta [ 94*dd3c26a0STobias Hieta "clangd", 95*dd3c26a0STobias Hieta "--remote-index-address=" + server_address, 96*dd3c26a0STobias Hieta "--project-root=" + args.project_root, 97*dd3c26a0STobias Hieta "--lit-test", 98*dd3c26a0STobias Hieta "--sync", 9976a168bcSKirill Bobyrev ], 100*dd3c26a0STobias Hieta stdin=in_file, 101*dd3c26a0STobias Hieta ) 10276a168bcSKirill Bobyrev clangd_process.wait() 1038e9bde34SKirill Bobyrev print( 104*dd3c26a0STobias Hieta "Clangd executed successfully, shutting down child processes.", file=sys.stderr 105*dd3c26a0STobias Hieta ) 106d0beda1bSKirill Bobyrev index_server_process.kill() 107686d8a09SSam McCall for line in index_server_process.stderr: 108686d8a09SSam McCall args.server_log.write(line) 109686d8a09SSam McCall args.server_log.flush() 11076a168bcSKirill Bobyrev 11134593ae9SKirill Bobyrev for line in index_server_monitor_process.stderr: 11234593ae9SKirill Bobyrev args.server_log.write(line) 11334593ae9SKirill Bobyrev args.server_log.flush() 11434593ae9SKirill Bobyrev 11576a168bcSKirill Bobyrev 116*dd3c26a0STobias Hietaif __name__ == "__main__": 11776a168bcSKirill Bobyrev main() 118