From 2fe888e1864a7bf3762a89be040297b61edfae4a Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sun, 20 Mar 2022 19:10:12 -0400 Subject: [PATCH] feat: add hilbish.jobs interface and add stop function to job in hooks (closes #109) --- api.go | 5 +++++ exec.go | 1 + job.go | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/api.go b/api.go index f3aead2..2cfff99 100644 --- a/api.go +++ b/api.go @@ -107,11 +107,16 @@ Check out the {blue}{bold}guide{reset} command to get started. util.Document(L, hshcomp, "Completions interface for Hilbish.") L.SetField(mod, "completion", hshcomp) + // hilbish.runner table runnerModule := runnerModeLoader(L) util.Document(L, runnerModule, "Runner/exec interface for Hilbish.") L.SetField(mod, "runner", runnerModule) + // hilbish.jobs table jobs = newJobHandler() + jobModule := jobs.loader(L) + util.Document(L, jobModule, "(Background) job interface.") + L.SetField(mod, "jobs", jobModule) L.Push(mod) diff --git a/exec.go b/exec.go index 0a0ab74..5e2c74e 100644 --- a/exec.go +++ b/exec.go @@ -262,6 +262,7 @@ func execCommand(cmd string) error { err = cmd.Start() job := jobs.getLatest() + job.setHandle(cmd.Process) if err == nil { if bg { job.start(cmd.Process.Pid) diff --git a/job.go b/job.go index 2764fc8..6ddaa96 100644 --- a/job.go +++ b/job.go @@ -2,6 +2,7 @@ package main import ( "sync" + "os" "github.com/yuin/gopher-lua" ) @@ -14,6 +15,7 @@ type job struct { id int pid int exitCode int + proc *os.Process } func (j *job) start(pid int) { @@ -22,15 +24,27 @@ func (j *job) start(pid int) { hooks.Em.Emit("job.start", j.lua()) } +func (j *job) stop() { + // finish will be called in exec handle + j.proc.Kill() +} + func (j *job) finish() { j.running = false hooks.Em.Emit("job.done", j.lua()) } +func (j *job) setHandle(handle *os.Process) { + j.proc = handle +} + func (j *job) lua() *lua.LTable { // returns lua table for job // because userdata is gross - luaJob := l.NewTable() + jobFuncs := map[string]lua.LGFunction{ + "stop": j.luaStop, + } + luaJob := l.SetFuncs(l.NewTable(), jobFuncs) l.SetField(luaJob, "cmd", lua.LString(j.cmd)) l.SetField(luaJob, "running", lua.LBool(j.running)) @@ -41,6 +55,14 @@ func (j *job) lua() *lua.LTable { return luaJob } +func (j *job) luaStop(L *lua.LState) int { + if j.running { + j.stop() + } + + return 0 +} + type jobHandler struct { jobs map[int]*job latestID int @@ -73,3 +95,42 @@ func (j *jobHandler) getLatest() *job { return j.jobs[j.latestID] } + + +func (j *jobHandler) loader(L *lua.LState) *lua.LTable { + jobFuncs := map[string]lua.LGFunction{ + "all": j.luaAllJobs, + "get": j.luaGetJob, + } + + luaJob := l.SetFuncs(l.NewTable(), jobFuncs) + + return luaJob +} + +func (j *jobHandler) luaGetJob(L *lua.LState) int { + j.mu.RLock() + defer j.mu.RUnlock() + + jobID := L.CheckInt(1) + job := j.jobs[jobID] + if job != nil { + return 0 + } + L.Push(job.lua()) + + return 1 +} + +func (j *jobHandler) luaAllJobs(L *lua.LState) int { + j.mu.RLock() + defer j.mu.RUnlock() + + jobTbl := L.NewTable() + for id, job := range j.jobs { + jobTbl.Insert(id, job.lua()) + } + + L.Push(jobTbl) + return 1 +}