//! Command line entry: dispatch table, usage text and exit codes. //! //! Exit codes are fixed across every command: 0 success, 1 refusal or error, //! 2 bad usage. Each command returns its code; nothing else calls `exit`. module cli import src.fmt // Read from VERSION at build time, so the binary and the manifest cannot drift. pub const version = $embed_file('../../VERSION').to_string().trim_space() // The help screen. It is built rather than embedded in a constant, because the // colour follows NO_COLOR, KOH_NO_COLOR and whether the output is a terminal. // Flags are not shown here: `koh man ` documents every one. pub fn usage_text() string { commands := [ ['save', 'snapshot your work'], ['checkpoint', 'mark a place to come back to'], ['status', 'where things stand'], ['view', 'browse saves and checkpoints'], ['diff', 'what changed'], ['undo', 'step back'], ['revert', 'throw away unsaved changes'], ['load', 'go to any save'], ['offer', 'send to your remote'], ['steal', 'bring in from your remote'], ] mut text := '${fmt.light('koh ${version} — version control for the solo developer')}\n' // A blank line between commands, so the eye lands on one line at a time, and // the list grows as commands land. for row in commands { text += '\n ${fmt.gold(row[0])}${' '.repeat(12 - row[0].len)}${fmt.muted(row[1])}\n' } text += '\n ${fmt.dim('also: remote · flag · pluck · peek · build · update')}\n' text += ' ${fmt.dim('init · doctor · ignore · strip · migrate')}\n' text += '\n ${fmt.dim('koh man for options and examples')}\n' text += '\n ${fmt.dim('Asha Software · asha.software')}\n' return text } pub fn run(argv []string) int { if argv.len < 2 { eprintln(usage_text()) return 2 } if needs_migration(argv) { return refuse('--json' in argv, 'this is a Koh 2 repo — run "koh migrate" first') } rest := argv[2..] match argv[1] { '--version', '-v' { println('koh ${version}') return 0 } '--help', '-h' { println(usage_text()) return 0 } 'init' { return cmd_init(rest) } 'save' { return cmd_save(rest, false) } 'checkpoint' { return cmd_save(rest, true) } 'status' { return cmd_status(rest) } 'view' { return cmd_view(rest) } 'diff' { return cmd_diff(rest) } 'undo' { return cmd_undo(rest) } 'revert' { return cmd_revert(rest) } 'load' { return cmd_load(rest) } 'flag' { return cmd_flag(rest) } 'pluck' { return cmd_pluck(rest) } 'peek' { return cmd_peek(rest) } 'doctor' { return cmd_doctor(rest) } 'ignore' { return cmd_ignore(rest) } 'strip' { return cmd_strip(rest) } 'remote' { return cmd_remote(rest) } 'offer' { return cmd_offer(rest) } 'steal' { return cmd_steal(rest) } 'build' { return cmd_build(rest) } 'update' { return cmd_update(rest) } 'migrate' { return cmd_migrate(rest) } 'man', 'help' { return cmd_man(rest) } else { return usage_error('unknown command "${argv[1]}" — run "koh --help" for the command list') } } }