output.v

1.6 KB · raw

1//! Output for the command line: the ✦ / ✗ habit, and the `--json` shapes2//! agents read.3//!4//! Colour comes from `src.fmt`, so turning it off turns it off everywhere.5//! Every command that prints data has a JSON form with stable field names, and6//! every error is `{"error": "..."}` on stderr. Exit codes are fixed: 07//! success, 1 refusal or error, 2 bad usage.89module cli1011import json212import os13import src.fmt1415// ok, note and warn print on stdout after clearing the progress line; errors go to stderr.16pub fn ok(message string) {17	done_working()18	println('  ${fmt.amber(fmt.glyph_ok)} ${message}')19}2021pub fn note(message string) {22	done_working()23	println('  ${fmt.dim(message)}')24}2526pub fn warn(message string) {27	done_working()28	println('  ${fmt.amber('!')} ${message}')29}3031// fail prints a refusal and returns the exit code to hand back.32pub fn fail(message string) int {33	done_working()34	eprintln('  ${fmt.red(fmt.glyph_fail)} ${message}')35	return 136}3738pub fn fail_json(message string) int {39	eprintln(json2.encode({40		'error': message41	}))42	return 143}4445// usage_error reports a mistake in the command line itself. It can happen46// before the options are parsed, so `--json` is looked for on the raw line.47pub fn usage_error(message string) int {48	if '--json' in os.args {49		fail_json(message)50	} else {51		eprintln('  ${fmt.red(fmt.glyph_fail)} ${message}')52	}53	return 254}5556// refuse reports an error in whichever shape the command was asked for.57pub fn refuse(as_json bool, message string) int {58	if as_json {59		return fail_json(message)60	}61	return fail(message)62}6364pub fn emit_json(value string) {65	done_working()66	println(value)67}