From 906dbeeb744894e3a6d70451e4215ebb171fc095 Mon Sep 17 00:00:00 2001 From: Hexagon Date: Sun, 17 Mar 2024 01:44:32 +0100 Subject: [PATCH] Add rest collector (collect everything after stray in arguments to --- deno.json | 2 +- utils/args.test.ts | 58 ++++++++++++++++++++++++++++++++++++++++++++++ utils/args.ts | 36 ++++++++++++++++++++++++---- 3 files changed, 91 insertions(+), 5 deletions(-) diff --git a/deno.json b/deno.json index 89130a9..db6b7a3 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "name": "@cross/utils", - "version": "0.5.0", + "version": "0.6.0", "exports": { ".": "./mod.ts", "./ansi": "./utils/ansi.ts", diff --git a/utils/args.test.ts b/utils/args.test.ts index 2090152..7e69ddf 100644 --- a/utils/args.test.ts +++ b/utils/args.test.ts @@ -14,6 +14,7 @@ test("Parse arguments using space as separator", () => { configFile: ["app.config"], }, loose: [], + rest: "", }); }); @@ -26,6 +27,7 @@ test("Parse arguments using equal sign as separator", () => { arg: ["asd"], }, loose: [], + rest: "", }); }); @@ -39,6 +41,7 @@ test("Handle flags with no values", () => { debug: [true], }, loose: [], + rest: "", }); }); @@ -51,6 +54,7 @@ test("Handle an argument at the end", () => { port: ["8080"], }, loose: ["app.config"], + rest: "", }); }); @@ -63,6 +67,7 @@ test("Handle empty arguments", () => { flag: [""], }, loose: [], + rest: "", }); }); @@ -75,6 +80,7 @@ test("Handle arguments with embedded equals signs", () => { path: ["/my/path=with/equals"], }, loose: [], + rest: "", }); }); @@ -88,6 +94,7 @@ test("Handle multiple occurrences of a flag", () => { config: ["prod.config"], }, loose: [], + rest: "", }); }); @@ -111,3 +118,54 @@ test("Test ArgsParser methods", () => { // Add a method to get loose arguments for completeness (optional) assertEquals(parser.getLoose(), ["file.txt"]); }); + +test("Handle everything after '--' as the rest command", () => { + const cmdArgs = ["--port", "8080", "--", "run", "server", "--debug"]; + const parsedArgs = ArgsParser.parseArgs(cmdArgs); + + assertEquals(parsedArgs, { + args: { + port: ["8080"], + }, + loose: [], + rest: "run server --debug", + }); + + const parser = new ArgsParser(cmdArgs); + assertEquals(parser.getRest(), "run server --debug"); + assertEquals(parser.hasRest(), true); +}); + +test("Handle multiple '--' delimiters", () => { + const cmdArgs = ["--flag", "--", "start", "--", "build"]; + const parsedArgs = ArgsParser.parseArgs(cmdArgs); + + assertEquals(parsedArgs, { + args: { + flag: [true], + }, + loose: [], + rest: "start -- build", + }); + + const parser = new ArgsParser(cmdArgs); + assertEquals(parser.getRest(), "start -- build"); + assertEquals(parser.hasRest(), true); +}); + +test("Handle the '--' delimiter at the end", () => { + const cmdArgs = ["--flag", "--"]; + const parsedArgs = ArgsParser.parseArgs(cmdArgs); + + assertEquals(parsedArgs, { + args: { + flag: [true], + }, + loose: [], + rest: "", + }); + + const parser = new ArgsParser(cmdArgs); + assertEquals(parser.getRest(), ""); + assertEquals(parser.hasRest(), false); +}); diff --git a/utils/args.ts b/utils/args.ts index c2c4b6b..efbf7a0 100644 --- a/utils/args.ts +++ b/utils/args.ts @@ -46,6 +46,7 @@ export function args(all: boolean = false): string[] { export class ArgsParser { private readonly parsedArgs: Record; private readonly looseArgs: string[]; + private readonly restCommand: string = ""; /** * Parses command-line arguments. @@ -58,13 +59,23 @@ export class ArgsParser { */ public static parseArgs( cmdArgs: string[], - ): { args: Record; loose: string[] } { + ): { + args: Record; + loose: string[]; + rest: string; + } { const parsedArgs: Record = {}; const looseArgs: string[] = []; - + let restCommand = ""; + let collectingRest = false; for (let i = 0; i < cmdArgs.length; i++) { const arg = cmdArgs[i]; - if (arg.startsWith("--") || arg.startsWith("-")) { + + if (collectingRest) { + restCommand += (restCommand ? " " : "") + arg; // Join with spaces + } else if (arg === "--") { + collectingRest = true; + } else if (arg.startsWith("--") || arg.startsWith("-")) { const parts = arg.slice(arg.startsWith("--") ? 2 : 1).split("="); const key = parts[0]; let value: string | boolean = true; // Default to boolean for flags @@ -90,13 +101,14 @@ export class ArgsParser { } } - return { args: parsedArgs, loose: looseArgs }; + return { args: parsedArgs, loose: looseArgs, rest: restCommand }; } constructor(cmdArgs: string[]) { const result = ArgsParser.parseArgs(cmdArgs); this.parsedArgs = result.args; this.looseArgs = result.loose; + this.restCommand = result.rest; } /** @@ -146,4 +158,20 @@ export class ArgsParser { countLoose(): number { return this.looseArgs.length; } + + /** + * Returns the remaining command portion collected after the "--" delimiter. + * @returns {string} The rest of the command. + */ + getRest(): string { + return this.restCommand; + } + + /** + * Checks whether a command portion was collected after the "--" delimiter. + * @returns {boolean} True if a rest command exists, false otherwise. + */ + hasRest(): boolean { + return this.restCommand !== ""; + } }