* Copyright (c) 2025 Huawei Technologies Co., Ltd.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {
execSync,
ExecSyncOptionsWithStringEncoding,
} from "node:child_process";
export class CommandExecutor {
public run(
command: string,
args?: Record<string, string | number | boolean | undefined>,
execOptions: ExecSyncOptionsWithStringEncoding = {
encoding: "utf-8",
}
): string {
let commandWithArgs = command;
if (args) {
commandWithArgs += " " + this.stringifyCliArgs(args);
}
return execSync(commandWithArgs, execOptions);
}
protected stringifyCliArgs(
args: Record<string, string | number | boolean | undefined>
): string {
return Object.entries(args)
.filter(([_, value]) => {
if (typeof value === "boolean") {
return value;
}
return value !== undefined && value !== null;
})
.map(([key, value]) => {
if (value === undefined) return "";
const formattedKey = this.toKebabCase(key);
if (typeof value === "boolean") {
return `--${formattedKey}`;
}
return `--${formattedKey} ${value}`;
})
.join(" ");
}
protected toKebabCase(str: string): string {
return str
.replace(/([a-z])([A-Z])/g, "$1-$2")
.replace(/[\s_]+/g, "-")
.toLowerCase();
}
}