12345678module cli910import json11import os1213const glyph_ok = '✦'14const glyph_fail = '✗'1516pub fn color_enabled() bool {17 if os.getenv('NO_COLOR') != '' || os.getenv('KOH_NO_COLOR') != '' {18 return false19 }20 return os.is_atty(1) != 021}2223fn paint(text string, code string) string {24 if !color_enabled() {25 return text26 }27 return '\x1b[${code}m${text}\x1b[0m'28}2930pub fn amber(text string) string {31 return paint(text, '38;5;214')32}3334pub fn red(text string) string {35 return paint(text, '38;5;203')36}3738pub fn dim(text string) string {39 return paint(text, '38;5;245')40}4142pub fn green(text string) string {43 return paint(text, '38;5;114')44}4546pub fn ok(message string) {47 println(' ${amber(glyph_ok)} ${message}')48}4950pub fn note(message string) {51 println(' ${dim(message)}')52}5354pub fn warn(message string) {55 println(' ${amber('!')} ${message}')56}575859pub fn fail(message string) int {60 eprintln(' ${red(glyph_fail)} ${message}')61 return 162}6364pub fn fail_json(message string) int {65 eprintln(json.encode({66 'error': message67 }))68 return 169}7071pub fn usage_error(message string) int {72 eprintln(' ${red(glyph_fail)} ${message}')73 return 274}757677pub fn refuse(as_json bool, message string) int {78 if as_json {79 return fail_json(message)80 }81 return fail(message)82}8384pub fn emit_json(value string) {85 println(value)86}