Skip to content

Commit

Permalink
Merge branch 'run-cmd'
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/app/project_runner.go
#	src/tui/proc-info-form.go
#	src/types/validators.go
  • Loading branch information
F1bonacc1 committed Nov 18, 2023
2 parents 84b141d + d787b8b commit 48e7711
Show file tree
Hide file tree
Showing 14 changed files with 153 additions and 30 deletions.
11 changes: 8 additions & 3 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,19 @@
commit = self.shortRev or "dirty";
};
in
(flake-utils.lib.eachDefaultSystem (system:
{
packages.process-compose = mkPackage nixpkgs.legacyPackages.${system};
(flake-utils.lib.eachDefaultSystem (system: let
pkgs = nixpkgs.legacyPackages.${system};
in {
packages.process-compose = mkPackage pkgs;
defaultPackage = self.packages."${system}".process-compose;
apps.process-compose = flake-utils.lib.mkApp {
drv = self.packages."${system}".process-compose;
};
apps.default = self.apps."${system}".process-compose;
checks.default = self.packages."${system}".process-compose.overrideAttrs (prev: {
doCheck = true;
nativeBuildInputs = prev.nativeBuildInputs ++ (with pkgs; [python3]);
});
})
) // {
overlays.default = final: prev: {
Expand Down
1 change: 1 addition & 0 deletions src/app/commander_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ type Commander interface {
StderrPipe() (io.ReadCloser, error)
Stop(int, bool) error
SetCmdArgs()
AttachIo()
}
51 changes: 37 additions & 14 deletions src/app/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ type Process struct {
liveProber *health.Prober
readyProber *health.Prober
shellConfig command.ShellConfig
printLogs bool
isMain bool
extraArgs []string
}

func NewProcess(
Expand All @@ -62,6 +65,9 @@ func NewProcess(
processState *types.ProcessState,
procLog *pclog.ProcessLogBuffer,
shellConfig command.ShellConfig,
printLogs bool,
isMain bool,
extraArgs []string,
) *Process {
colNumeric := rand.Intn(int(color.FgHiWhite)-int(color.FgHiBlack)) + int(color.FgHiBlack)

Expand All @@ -78,6 +84,9 @@ func NewProcess(
shellConfig: shellConfig,
procStateChan: make(chan string, 1),
procReadyChan: make(chan string, 1),
printLogs: printLogs,
isMain: isMain,
extraArgs: extraArgs,
}

proc.procReadyCtx, proc.readyCancelFn = context.WithCancel(context.Background())
Expand All @@ -92,7 +101,7 @@ func (p *Process) run() int {
}

if err := p.validateProcess(); err != nil {
log.Error().Err(err).Msgf("Failed to run command %s for process %s", p.getCommand(), p.getName())
log.Error().Err(err).Msgf(`Failed to run command ["%v"] for process %s`, strings.Join(p.getCommand(), `" "`), p.getName())
p.onProcessEnd(types.ProcessStateError)
return 1
}
Expand All @@ -101,7 +110,7 @@ func (p *Process) run() int {
for {
err := p.setStateAndRun(p.getStartingStateName(), p.getProcessStarter())
if err != nil {
log.Error().Err(err).Msgf("Failed to run command %s for process %s", p.getCommand(), p.getName())
log.Error().Err(err).Msgf(`Failed to run command ["%v"] for process %s`, strings.Join(p.getCommand(), `" "`), p.getName())
p.logBuffer.Write(err.Error())
p.onProcessEnd(types.ProcessStateError)
return 1
Expand Down Expand Up @@ -151,16 +160,23 @@ func (p *Process) run() int {

func (p *Process) getProcessStarter() func() error {
return func() error {
p.command = command.BuildCommandShellArg(p.shellConfig, p.getCommand())
p.command = command.BuildCommand(
p.procConf.Executable,
append(p.procConf.Args, p.extraArgs...),
)
p.command.SetEnv(p.getProcessEnvironment())
p.command.SetDir(p.procConf.WorkingDir)
p.command.SetCmdArgs()
stdout, _ := p.command.StdoutPipe()
stderr, _ := p.command.StderrPipe()
go p.handleOutput(stdout, p.handleInfo)
go p.handleOutput(stderr, p.handleError)
//stdin, _ := p.command.StdinPipe()
//go p.handleInput(stdin)

if p.isMain {
p.command.AttachIo()
} else {
p.command.SetCmdArgs()
stdout, _ := p.command.StdoutPipe()
stderr, _ := p.command.StderrPipe()
go p.handleOutput(stdout, p.handleInfo)
go p.handleOutput(stderr, p.handleError)
}

return p.command.Start()
}
}
Expand Down Expand Up @@ -346,8 +362,11 @@ func (p *Process) getNameWithSmartReplica() string {
return p.procConf.Name
}

func (p *Process) getCommand() string {
return p.procConf.Command
func (p *Process) getCommand() []string {
return append(
[]string{(*p.procConf).Executable},
append(p.procConf.Args, p.extraArgs...)...,
)
}

func (p *Process) updateProcState() {
Expand Down Expand Up @@ -401,13 +420,17 @@ func (p *Process) handleOutput(pipe io.ReadCloser, handler func(message string))

func (p *Process) handleInfo(message string) {
p.logger.Info(message, p.getName(), p.procConf.ReplicaNum)
fmt.Printf("[%s\t] %s\n", p.procColor(p.getName()), message)
if p.printLogs {
fmt.Printf("[%s\t] %s\n", p.procColor(p.getName()), message)
}
p.logBuffer.Write(message)
}

func (p *Process) handleError(message string) {
p.logger.Error(message, p.getName(), p.procConf.ReplicaNum)
fmt.Printf("[%s\t] %s\n", p.procColor(p.getName()), p.redColor(message))
if p.printLogs {
fmt.Printf("[%s\t] %s\n", p.procColor(p.getName()), p.redColor(message))
}
p.logBuffer.Write(message)
}

Expand Down
32 changes: 30 additions & 2 deletions src/app/project_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type ProjectRunner struct {
waitGroup sync.WaitGroup
exitCode int
projectState *types.ProjectState
mainProcess string
mainProcessArgs []string
}

func (p *ProjectRunner) GetLexicographicProcessNames() ([]string, error) {
Expand Down Expand Up @@ -84,7 +86,25 @@ func (p *ProjectRunner) runProcess(config *types.ProcessConfig) {
procLog = pclog.NewLogBuffer(0)
}
procState, _ := p.GetProcessState(config.ReplicaName)
process := NewProcess(p.project.Environment, procLogger, config, procState, procLog, *p.project.ShellConfig)
isMain := config.Name == p.mainProcess
hasMain := p.mainProcess != ""
printLogs := !hasMain
extraArgs := []string{}
if isMain {
extraArgs = p.mainProcessArgs
config.RestartPolicy.ExitOnEnd = true
}
process := NewProcess(
p.project.Environment,
procLogger,
config,
procState,
procLog,
*p.project.ShellConfig,
printLogs,
isMain,
extraArgs,
)
p.addRunningProcess(process)
p.waitGroup.Add(1)
go func() {
Expand Down Expand Up @@ -574,7 +594,13 @@ func (p *ProjectRunner) GetProjectState() (*types.ProjectState, error) {
return p.projectState, nil
}

func NewProjectRunner(project *types.Project, processesToRun []string, noDeps bool) (*ProjectRunner, error) {
func NewProjectRunner(
project *types.Project,
processesToRun []string,
noDeps bool,
mainProcess string,
mainProcessArgs []string,
) (*ProjectRunner, error) {

hostname, err := os.Hostname()
if err != nil {
Expand All @@ -590,6 +616,8 @@ func NewProjectRunner(project *types.Project, processesToRun []string, noDeps bo
}
runner := &ProjectRunner{
project: project,
mainProcess: mainProcess,
mainProcessArgs: mainProcessArgs,
projectState: &types.ProjectState{
FileNames: project.FileNames,
StartTime: time.Now(),
Expand Down
10 changes: 5 additions & 5 deletions src/app/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestSystem_TestFixtures(t *testing.T) {
t.Errorf(err.Error())
return
}
runner, err := NewProjectRunner(project, []string{}, false)
runner, err := NewProjectRunner(project, []string{}, false, "", []string{})
if err != nil {
t.Errorf(err.Error())
return
Expand All @@ -48,7 +48,7 @@ func TestSystem_TestComposeWithLog(t *testing.T) {
t.Errorf(err.Error())
return
}
runner, err := NewProjectRunner(project, []string{}, false)
runner, err := NewProjectRunner(project, []string{}, false, "", []string{})
if err != nil {
t.Errorf(err.Error())
return
Expand Down Expand Up @@ -81,7 +81,7 @@ func TestSystem_TestComposeChain(t *testing.T) {
t.Errorf(err.Error())
return
}
runner, err := NewProjectRunner(project, []string{}, false)
runner, err := NewProjectRunner(project, []string{}, false, "", []string{})
if err != nil {
t.Errorf(err.Error())
return
Expand Down Expand Up @@ -117,7 +117,7 @@ func TestSystem_TestComposeChainExit(t *testing.T) {
t.Errorf(err.Error())
return
}
runner, err := NewProjectRunner(project, []string{}, false)
runner, err := NewProjectRunner(project, []string{}, false, "", []string{})
if err != nil {
t.Errorf(err.Error())
return
Expand Down Expand Up @@ -162,7 +162,7 @@ func TestSystem_TestComposeScale(t *testing.T) {
t.Errorf(err.Error())
return
}
runner, err := NewProjectRunner(project, []string{}, false)
runner, err := NewProjectRunner(project, []string{}, false, "", []string{})
if err != nil {
t.Errorf(err.Error())
return
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/project_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"time"
)

func getProjectRunner(process []string, noDeps bool) *app.ProjectRunner {
func getProjectRunner(process []string, noDeps bool, mainProcess string, mainProcessArgs []string) *app.ProjectRunner {
if *pcFlags.HideDisabled {
opts.AddAdmitter(&admitter.DisabledProcAdmitter{})
}
Expand All @@ -23,7 +23,7 @@ func getProjectRunner(process []string, noDeps bool) *app.ProjectRunner {
log.Fatal().Msg(err.Error())
}

runner, err := app.NewProjectRunner(project, process, noDeps)
runner, err := app.NewProjectRunner(project, process, noDeps, mainProcess, mainProcessArgs)
if err != nil {
fmt.Println(err)
log.Fatal().Msg(err.Error())
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func run(cmd *cobra.Command, args []string) error {
defer func() {
_ = logFile.Close()
}()
runner := getProjectRunner([]string{}, false)
runner := getProjectRunner([]string{}, false, "", []string{})
api.StartHttpServer(!*pcFlags.Headless, *pcFlags.PortNum, runner)
runProject(runner)
return nil
Expand Down
54 changes: 54 additions & 0 deletions src/cmd/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package cmd

import (
"fmt"
"os"
"github.com/f1bonacc1/process-compose/src/api"
"github.com/spf13/cobra"
)

// runCmd represents the up command
var runCmd = &cobra.Command{
Use: "run PROCESS [flags] -- [process_args]",
Short: "Run PROCESS in the foreground, and its dependencies in the background",
Long: `Run selected process with std(in|out|err) attached, while other processes run in the background.
Command line arguments, provided after --, are passed to the PROCESS.`,
Args: cobra.MinimumNArgs(1),
// Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
*pcFlags.Headless = false

processName := args[0]

if len(args) > 1 {
argsLenAtDash := cmd.ArgsLenAtDash()
if argsLenAtDash != 1 {
message := "Extra positional arguments provided! To pass args to PROCESS, separate them from process-compose arguments with: --"
fmt.Println(message)
os.Exit(1)
}
args = args[argsLenAtDash:]
} else {
// Clease args as they will contain the processName
args = []string{}
}

runner := getProjectRunner(
[]string{processName},
*pcFlags.NoDependencies,
processName,
args,
)

api.StartHttpServer(false, *pcFlags.PortNum, runner)
runProject(runner)
},
}

func init() {
rootCmd.AddCommand(runCmd)

runCmd.Flags().BoolVarP(pcFlags.NoDependencies, "no-deps", "", *pcFlags.NoDependencies, "don't start dependent processes")
runCmd.Flags().AddFlag(rootCmd.Flags().Lookup("config"))

}
2 changes: 1 addition & 1 deletion src/cmd/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var upCmd = &cobra.Command{
If one or more process names are passed as arguments,
will start them and their dependencies only`,
Run: func(cmd *cobra.Command, args []string) {
runner := getProjectRunner(args, *pcFlags.NoDependencies)
runner := getProjectRunner(args, *pcFlags.NoDependencies, "", []string{})
api.StartHttpServer(!*pcFlags.Headless, *pcFlags.PortNum, runner)
runProject(runner)
},
Expand Down
5 changes: 3 additions & 2 deletions src/command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import (
"runtime"
)

func BuildCommandShellArg(shell ShellConfig, cmd string) *CmdWrapper {

func BuildCommand(cmd string, args []string) *CmdWrapper {
return &CmdWrapper{
cmd: exec.Command(shell.ShellCommand, shell.ShellArgument, cmd),
cmd: exec.Command(cmd, args...),
}
//return NewMockCommand()
}
Expand Down
7 changes: 7 additions & 0 deletions src/command/command_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package command

import (
"io"
"os"
"os/exec"
)

Expand Down Expand Up @@ -37,6 +38,12 @@ func (c *CmdWrapper) StderrPipe() (io.ReadCloser, error) {
return c.cmd.StderrPipe()
}

func (c *CmdWrapper) AttachIo() () {
c.cmd.Stdin = os.Stdin
c.cmd.Stdout = os.Stdout
c.cmd.Stderr = os.Stderr
}

func (c *CmdWrapper) SetEnv(env []string) {
c.cmd.Env = env
}
Expand Down
1 change: 1 addition & 0 deletions src/tui/proc-info-form.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func (pv *pcView) createProcInfoForm(info *types.ProcessConfig, ports *types.Pro
f.SetButtonsAlign(tview.AlignCenter)
f.SetTitle("Process " + info.Name + " Info")
addStringIfNotEmpty("Description:", info.Description, f)
addStringIfNotEmpty("Entrypoint:", strings.Join(info.Entrypoint, " "), f)
addStringIfNotEmpty("Command:", info.Command, f)
addStringIfNotEmpty("Working Directory:", info.WorkingDir, f)
addStringIfNotEmpty("Log Location:", info.LogLocation, f)
Expand Down
3 changes: 3 additions & 0 deletions src/types/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type ProcessConfig struct {
Disabled bool `yaml:"disabled,omitempty"`
IsDaemon bool `yaml:"is_daemon,omitempty"`
Command string `yaml:"command"`
Entrypoint []string `yaml:"entrypoint"`
LogLocation string `yaml:"log_location,omitempty"`
LoggerConfig *LoggerConfig `yaml:"log_configuration,omitempty"`
Environment Environment `yaml:"environment,omitempty"`
Expand All @@ -33,6 +34,8 @@ type ProcessConfig struct {
Vars Vars `yaml:"vars"`
ReplicaNum int
ReplicaName string
Executable string
Args []string
}

func (p *ProcessConfig) GetDependencies() []string {
Expand Down
Empty file added src/types/validators.go
Empty file.

0 comments on commit 48e7711

Please sign in to comment.