commit 3629cb72436f1c154033ed74ac01ff196efdb095 Author: Matthew Bessette Date: Sat Mar 15 20:56:50 2025 -0400 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..48d0315 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +bin +!bin/.githold diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..826c07a --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +build: + amber build src/index.amber bin/some-cli + +clean: + rm -rf bin + mkdir bin + touch bin/.githold diff --git a/src/command-hooks/help.amber b/src/command-hooks/help.amber new file mode 100644 index 0000000..6c3822e --- /dev/null +++ b/src/command-hooks/help.amber @@ -0,0 +1,10 @@ +import { bold, echo_info, underlined } from "std/env" + +pub fun help(): Null { + const usage = underlined(bold("Usage")) + const commands = underlined(bold("Commands")) + echo_info("{usage}: some-cli [--flag[=value]] [-f[=value]]") + echo_info("") + echo_info("{commands}") + echo_info(" help Print this message or the help of the given command") +} diff --git a/src/helpers/arg-parser.amber b/src/helpers/arg-parser.amber new file mode 100644 index 0000000..6c46676 --- /dev/null +++ b/src/helpers/arg-parser.amber @@ -0,0 +1,55 @@ +import { array_find, array_find_all, array_remove_at } from "std/array" +import { slice, split_chars, starts_with, text_contains } from "std/text" + +fun remove_prefix(arg: Text): Text? { + + if starts_with(arg, "--") { + return slice(arg, 2) + } + + if starts_with(arg, "-") { + return slice(arg, 1) + } + + fail 2 // "Flags must start with `--` or `-` given {arg}" +} + +fun safe_split_flag(arg: Text): [Text] { + + const string_of_chars = split_chars(arg) + const first_equals = array_find(string_of_chars, "=") + + if first_equals == -1 { + return [arg, ""] + } + + const flag = slice(arg, 0, first_equals) + const value = slice(arg, first_equals+1) + echo "{flag} {value}" + return [flag, value] +} + +// Returns associative map of flagName -> value or flagName -> "" if just present +pub fun arg_parser(arguments: [Text]): [Text]? { + + if len(arguments) < 3 { + return [Text] + } + + let results = [Text] + + for i in 2..len(arguments) { + const arg = remove_prefix(arguments[i]) failed { + fail status + } + + if text_contains(arg, "=") { + results = results + safe_split_flag(arg) + continue + } + + results = results + [arg, ""] + } + + return results +} diff --git a/src/helpers/resolve-status-code.amber b/src/helpers/resolve-status-code.amber new file mode 100644 index 0000000..2f1d08a --- /dev/null +++ b/src/helpers/resolve-status-code.amber @@ -0,0 +1,8 @@ +pub fun resolve_status_code(code: Num): Text { + if { + code == 0: return "" + code == 1: return "Unknown error..." + code == 2: return "Flags must start with `--` or `-`" + else: return "Unknown error... {code}" + } +} diff --git a/src/index.amber b/src/index.amber new file mode 100644 index 0000000..ecee25f --- /dev/null +++ b/src/index.amber @@ -0,0 +1,20 @@ +import { arg_parser } from "./helpers/arg-parser.amber" +import { resolve_status_code } from "./helpers/resolve-status-code.amber" +import { help } from "./command-hooks/help.amber" +import { echo_error } from "std/env" + +main(cli_params) { + + const command = cli_params[1] + const flags = arg_parser(cli_params) failed { + echo_error(resolve_status_code(status)) + fail 1 + } + + echo "We parsed: command={command} flags={flags}" + + if { + command == "help": help() + else: help() + } +}