cli.v

2.9 KB · raw

1//! Command line entry: dispatch table, usage text and exit codes.2//!3//! Exit codes are fixed across every command: 0 success, 1 refusal or error,4//! 2 bad usage. Each command returns its code; nothing else calls `exit`.56module cli78import src.fmt910// Read from VERSION at build time, so the binary and the manifest cannot drift.11pub const version = $embed_file('../../VERSION').to_string().trim_space()1213// The help screen. It is built rather than embedded in a constant, because the14// colour follows NO_COLOR, KOH_NO_COLOR and whether the output is a terminal.15// Flags are not shown here: `koh man <command>` documents every one.16pub fn usage_text() string {17	groups := [18		[19			['save', 'snapshot your work'],20			['checkpoint', 'mark a place to come back to'],21			['status', 'what changed'],22			['view', 'browse saves and checkpoints'],23			['diff', 'show changes'],24		],25		[26			['undo', 'step back'],27			['revert', 'throw away unsaved changes'],28			['load', 'go to any save'],29		],30		[31			['offer', 'send to your remote'],32			['steal', 'bring in from your remote'],33		],34	]35	mut text := '${fmt.light('koh ${version} — version control for the solo developer')}\n'36	for group in groups {37		text += '\n'38		for row in group {39			text += '  ${fmt.gold(row[0])}${' '.repeat(12 - row[0].len)}${fmt.muted(row[1])}\n'40		}41	}42	// The list grows as commands land, and the screen keeps to 80 columns, so it43	// wraps rather than running off the edge.44	text += '\n  ${fmt.dim('also: remote · flag · pluck · peek · build · update')}\n'45	text += '        ${fmt.dim('init · doctor · strip · migrate')}\n'46	text += '\n  ${fmt.dim('koh man <command>  for options and examples')}\n'47	return text48}4950pub fn run(argv []string) int {51	if argv.len < 2 {52		eprintln(usage_text())53		return 254	}55	hand_over(argv)56	rest := argv[2..]57	match argv[1] {58		'--version', '-v' {59			println('koh ${version}')60			return 061		}62		'--help', '-h' {63			println(usage_text())64			return 065		}66		'init' {67			return cmd_init(rest)68		}69		'save' {70			return cmd_save(rest, false)71		}72		'checkpoint' {73			return cmd_save(rest, true)74		}75		'status' {76			return cmd_status(rest)77		}78		'view' {79			return cmd_view(rest)80		}81		'diff' {82			return cmd_diff(rest)83		}84		'undo' {85			return cmd_undo(rest)86		}87		'revert' {88			return cmd_revert(rest)89		}90		'load' {91			return cmd_load(rest)92		}93		'flag' {94			return cmd_flag(rest)95		}96		'pluck' {97			return cmd_pluck(rest)98		}99		'peek' {100			return cmd_peek(rest)101		}102		'doctor' {103			return cmd_doctor(rest)104		}105		'strip' {106			return cmd_strip(rest)107		}108		'remote' {109			return cmd_remote(rest)110		}111		'offer' {112			return cmd_offer(rest)113		}114		'steal' {115			return cmd_steal(rest)116		}117		'build' {118			return cmd_build(rest)119		}120		'update' {121			return cmd_update(rest)122		}123		'migrate' {124			return cmd_migrate(rest)125		}126		'man', 'help' {127			return cmd_man(rest)128		}129		else {130			return usage_error('unknown command "${argv[1]}" — run "koh --help" for the command list')131		}132	}133}