//! `koh update` — put a newer published koh in place of this one (§12). //! //! Nothing is installed without being asked, and nothing is removed: the new //! binary replaces the running one by rename, which is the step that makes the //! change visible. module cli import json2 import src.build import src.update pub fn cmd_update(raw []string) int { args := parse('update', raw, Options{ flags: ['check', 'json', 'yes'] }) or { return usage_error(err.msg()) } if args.positional.len > 0 { return usage_error('update takes no arguments, not "${args.positional_at(0)}"') } if args.json() && !args.flag('yes') && !args.flag('check') { // The question cannot be asked inside a JSON document, so an install asked // for in JSON has to be asked for with --yes as well. That is a mistake in // the command line, not a refusal of the work. return usage_error('--json needs --yes when it would install') } current := version platform := build.this_machine() or { return refuse(args.json(), err.msg()) } checked := update.check(current, platform) or { return refuse(args.json(), err.msg()) } latest := if checked.update { checked.available } else { if args.json() { emit_json(json2.encode(UpdateJson{ current: current latest: current available: false })) } else { ok('koh ${current} is the newest — nothing to do') } return 0 } if args.flag('check') { if args.json() { emit_json(json2.encode(UpdateJson{ current: current latest: latest.version available: true notes: latest.notes })) } else { ok('koh ${latest.version} is available — you have ${current}') if latest.notes != '' { note(latest.notes) } note('run "koh update" to install it') } // `--check` reports and says so with its exit code, so a script can ask. return 1 } if !args.json() { note('${current} → ${latest.version}') if latest.notes != '' { note(latest.notes) } } // A "no" at the question is a refusal, not a reason to carry on. approved := confirm(args.flag('yes')) or { return refuse(args.json(), err.msg()) } if !approved { return refuse(args.json(), 'not updating, then') } target := update.install(latest) or { return refuse(args.json(), err.msg()) } if args.json() { emit_json(json2.encode(UpdateJson{ current: current latest: latest.version available: true installed: target })) return 0 } ok('installed koh ${latest.version} as ${target}') return 0 } struct UpdateJson { current string latest string available bool installed string notes string }