Skip to content

Commit

Permalink
Add support for foreground processes
Browse files Browse the repository at this point in the history
  • Loading branch information
F1bonacc1 committed Dec 8, 2023
1 parent f058176 commit 50b4a72
Show file tree
Hide file tree
Showing 11 changed files with 268 additions and 52 deletions.
10 changes: 3 additions & 7 deletions process-compose.override.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ processes:
liveness_probe:
exec:
command: '[ $(docker inspect -f {{ "{{.State.Running}}" }} nginx_test) = true ]'
# command: '[ $(docker inspect -f "{{.State.Running}}" nginx_test) = true ]'
initial_delay_seconds: 5
period_seconds: 2
timeout_seconds: 5
Expand Down Expand Up @@ -161,7 +160,6 @@ processes:

entrypoint:
description: "run process with entrypoint and no command"
command: "echo you should not see ls"
entrypoint:
- ls
- -lFa
Expand All @@ -170,8 +168,6 @@ processes:
- /

vim:
description: "run process with entrypoint and no command"
command: "vim"
# entrypoint:
# - vim
disabled: true
description: "run a foreground process"
command: "vim process-compose.override.yaml"
is_foreground: true
41 changes: 41 additions & 0 deletions src/app/project_opts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package app

import "github.com/f1bonacc1/process-compose/src/types"

type ProjectOpts struct {
project *types.Project
processesToRun []string
noDeps bool
mainProcess string
mainProcessArgs []string
isTuiOn bool
}

func (p *ProjectOpts) WithProject(project *types.Project) *ProjectOpts {
p.project = project
return p
}

func (p *ProjectOpts) WithProcessesToRun(processesToRun []string) *ProjectOpts {
p.processesToRun = processesToRun
return p
}
func (p *ProjectOpts) WithNoDeps(noDeps bool) *ProjectOpts {
p.noDeps = noDeps
return p
}

func (p *ProjectOpts) WithMainProcess(mainProcess string) *ProjectOpts {
p.mainProcess = mainProcess
return p
}

func (p *ProjectOpts) WithMainProcessArgs(mainProcessArgs []string) *ProjectOpts {
p.mainProcessArgs = mainProcessArgs
return p
}

func (p *ProjectOpts) WithIsTuiOn(isTuiOn bool) *ProjectOpts {
p.isTuiOn = isTuiOn
return p
}
27 changes: 12 additions & 15 deletions src/app/project_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type ProjectRunner struct {
projectState *types.ProjectState
mainProcess string
mainProcessArgs []string
isTuiOn bool
}

func (p *ProjectRunner) GetLexicographicProcessNames() ([]string, error) {
Expand Down Expand Up @@ -89,7 +90,7 @@ func (p *ProjectRunner) runProcess(config *types.ProcessConfig) {
procState, _ := p.GetProcessState(config.ReplicaName)
isMain := config.Name == p.mainProcess
hasMain := p.mainProcess != ""
printLogs := !hasMain
printLogs := !hasMain && !p.isTuiOn
extraArgs := []string{}
if isMain {
extraArgs = p.mainProcessArgs
Expand Down Expand Up @@ -599,13 +600,6 @@ func (p *ProjectRunner) GetProjectState(checkMem bool) (*types.ProjectState, err
return p.projectState, nil
}

func NewProjectRunner(
project *types.Project,
processesToRun []string,
noDeps bool,
mainProcess string,
mainProcessArgs []string,
) (*ProjectRunner, error) {
func getMemoryUsage() *types.MemoryState {
var m runtime.MemStats
runtime.ReadMemStats(&m)
Expand All @@ -622,6 +616,8 @@ func bToMb(b uint64) uint64 {
return b / 1024 / 1024
}

func NewProjectRunner(opts *ProjectOpts) (*ProjectRunner, error) {

hostname, err := os.Hostname()
if err != nil {
log.Err(err).Msg("Failed get hostname")
Expand All @@ -635,22 +631,23 @@ func bToMb(b uint64) uint64 {
username = current.Username
}
runner := &ProjectRunner{
project: project,
mainProcess: mainProcess,
mainProcessArgs: mainProcessArgs,
project: opts.project,
mainProcess: opts.mainProcess,
mainProcessArgs: opts.mainProcessArgs,
isTuiOn: opts.isTuiOn,
projectState: &types.ProjectState{
FileNames: project.FileNames,
FileNames: opts.project.FileNames,
StartTime: time.Now(),
UserName: username,
HostName: hostname,
Version: config.Version,
},
}

if noDeps {
err = runner.selectRunningProcessesNoDeps(processesToRun)
if opts.noDeps {
err = runner.selectRunningProcessesNoDeps(opts.processesToRun)
} else {
err = runner.selectRunningProcesses(processesToRun)
err = runner.selectRunningProcesses(opts.processesToRun)
}
if err != nil {
return nil, err
Expand Down
33 changes: 28 additions & 5 deletions src/app/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@ func TestSystem_TestFixtures(t *testing.T) {
t.Errorf(err.Error())
return
}
runner, err := NewProjectRunner(project, []string{}, false, "", []string{})
runner, err := NewProjectRunner(&ProjectOpts{
project: project,
processesToRun: []string{},
noDeps: false,
mainProcess: "",
mainProcessArgs: []string{},
isTuiOn: false,
})
if err != nil {
t.Errorf(err.Error())
return
Expand All @@ -48,7 +55,11 @@ func TestSystem_TestComposeWithLog(t *testing.T) {
t.Errorf(err.Error())
return
}
runner, err := NewProjectRunner(project, []string{}, false, "", []string{})
runner, err := NewProjectRunner(&ProjectOpts{
project: project,
processesToRun: []string{},
mainProcessArgs: []string{},
})
if err != nil {
t.Errorf(err.Error())
return
Expand Down Expand Up @@ -81,7 +92,11 @@ func TestSystem_TestComposeChain(t *testing.T) {
t.Errorf(err.Error())
return
}
runner, err := NewProjectRunner(project, []string{}, false, "", []string{})
runner, err := NewProjectRunner(&ProjectOpts{
project: project,
processesToRun: []string{},
mainProcessArgs: []string{},
})
if err != nil {
t.Errorf(err.Error())
return
Expand Down Expand Up @@ -117,7 +132,11 @@ func TestSystem_TestComposeChainExit(t *testing.T) {
t.Errorf(err.Error())
return
}
runner, err := NewProjectRunner(project, []string{}, false, "", []string{})
runner, err := NewProjectRunner(&ProjectOpts{
project: project,
processesToRun: []string{},
mainProcessArgs: []string{},
})
if err != nil {
t.Errorf(err.Error())
return
Expand Down Expand Up @@ -162,7 +181,11 @@ func TestSystem_TestComposeScale(t *testing.T) {
t.Errorf(err.Error())
return
}
runner, err := NewProjectRunner(project, []string{}, false, "", []string{})
runner, err := NewProjectRunner(&ProjectOpts{
project: project,
processesToRun: []string{},
mainProcessArgs: []string{},
})
if err != nil {
t.Errorf(err.Error())
return
Expand Down
17 changes: 13 additions & 4 deletions src/cmd/project_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,16 @@ func getProjectRunner(process []string, noDeps bool, mainProcess string, mainPro
log.Fatal().Msg(err.Error())
}

runner, err := app.NewProjectRunner(project, process, noDeps, mainProcess, mainProcessArgs)
prjOpts := app.ProjectOpts{}

runner, err := app.NewProjectRunner(
prjOpts.WithIsTuiOn(*pcFlags.Headless).
WithMainProcess(mainProcess).
WithMainProcessArgs(mainProcessArgs).
WithProject(project).
WithProcessesToRun(process).
WithNoDeps(noDeps),
)
if err != nil {
fmt.Println(err)
log.Fatal().Msg(err.Error())
Expand Down Expand Up @@ -63,10 +72,10 @@ func runHeadless(project *app.ProjectRunner) int {
}

func runTui(project *app.ProjectRunner) int {
setSignal(func() {
/*setSignal(func() {
tui.Stop()
})
defer quiet()()
})*/
//defer quiet()()
go startTui(project)
exitCode := project.Run()
tui.Stop()
Expand Down
31 changes: 23 additions & 8 deletions src/tui/log-operations.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tui

import (
"context"
"fmt"
"github.com/f1bonacc1/glippy"
"github.com/gdamore/tcell/v2"
Expand Down Expand Up @@ -37,12 +38,18 @@ func (pv *pcView) startFollowLog(name string) {
pv.exitSearch()
pv.logFollow = true
pv.followLog(name)
go pv.updateLogs()
var ctx context.Context
ctx, pv.cancelLogFn = context.WithCancel(context.Background())
go pv.updateLogs(ctx)
pv.updateHelpTextView()
}

func (pv *pcView) stopFollowLog() {
pv.logFollow = false
if pv.cancelLogFn != nil {
pv.cancelLogFn()
pv.cancelLogFn = nil
}
pv.unFollowLog()
pv.updateHelpTextView()
}
Expand Down Expand Up @@ -70,15 +77,23 @@ func (pv *pcView) unFollowLog() {
pv.logsText.Flush()
}

func (pv *pcView) updateLogs() {
func (pv *pcView) updateLogs(ctx context.Context) {
pv.appView.QueueUpdateDraw(func() {
pv.logsText.Flush()
})
for {
pv.appView.QueueUpdateDraw(func() {
pv.logsText.Flush()
})
if !pv.logFollow {
break
select {
case <-ctx.Done():
log.Debug().Msg("Logs monitoring canceled")
return
case <-time.After(300 * time.Millisecond):
pv.appView.QueueUpdateDraw(func() {
pv.logsText.Flush()
})
//if !pv.logFollow {
// return
//}
}
time.Sleep(300 * time.Millisecond)
}
}

Expand Down
71 changes: 71 additions & 0 deletions src/tui/proc-starter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package tui

import (
"context"
"fmt"
"github.com/f1bonacc1/process-compose/src/types"
"github.com/rs/zerolog/log"
"os"
"os/exec"
"os/signal"
"syscall"
)

func (pv *pcView) startProcess() {
name := pv.getSelectedProcName()
info, err := pv.project.GetProcessInfo(name)
if err != nil {
pv.showError(err.Error())
return
}
if info.IsForeground {
pv.runForeground(info)
return
}
err = pv.project.StartProcess(name)
if err != nil {
pv.showError(err.Error())
}
}

func (pv *pcView) runForeground(info *types.ProcessConfig) bool {
pv.halt()
defer pv.resume()
return pv.appView.Suspend(func() {
err := pv.execute(info)
if err != nil {
log.Err(err).Msgf("Command failed")
}
})
}

func (pv *pcView) execute(info *types.ProcessConfig) error {
ctx, cancel := context.WithCancel(context.Background())
defer func() {
cancel()
clearScreen()
}()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
go func(cancel context.CancelFunc) {
select {
case sig := <-sigChan:
log.Debug().Msgf("Command canceled with signal %#v", sig)
cancel()
case <-ctx.Done():
log.Debug().Msgf("Foreground process context canceled")
}
}(cancel)

cmd := exec.CommandContext(ctx, info.Executable, info.Args...)
log.Debug().Str("exec", info.Executable).Strs("args", info.Args).Msg("running start")
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
err := cmd.Run()
log.Debug().Str("exec", info.Executable).Strs("args", info.Args).Msg("running end")

return err
}

func clearScreen() {
fmt.Print("\033[H\033[2J")
}
Loading

0 comments on commit 50b4a72

Please sign in to comment.