configuration/strings/tool.strings.ts

configuration/strings/tool.strings.ts is a file in GovLab Quality. 182 lines of code and 42 definitions.

export const NO_STDERR_DETAIL = "(no detail on stderr)";

export const NO_ERROR_DETAIL = "(no error detail)";

export const UNKNOWN_SIGNAL = "unknown";

export const UNUSED_FILE = "Unused file";

export const UNFORMATTED_FILE = "File is not formatted — run govlab lint to format it.";

export const MISSING_VERIFY = "htmlhint is installed but exposes no verify entry point";

export const NO_ECOSYSTEM = "quality engine: contextFor requires at least one detected ecosystem";

export const UNUSED_LABELS: Readonly<Record<string, string>> = {
    binaries: "unlisted binary",
    dependencies: "dependency",
    devDependencies: "devDependency",
    duplicates: "duplicate export",
    exports: "export",
    types: "exported type",
    unlisted: "unlisted dependency",
    unresolved: "unresolved import",
};

const INSTALL_HINTS: Readonly<Record<string, string>> = {
    actionlint: "actionlint is not installed — install it (e.g. 'scoop install actionlint').",
    brakeman: "brakeman is not installed — run 'gem install brakeman' to scan Rails apps for security issues.",
    "clang-tidy":
        "clang-tidy is not installed — install LLVM (e.g. 'scoop install llvm') and expose clang-tidy on PATH.",
    clippy: "cargo/clippy is not installed — run 'govlab install rust' to add it.",
    "golangci-lint": "golangci-lint is not installed — run 'govlab install go' to add it.",
    gosec: "gosec is not installed. Install it with go install, as the gosec installation guide describes.",
    hadolint: "hadolint is not installed — run 'govlab install dockerfile' (or scoop/brew install hadolint).",
    luacheck: "luacheck is not installed — install it (e.g. 'scoop install luacheck').",
    oxlint: "oxlint is not installed — run 'npm install -D -E oxlint' to add it.",
    phpcs: "phpcs is not installed — run 'composer global require squizlabs/php_codesniffer'.",
    phpmd: "phpmd is not installed — run 'composer global require phpmd/phpmd'.",
    rubocop: "rubocop is not installed — run 'govlab install ruby' to add it.",
    ruff: "ruff is not installed — run 'govlab install python' to add it.",
    shellcheck: "shellcheck is not installed — run 'govlab install shell' (or scoop/apt install shellcheck).",
    stylua: "stylua is not installed — install it (e.g. 'scoop install stylua').",
    tflint: "tflint is not installed — install it (e.g. 'scoop install tflint').",
    trivy: "trivy is not installed — install it (e.g. 'scoop install trivy') to scan IaC misconfigurations.",
};

const MISSING = "is not installed";

const UNRUNNABLE = "could not run";

const COMMAND_HINTS: Readonly<Record<string, readonly [string, string]>> = {
    bandit: [MISSING, "set bandit.command in govlab.config to your bandit interpreter."],
    checkov: [
        MISSING,
        "set checkov.command in govlab.config to your checkov interpreter (e.g. 'py -3.14 -m checkov.main').",
    ],
    checkstyle: [
        UNRUNNABLE,
        "set checkstyle.command in govlab.config to your '<java> -jar <checkstyle.jar>' invocation.",
    ],
    "clj-kondo": [UNRUNNABLE, "set clj-kondo.command in govlab.config to your clj-kondo binary path."],
    credo: [
        UNRUNNABLE,
        "set credo.command in govlab.config to your mix invocation (e.g. 'mix' or 'wsl.exe -e mix') in a project with credo as a dependency.",
    ],
    detekt: [UNRUNNABLE, "set detekt.command in govlab.config to your '<java> -jar <detekt-cli-all.jar>' invocation."],
    kics: [UNRUNNABLE, "set kics.command, kics.queries (its query library) and kics.libraries in govlab.config."],
    lintr: [
        UNRUNNABLE,
        "set lintr.command in govlab.config to your Rscript invocation (e.g. 'Rscript' or 'wsl.exe -e Rscript') with the lintr package installed.",
    ],
    perlcritic: [UNRUNNABLE, "set perlcritic.command in govlab.config (e.g. 'perlcritic' or 'wsl.exe -e perlcritic')."],
    pmd: [
        UNRUNNABLE,
        "set pmd.command in govlab.config to your '<java> -cp \"<pmd>/lib/*\" net.sourceforge.pmd.cli.PmdCli' invocation.",
    ],
    scalastyle: [
        UNRUNNABLE,
        "set scalastyle.command (its '<java> -jar <scalastyle-batch.jar>' invocation) and scalastyle.config (the ruleset XML path) in govlab.config.",
    ],
    semgrep: [
        UNRUNNABLE,
        "set semgrep.command (e.g. 'semgrep' or 'wsl.exe <path>') and semgrep.config (a ruleset) in govlab.config.",
    ],
    slither: [
        UNRUNNABLE,
        "set slither.command (its binary) and slither.solc (the solc path) in govlab.config, e.g. 'pip install slither-analyzer solc-select'.",
    ],
    sqlfluff: [MISSING, "set sqlfluff.command in govlab.config to your sqlfluff interpreter."],
    swiftlint: [
        UNRUNNABLE,
        "set swiftlint.command in govlab.config (e.g. 'swiftlint' or 'wsl.exe -e swiftlint-static', the self-contained Linux binary).",
    ],
    yamllint: [MISSING, "set yamllint.command in govlab.config to your interpreter."],
};

export const commandHint = function commandHint(tool: string, bin: string): string {
    const [lead, instruction] = COMMAND_HINTS[tool] ?? [MISSING, ""];
    return `${bin} ${lead} — ${instruction}`;
};

export const notInstalledOutput = function notInstalledOutput(tool: string): string {
    return `${tool} is not installed.`;
};

export const installHint = function installHint(tool: string): string {
    return INSTALL_HINTS[tool] ?? notInstalledOutput(tool);
};

export const electedMissing = function electedMissing(tool: string): string {
    return `${tool} is not installed — elected as an owner in govlab.config quality.owners but missing from PATH.`;
};

export const spawnErrorMessage = function spawnErrorMessage(tool: string, detail: string): string {
    return `${tool} could not be spawned: ${detail}`;
};

export const toolErrorMessage = function toolErrorMessage(tool: string, status: number, detail: string): string {
    return `${tool} exited with a tool error (exit ${String(status)}): ${detail}`;
};

export const toolErrorBecause = function toolErrorBecause(
    tool: string,
    status: number,
    cause: string,
    detail: string,
): string {
    return `${tool} exited with a tool error (exit ${String(status)}) — likely ${cause}: ${detail}`;
};

export const incompleteScan = function incompleteScan(tool: string, cause: string, detail: string): string {
    return `${tool} could not complete a scan — likely ${cause}: ${detail}`;
};

export const credoIncomplete = function credoIncomplete(status: number, detail: string): string {
    return `mix credo could not complete (exit ${String(status)}) — likely a compile error or a missing credo dependency: ${detail}`;
};

export const scalastyleIncomplete = function scalastyleIncomplete(detail: string): string {
    return `scalastyle did not complete a scan (no "Processed" summary) — likely a missing/invalid ruleset or jar: ${detail}`;
};

export const semgrepFailed = function semgrepFailed(status: number, detail: string): string {
    return `semgrep exited with an error (exit ${String(status)}) — likely a missing/invalid ruleset: ${detail}`;
};

export const lintrFailed = function lintrFailed(status: number, detail: string): string {
    return `lintr (Rscript) exited with an error (exit ${String(status)}): ${detail}`;
};

export const pmdRecoverable = function pmdRecoverable(status: number): string {
    return `pmd exited with a recoverable error (exit ${String(status)}) — some files may not have been fully analyzed.`;
};

export const signalDeathMessage = function signalDeathMessage(tool: string, signal: string): string {
    return `${tool} was terminated by a signal (${signal}) before completing — a killed run is a tool error, not a clean result.`;
};

export const prettierFailed = function prettierFailed(code: number): string {
    return `prettier exited with code ${String(code)} — see output above.`;
};

export const unusedItem = function unusedItem(label: string, name: string): string {
    return `Unused ${label}: ${name}`;
};

export const duplicatedBlock = function duplicatedBlock(file: string, line: number): string {
    return `Duplicated block: also at ${file}:${String(line)}. Lift the shared logic rather than copying it.`;
};

export const unusedDependency = function unusedDependency(dependency: string, manifest: string): string {
    return `"${dependency}" is declared in ${manifest} but never used.`;
};

export const missingDependency = function missingDependency(dependency: string, manifest: string): string {
    return `"${dependency}" is used but not declared in ${manifest}.`;
};

export const dependencyEdge = function dependencyEdge(from: string, to: string): string {
    return `${from} → ${to}`;
};

export const circularDependency = function circularDependency(chain: string): string {
    return `Circular dependency: ${chain}`;
};

export const unimportedExport = function unimportedExport(name: string): string {
    return `"${name}" is exported but never imported.`;
};

export const dryRunFixes = function dryRunFixes(count: number, listed: string): string {
    return `\n${String(count)} file(s) would be fixed (dry-run):\n${listed}\n`;
};

export const outsideWorkspace = function outsideWorkspace(file: string, root: string): string {
    return `safe-fix: ${file} lies outside the workspace root ${root}, so its temp file has no cache home`;
};

export const runSummary = function runSummary(
    errors: number,
    advisory: number,
    notices: number,
    fixedCount: number,
): string {
    return `${String(errors)} error(s), ${String(advisory)} advisory, ${String(notices)} notice(s), ${String(fixedCount)} fixed`;
};

export const missingFlagValue = function missingFlagValue(flag: string): string {
    return `govlab: ${flag} needs a value`;
};

export const unknownReporter = function unknownReporter(value: string, valid: string): string {
    return `govlab: unknown reporter "${value}" — valid: ${valid}`;
};

export const unknownFlag = function unknownFlag(flag: string): string {
    return `govlab: unknown flag "${flag}"`;
};

export const unknownConcern = function unknownConcern(concern: string, valid: string): string {
    return `govlab: unknown concern "${concern}" — valid: ${valid}`;
};