Repository: apache/airflow
File: dev/breeze/src/airflow_breeze/utils/run_utils.py (Python)

Code before:
        os.killpg(gid, signal.SIGTERM)


def clean_ui_assets():
    get_console().print("[info]Cleaning ui assets[/]")
    UI_ASSET_HASH_PATH.unlink(missing_ok=True)
    shutil.rmtree(UI_NODE_MODULES_PATH, ignore_errors=True)
    shutil.rmtree(UI_DIST_PATH, ignore_errors=True)
    get_console().print("[success]Cleaned ui assets[/]")


def run_compile_ui_assets(
    dev: bool,
    run_in_background: bool,
    force_clean: bool,
    additional_ui_hooks: list[str],
):
    if force_clean:
        clean_ui_assets()
    if dev:
        get_console().print("\n[warning] The command below will run forever until you press Ctrl-C[/]\n")
        get_console().print(
            "\n[info]If you want to see output of the compilation command,\n"
            "[info]cancel it, go to airflow/ui folder and run 'pnpm dev'.\n"
            "[info]However, it requires you to have local pnpm installation.\n"
        )
    command_to_execute = [
        "prek",
        "run",
        "--hook-stage",
        "manual",
        "compile-ui-assets-dev" if dev else "compile-ui-assets",
        *additional_ui_hooks,
        "--all-files",
        "--verbose",
    ]
    get_console().print(
        "[info]The output of the asset compilation is stored in: [/]"
        f"{UI_ASSET_OUT_DEV_MODE_FILE if dev else UI_ASSET_OUT_FILE}\n"
    )
    if run_in_background:
        pid = os.fork()
        if pid:
            # Parent process - send signal to process group of the child process
            atexit.register(kill_process_group, pid)
        else:
            # Check if we are not a group leader already (We should not be)
            if os.getpid() != os.getsid(0):
                # and create a new process group where we are the leader
                os.setpgid(0, 0)
            _run_compile_internally(command_to_execute, dev, UI_ASSET_COMPILE_LOCK, UI_ASSET_OUT_FILE)

Review comment (suggestion):
The additional_ui_hooks parameter is added as a required positional parameter with default. Looks like not all callers are updated. Consider adding a default value `additional_ui_hooks: list[str] = []` ? 

https://github.com/apache/airflow/blob/bfaf4ffc4881fb21e8303bb9cf07d22a9e226a9d/dev/breeze/src/airflow_breeze/commands/ui_commands.py#L713

```suggestion
    additional_ui_hooks: list[str] = [],
```

Code after:
    Kills all processes in the process group and ignore if the group is missing.

    :param gid: process group id
    """
    with contextlib.suppress(OSError):
        os.killpg(gid, signal.SIGTERM)


def _clean_ui_assets(additional_ui_hooks: list[str]):
    get_console().print("[info]Cleaning ui assets[/]")
    UI_ASSET_HASH_PATH.unlink(missing_ok=True)
    shutil.rmtree(UI_NODE_MODULES_PATH, ignore_errors=True)
    shutil.rmtree(UI_DIST_PATH, ignore_errors=True)
    shutil.rmtree(FAST_API_SIMPLE_AUTH_MANAGER_NODE_MODULES_PATH, ignore_errors=True)
    shutil.rmtree(FAST_API_SIMPLE_AUTH_MANAGER_DIST_PATH, ignore_errors=True)
    if EDGE_PLUGIN_PREK_HOOK in additional_ui_hooks:
        shutil.rmtree(EDGE_PLUGIN_UI_NODE_MODULES_PATH, ignore_errors=True)
        shutil.rmtree(EDGE_PLUGIN_UI_DIST_PATH, ignore_errors=True)
    get_console().print("[success]Cleaned ui assets[/]")


def run_compile_ui_assets(
    dev: bool,
    run_in_background: bool,
    force_clean: bool,
    additional_ui_hooks: list[str],
):
    if force_clean:
        _clean_ui_assets(additional_ui_hooks)
    if dev:
        get_console().print("\n[warning] The command below will run forever until you press Ctrl-C[/]\n")
        get_console().print(
            "\n[info]If you want to see output of the compilation command,\n"
            "[info]cancel it, go to airflow/ui folder and run 'pnpm dev'.\n"
            "[info]However, it requires you to have local pnpm installation.\n"
        )
    command_to_execute = [
        "prek",
        "run",
        "--hook-stage",
        "manual",
        "compile-ui-assets-dev" if dev else "compile-ui-assets",
        *additional_ui_hooks,
        "--all-files",
        "--verbose",
    ]
    get_console().print(
        "[info]The output of the asset compilation is stored in: [/]"
        f"{UI_ASSET_OUT_DEV_MODE_FILE if dev else UI_ASSET_OUT_FILE}\n"
    )
    if run_in_background: