import argparse import os import subprocess import sys from core.file_utils import SparkPaths from core.iter_utils import at_bounded def _get_arg_parser(): parser = argparse.ArgumentParser( description="Build the Spark Api Server (websockets)" ) parser.add_argument( "--configuration", metavar="debug|release", help="The build configuration", ) parser.add_argument( "--cmake-jobs", type=int, help="The number of cmake parallel jobs", ) parser.add_argument( "--clean", action="store_true", help="Perform a clean build (remove artifacts from previous build)", ) parser.add_argument( "--verbosity", metavar="{0-5}", choices=range(0, 6), type=int, help="The output verbosity level", ) parser.add_argument( "--dry-run", action="store_true", help="Preview the build commands without running them", ) parser.set_defaults( configuration="debug", clean=False, verbosity=1, ) return parser def _dotnet_verbosity(level): names = ["quiet", "minimal", "normal", "detailed", "diagnostic"] return at_bounded(names, level) def _cmake_verbosity(level): # Skip 'WARNING' and 'NOTICE' levels, since the default CMake verbosity, # 'STATUS', doesn't produce that much output. This also better normalizes # numeric representation of verbosity w/ dotnet, which only has 5 levels. names = [ "ERROR", # 'WARNING', # 'NOTICE', "STATUS", "VERBOSE", "DEBUG", "TRACE", ] return at_bounded(names, level) def _cmake_preset(): match sys.platform: case "win32": return "spark-api-server-windows" case "linux": return "spark-api-server-linux" case _: raise ValueError(f"Unsupported platform {sys.platform}") def _main(): parser = _get_arg_parser() args = parser.parse_args() def run(cmd): print(cmd) if args.dry_run: return subprocess.run(cmd, shell=True).check_returncode() sln = SparkPaths.root().joinpath("Spark.Api.Server.sln") cmake_preset = _cmake_preset() cmake_config = args.configuration.title() cmake_jobs = args.cmake_jobs cmake_verbosity = _cmake_verbosity(args.verbosity) dotnet_config = args.configuration.title() dotnet_verbosity = _dotnet_verbosity(args.verbosity) os.chdir(SparkPaths.root()) if args.clean: run(f"cmake --build build/{cmake_preset} --target clean") run(f"dotnet clean {sln} -c {dotnet_config} -v {dotnet_verbosity}") run(f"cmake --preset {cmake_preset} -DCMAKE_MESSAGE_LOG_LEVEL={cmake_verbosity}") cmake_build_cmd = f"cmake --build build/{cmake_preset} --config {cmake_config}" if cmake_jobs: cmake_build_cmd += f" -j {cmake_jobs}" run(cmake_build_cmd) run(f"dotnet build {sln} -c {dotnet_config} -v {dotnet_verbosity}") if __name__ == "__main__": try: _main() except Exception as e: print(f"build_api_server.py failed: {e}") exit(1)