diff --git a/src/cli/args.ts b/src/cli/args.ts index c06c55bf1..ea4169cd9 100644 --- a/src/cli/args.ts +++ b/src/cli/args.ts @@ -206,13 +206,10 @@ export function parseArgs(argv: string[]): { } if (sub === ConfigAction.Set) { const key = argv[2]; - const value = argv[3]; if (key !== ConfigKey.CaCert) { throw new Error(`Unknown config key: ${key ?? "(none)"}. Valid keys: ${ConfigKey.CaCert}`); } - if (!value) { - throw new Error(`cve-lite config set ${ConfigKey.CaCert} requires a path argument`); - } + const value = requireFlagValue(`cve-lite config set ${ConfigKey.CaCert}`, argv[3], "path"); return { command: "config", options, configSubcommand: { action: ConfigAction.Set, key: ConfigKey.CaCert, value } }; } if (sub === ConfigAction.Unset) { diff --git a/tests/cli/config-command.test.ts b/tests/cli/config-command.test.ts index 64a2ed080..6cb01091e 100644 --- a/tests/cli/config-command.test.ts +++ b/tests/cli/config-command.test.ts @@ -2,6 +2,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { jest } from "@jest/globals"; +import { parseArgs } from "../../src/cli/args.js"; import { runConfigCommand } from "../../src/cli/config-command.js"; import { ConfigAction, @@ -117,3 +118,49 @@ describe("runConfigCommand", () => { expect(logged.join("\n")).toMatch(/is not set\./); }); }); + +describe("parseArgs - config set", () => { + it("accepts a valid certificate path", () => { + const result = parseArgs(["config", "set", "ca-cert", "/path/to/cert.pem"]); + expect(result.command).toBe("config"); + expect(result.configSubcommand).toEqual({ + action: ConfigAction.Set, + key: ConfigKey.CaCert, + value: "/path/to/cert.pem", + }); + }); + + it("accepts a valid dash-prefixed relative path", () => { + const result = parseArgs(["config", "set", "ca-cert", "./-cert.pem"]); + expect(result.command).toBe("config"); + expect(result.configSubcommand).toEqual({ + action: ConfigAction.Set, + key: ConfigKey.CaCert, + value: "./-cert.pem", + }); + }); + + it("rejects when the certificate path is missing", () => { + expect(() => parseArgs(["config", "set", "ca-cert"])).toThrow( + "cve-lite config set ca-cert requires a path argument", + ); + }); + + it("rejects an empty certificate path", () => { + expect(() => parseArgs(["config", "set", "ca-cert", ""])).toThrow( + "cve-lite config set ca-cert requires a path argument", + ); + }); + + it("rejects a flag passed as the certificate path", () => { + expect(() => parseArgs(["config", "set", "ca-cert", "--json"])).toThrow( + "cve-lite config set ca-cert requires a path argument", + ); + expect(() => parseArgs(["config", "set", "ca-cert", "-h"])).toThrow( + "cve-lite config set ca-cert requires a path argument", + ); + expect(() => parseArgs(["config", "set", "ca-cert", "--ca-cert"])).toThrow( + "cve-lite config set ca-cert requires a path argument", + ); + }); +}); diff --git a/tests/e2e/commands-and-exit-codes.test.ts b/tests/e2e/commands-and-exit-codes.test.ts index c3a7090fa..f62d20a0b 100644 --- a/tests/e2e/commands-and-exit-codes.test.ts +++ b/tests/e2e/commands-and-exit-codes.test.ts @@ -254,6 +254,43 @@ describe("commands + meta", () => { rmProject(certDir); } }); + + it("config set ca-cert rejects a flag as the path argument", () => { + const home = scratch(); + const r = runCli(["config", "set", "ca-cert", "--json"], { env: { HOME: home } }); + expect(r.status).toBe(1); + expect(r.stderr).toMatch(/cve-lite config set ca-cert requires a path argument/); + expect(existsSync(join(home, ".cve-lite-cli", "config.json"))).toBe(false); + }); + + it("config set ca-cert rejects a missing path argument", () => { + const home = scratch(); + const r = runCli(["config", "set", "ca-cert"], { env: { HOME: home } }); + expect(r.status).toBe(1); + expect(r.stderr).toMatch(/cve-lite config set ca-cert requires a path argument/); + expect(existsSync(join(home, ".cve-lite-cli", "config.json"))).toBe(false); + }); + + it("config set ca-cert accepts and saves a valid dash-prefixed relative path", () => { + const home = scratch(); + const certDir = mkProject({ + "-cert.pem": "-----BEGIN CERTIFICATE-----\nMIIB\n-----END CERTIFICATE-----\n", + }); + try { + const set = runCli(["config", "set", "ca-cert", "./-cert.pem"], { + cwd: certDir, + env: { HOME: home }, + }); + expect(set.status).toBe(0); + expect(existsSync(join(home, ".cve-lite-cli", "config.json"))).toBe(true); + + const show = runCli(["config", "show"], { env: { HOME: home } }); + expect(show.status).toBe(0); + expect(show.stdout).toContain("./-cert.pem"); + } finally { + rmProject(certDir); + } + }); }); describe("exit codes", () => {