hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit d858829e8243c0ff4d3c5c025553450b24036741
parent 71465a4db2a0693314450e76e1de9ecff272235a
Author: Alexey Yerin <yyp@disroot.org>
Date:   Sun, 20 Feb 2022 15:19:22 +0300

cmd/hare: add a progress indicator when building

Fixes: https://todo.sr.ht/~sircmpwn/hare/573
Signed-off-by: Alexey Yerin <yyp@disroot.org>

Diffstat:
Mcmd/hare/plan.ha | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcmd/hare/schedule.ha | 5+++++
2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/cmd/hare/plan.ha b/cmd/hare/plan.ha @@ -2,11 +2,14 @@ use fmt; use fs; use hare::ast; use hare::module; +use io; +use math; use os::exec; use os; use path; use strings; use temp; +use unix::tty; type status = enum { SCHEDULED, @@ -19,12 +22,18 @@ type task = struct { depend: []*task, output: str, cmd: []str, + module: (str | void), }; fn task_free(task: *task) void = { free(task.depend); free(task.output); free(task.cmd); + match (task.module) { + case let s: str => + free(s); + case => void; + }; free(task); }; @@ -126,6 +135,16 @@ fn plan_execute(plan: *plan, verbose: bool) (void | !exec::exit_status) = { }; }; + let current_module = ""; + let current = 0z; + const total = len(plan.scheduled); + // Disable progress when used with -v + const term = if (!verbose && tty::isatty(os::stderr)) { + yield os::stderr; + } else { + yield; + }; + for (len(plan.scheduled) != 0) { let next: nullable *task = null; let i = 0z; @@ -151,6 +170,34 @@ fn plan_execute(plan: *plan, verbose: bool) (void | !exec::exit_status) = { yield t; }; + match (task.module) { + case let s: str => + current_module = s; + case => void; + }; + + match (term) { + case let term: io::file => + current += 1; + fmt::fprintf(term, "\r\x1b[K[{%}/{}] [", + current, &fmt::modifiers { + width = math::ceilf64(math::log10f64( + total: f64)): uint, + ... + }, + total)!; + const stop = (current: f64 / total: f64 * 50.0): size; + for (let i = 0z; i < 50; i += 1) { + if (i > stop) { + fmt::fprint(term, ".")!; + } else { + fmt::fprint(term, "#")!; + }; + }; + fmt::fprintf(term, "] {}", current_module)!; + case => void; + }; + match (execute(plan, task, verbose)) { case let err: exec::error => fmt::fatal("Error: {}: {}", task.cmd[0], @@ -168,6 +215,12 @@ fn plan_execute(plan: *plan, verbose: bool) (void | !exec::exit_status) = { append(plan.complete, task); }; + match (term) { + case let term: io::file => + fmt::fprintln(term)!; + case => void; + }; + update_modcache(plan); }; diff --git a/cmd/hare/schedule.ha b/cmd/hare/schedule.ha @@ -70,6 +70,7 @@ fn sched_ld(plan: *plan, output: str, depend: *task...) *task = { "-T", plan.script, "-o", output, ]), + module = void, }); // Using --gc-sections will not work when using cc as the linker @@ -104,6 +105,7 @@ fn sched_ar(plan: *plan, output: str, depend: *task...) *task = { cmd = alloc([ os::tryenv("AR", "ar"), "-csr", output, ]), + module = void, }); for (let i = 0z; i < len(depend); i += 1) { assert(strings::hassuffix(depend[i].output, ".o")); @@ -122,6 +124,7 @@ fn sched_as(plan: *plan, output: str, input: str, depend: *task...) *task = { cmd = alloc([ os::tryenv("AS", "as"), "-g", "-o", output, input, ]), + module = void, }); append(plan.scheduled, task); return task; @@ -136,6 +139,7 @@ fn sched_qbe(plan: *plan, output: str, depend: *task) *task = { cmd = alloc([ os::tryenv("QBE", "qbe"), "-o", output, depend.output, ]), + module = void, }); append(plan.scheduled, task); return task; @@ -166,6 +170,7 @@ fn sched_hare_object( cmd = alloc([ os::tryenv("HAREC", "harec"), "-o", ssa, ]), + module = strings::dup(ns), }); for (let i = 0z; i < len(plan.context.tags); i += 1) {