Add progression reporting.
This commit is contained in:
parent
feaef5a448
commit
e94d8a0c50
4 changed files with 58 additions and 9 deletions
6
examples/run_wait
Executable file
6
examples/run_wait
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/usr/bin/bash
|
||||||
|
set -e
|
||||||
|
cd "$(dirname "$(realpath "$0")")"
|
||||||
|
|
||||||
|
|
||||||
|
../src/regar.ts --hard --progress 'sleep 2s' wdir
|
0
examples/wdir/work.txt
Normal file
0
examples/wdir/work.txt
Normal file
6
package/deploy
Normal file
6
package/deploy
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/usr/bin/bash
|
||||||
|
set -e
|
||||||
|
cd "$(dirname "$(realpath "$0")")"
|
||||||
|
|
||||||
|
./release/package
|
||||||
|
./aur/package
|
55
src/regar.ts
55
src/regar.ts
|
@ -5,13 +5,13 @@ import { Command } from "https://deno.land/x/cliffy@v1.0.0-rc.4/command/mod.ts"
|
||||||
import { Channel, Constructible, InstanceOf } from "https://git.barnulf.net/mb/barnulf_ts/raw/branch/master/mod.ts"
|
import { Channel, Constructible, InstanceOf } from "https://git.barnulf.net/mb/barnulf_ts/raw/branch/master/mod.ts"
|
||||||
import { wait } from "https://git.barnulf.net/mb/barnulf_ts/raw/branch/master/src/lib/utils.ts"
|
import { wait } from "https://git.barnulf.net/mb/barnulf_ts/raw/branch/master/src/lib/utils.ts"
|
||||||
|
|
||||||
const version = "1.0.0"
|
const version = "1.1.0"
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const { do_clear, command, extensions, files, strategy, go_up } = await parse_args()
|
const { do_clear, command, extensions, files, strategy, go_up, show_progress } = await parse_args()
|
||||||
const channel = new Channel<Event>()
|
const channel = new Channel<Event>()
|
||||||
files.map((path) => new Watcher(path, extensions).spin(channel))
|
files.map((path) => new Watcher(path, extensions).spin(channel))
|
||||||
new Runner(command, strategy, do_clear, go_up).spin(channel)
|
new Runner(command, strategy, do_clear, go_up, show_progress).spin(channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function parse_args() {
|
async function parse_args() {
|
||||||
|
@ -26,6 +26,7 @@ async function parse_args() {
|
||||||
.option("-e, --extensions <extentions>", "Comma separated whitelist of extensions to whatch.")
|
.option("-e, --extensions <extentions>", "Comma separated whitelist of extensions to whatch.")
|
||||||
.option("-c, --clear", "Clear the terminal on restart.", { default: false })
|
.option("-c, --clear", "Clear the terminal on restart.", { default: false })
|
||||||
.option("-u, --up", "Scroll the terminal to the start of the command at each run.", { default: false })
|
.option("-u, --up", "Scroll the terminal to the start of the command at each run.", { default: false })
|
||||||
|
.option("-p, --progress", "Show estimated progress on subsequent runs.", { default: false })
|
||||||
.help({ colors: false })
|
.help({ colors: false })
|
||||||
const { args, options } = await cmd.parse()
|
const { args, options } = await cmd.parse()
|
||||||
const [command, ...files] = args
|
const [command, ...files] = args
|
||||||
|
@ -36,7 +37,8 @@ async function parse_args() {
|
||||||
const extensions = options.extensions?.split(",")
|
const extensions = options.extensions?.split(",")
|
||||||
const do_clear = options.clear
|
const do_clear = options.clear
|
||||||
const go_up = options.up
|
const go_up = options.up
|
||||||
return { command, files, strategy, extensions, do_clear, go_up }
|
const show_progress = options.progress
|
||||||
|
return { command, files, strategy, extensions, do_clear, go_up, show_progress }
|
||||||
}
|
}
|
||||||
|
|
||||||
class Watcher {
|
class Watcher {
|
||||||
|
@ -67,6 +69,7 @@ class Runner {
|
||||||
private strategy: ShutdownStrategy,
|
private strategy: ShutdownStrategy,
|
||||||
private do_clear: boolean,
|
private do_clear: boolean,
|
||||||
private go_up: boolean,
|
private go_up: boolean,
|
||||||
|
private show_progress: boolean,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async spin(channel: Channel<Event>) {
|
public async spin(channel: Channel<Event>) {
|
||||||
|
@ -89,7 +92,9 @@ class Runner {
|
||||||
log("running", this.command)
|
log("running", this.command)
|
||||||
console.log()
|
console.log()
|
||||||
const process = new Deno.Command("sh", { args }).spawn()
|
const process = new Deno.Command("sh", { args }).spawn()
|
||||||
process.status.then(this.on_end())
|
let stop: Stop | undefined = undefined
|
||||||
|
if (this.show_progress) stop = this.start_progress()
|
||||||
|
process.status.then(this.on_end(stop))
|
||||||
return process
|
return process
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,20 +106,22 @@ class Runner {
|
||||||
private last_event_date_ms = 0
|
private last_event_date_ms = 0
|
||||||
private debouncing(event: Event) {
|
private debouncing(event: Event) {
|
||||||
const delay_ms = event.date_ms - this.last_event_date_ms
|
const delay_ms = event.date_ms - this.last_event_date_ms
|
||||||
const threshold_ms = 100
|
const threshold_ms = 150
|
||||||
if (delay_ms < threshold_ms) return true
|
if (delay_ms < threshold_ms) return true
|
||||||
this.last_event_date_ms = event.date_ms
|
this.last_event_date_ms = event.date_ms
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private on_end() {
|
private on_end(stop: Stop | undefined) {
|
||||||
if (this.go_up) this.save_cursor()
|
if (this.go_up) this.save_cursor()
|
||||||
const start_ms = Date.now()
|
const start_ms = Date.now()
|
||||||
return () => {
|
return (status: Deno.CommandStatus) => {
|
||||||
const end_ms = Date.now()
|
const end_ms = Date.now()
|
||||||
const time_ms = end_ms - start_ms
|
const time_ms = end_ms - start_ms
|
||||||
|
if (status.success) this.time_estimation_ms = time_ms
|
||||||
const secs = time_ms / 1000
|
const secs = time_ms / 1000
|
||||||
if (this.go_up) this.restore_cursor()
|
if (this.go_up) this.restore_cursor()
|
||||||
|
if (stop !== undefined) stop.stop = true
|
||||||
log("terminated", `${secs} s`)
|
log("terminated", `${secs} s`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +133,25 @@ class Runner {
|
||||||
private restore_cursor() {
|
private restore_cursor() {
|
||||||
console.log("\x1b[u")
|
console.log("\x1b[u")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_estimation_ms = 0
|
||||||
|
private start_progress() {
|
||||||
|
const stop = { stop: false }
|
||||||
|
;(async () => {
|
||||||
|
for await (const step of progress(this.time_estimation_ms)) {
|
||||||
|
if (stop.stop) break
|
||||||
|
const secs = (Math.floor(step.ms / 100) / 10).toString().padStart(3)
|
||||||
|
const total = Math.floor(this.time_estimation_ms / 1_000).toString().padStart(3)
|
||||||
|
const perc = (Math.floor(step.relative * 1_000) / 10).toString().padStart(5)
|
||||||
|
log("progress", `${secs} s / ${total} s (${perc} %)\x1bM`)
|
||||||
}
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
|
return stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Stop = { stop: boolean }
|
||||||
|
|
||||||
interface ShutdownStrategy {
|
interface ShutdownStrategy {
|
||||||
/** Returns wether the child has been shutdown. */
|
/** Returns wether the child has been shutdown. */
|
||||||
|
@ -173,6 +198,18 @@ function try_signal(pid: number, sig: Deno.Signal) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function* progress(time_ms: number, step_ms = 100) {
|
||||||
|
const start = Date.now()
|
||||||
|
yield { ms: 0., relative: 0. }
|
||||||
|
while (true) {
|
||||||
|
const ellapsed = Date.now() - start
|
||||||
|
if (ellapsed > time_ms) break
|
||||||
|
yield { ms: ellapsed, relative: ellapsed / time_ms }
|
||||||
|
await wait(step_ms)
|
||||||
|
}
|
||||||
|
yield { ms: time_ms, relative: 1. }
|
||||||
|
}
|
||||||
|
|
||||||
// deno-lint-ignore no-explicit-any
|
// deno-lint-ignore no-explicit-any
|
||||||
type Catching<C extends Constructible<C, any>, R = void> = [
|
type Catching<C extends Constructible<C, any>, R = void> = [
|
||||||
exception: C,
|
exception: C,
|
||||||
|
@ -199,7 +236,7 @@ function log(verb: string, value: unknown) {
|
||||||
const bold = "\x1b[1m"
|
const bold = "\x1b[1m"
|
||||||
const reset = "\x1b[0m"
|
const reset = "\x1b[0m"
|
||||||
console.log(
|
console.log(
|
||||||
`` +
|
`\x1b[2K` +
|
||||||
`${yellow}${bold}${verb.padStart(12)}${reset}` +
|
`${yellow}${bold}${verb.padStart(12)}${reset}` +
|
||||||
` ` +
|
` ` +
|
||||||
`${yellow}${value}${reset}`,
|
`${yellow}${value}${reset}`,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue