/// `--verbose` progress logging for the self-hosted compiler: one line /// per pipeline stage and one line per module load, ANSI-colored when the /// environment supports it. /// /// Why this module exists: the bootstrap self-compile runs for minutes /// (interpreted) and, with `--verbose`, used to print only the target /// module -- the dependency walk and the codegen stages were silent, so /// a long run gave no way to tell a healthy compile from a wedged one /// (that invisibility is half of why `monad:bootstrap-compile`'s old /// `timeout 1200` killed healthy runs: nothing in the output said /// "progressing"). The CI task now runs untimed and relies on this trace /// instead (devenv.nix, ci.yml's hang-guard comments). /// /// Rules the call sites depend on: /// - every helper gates on `verbose` ITSELF, so a call site is one call /// and `if verbose then ... else return unit` noise does not spread /// through the loading chain (`ok_line`/`fail_line` are deliberately /// NOT gated: the finish/failure lines print in both modes, as they /// did before this module existed); /// - prints are IO effects only, never term rewrites -- the emitted IR /// is identical with or without them (the bootstrap ladder's /// fixpoint property depends on that, so keep it true); /// - granularity is per-stage and per-module, never per-def: this code /// runs inside the compiler being timed, and a per-def print in the /// compile path would slow the very thing it instruments. (The /// `check` command's own per-def trace is separate and stays as is.) /// /// Colors: `std.ansi`'s `colors_enabled` checks NO_COLOR (always wins, /// the off switch) / FORCE_COLOR / TERM=dumb, with deliberately no /// isatty check -- so piped CI job logs get colors too, which Forgejo /// and GitHub render in the run view. use io {IO} open IO {println} // `Ansi.fail`/`Ansi.pass` are DOTTED names -- see std/ansi.mo's own doc // comment on `Ansi.fail` for why a bare `def fail` there poisoned the // whole loaded set (parser's bare ParseResult `fail` ctor got rewritten // to it by qualify's `resolve_owner` rule 3, which knows defs only). use lib::ansi {bold, colors_enabled, dim, fail, pass} use lib::bench {since} /// `wrap s` (a pure `String -> String` ANSI wrapper from `std.ansi`, /// e.g. `bold`/`dim`/`pass`/`fail`) applied only when colors are on. /// `colored` (std.ansi) already does this env check for plain colors; /// this is the same for style wrappers, which have no checked variant. def styled (s : String) (wrap : String -> String) : IO String := do { let enabled : Bool <- colors_enabled; if enabled then return (wrap s) else return s } /// One pipeline stage starting: `-> stage: