Skip to content

Commit

Permalink
feat #266: Start disabled processes if specified explicitly
Browse files Browse the repository at this point in the history
  • Loading branch information
F1bonacc1 committed Nov 9, 2024
1 parent aba328e commit b34afe4
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 36 deletions.
13 changes: 13 additions & 0 deletions process-compose.override.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,16 @@ processes:
description: "disable elevation cache"
command: "sudo -k"

disabled:
description: "disabled process"
command: "echo I\\'m disabled"
disabled: true
depends_on:
disabled_dependency:
condition: process_completed

disabled_dependency:
description: "disabled dependency process"
command: "echo I\\'m disabled dependency"
disabled: true

21 changes: 13 additions & 8 deletions src/app/project_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ func (p *ProjectRunner) GetLexicographicProcessNames() ([]string, error) {
return p.project.GetLexicographicProcessNames()
}

func (p *ProjectRunner) WithProcesses(names []string, fn func(process types.ProcessConfig) error) error {
return p.project.WithProcesses(names, fn)
}

func (p *ProjectRunner) init() {
p.initProcessStates()
p.initProcessLogs()
Expand All @@ -68,6 +64,9 @@ func (p *ProjectRunner) Run() error {
p.runProcMutex.Unlock()
runOrder := []types.ProcessConfig{}
err := p.project.WithProcesses([]string{}, func(process types.ProcessConfig) error {
if process.IsDeferred() {
return nil
}
runOrder = append(runOrder, process)
return nil
})
Expand Down Expand Up @@ -751,7 +750,7 @@ func (p *ProjectRunner) addProcessAndRun(proc types.ProcessConfig) {
p.statesMutex.Unlock()
p.project.Processes[proc.ReplicaName] = proc
p.initProcessLog(proc.ReplicaName)
if !proc.Disabled {
if !proc.IsDeferred() {
p.runProcess(&proc)
}
}
Expand All @@ -762,6 +761,9 @@ func (p *ProjectRunner) selectRunningProcesses(procList []string) error {
}
newProcMap := types.Processes{}
err := p.project.WithProcesses(procList, func(process types.ProcessConfig) error {
if process.IsForeground {
return nil
}
newProcMap[process.ReplicaName] = process
return nil
})
Expand All @@ -772,8 +774,10 @@ func (p *ProjectRunner) selectRunningProcesses(procList []string) error {
for name, proc := range p.project.Processes {
if _, ok := newProcMap[name]; !ok {
proc.Disabled = true
p.project.Processes[name] = proc
} else {
proc.Disabled = false
}
p.project.Processes[name] = proc
}
return nil
}
Expand All @@ -792,11 +796,11 @@ func (p *ProjectRunner) selectRunningProcessesNoDeps(procList []string) error {
}
if !found {
proc.Disabled = true
p.project.Processes[name] = proc
} else {
proc.DependsOn = types.DependsOnConfig{}
p.project.Processes[name] = proc
proc.Disabled = false
}
p.project.Processes[name] = proc
}

return nil
Expand All @@ -806,6 +810,7 @@ func (p *ProjectRunner) GetLogLength() int {
return p.project.LogLength
}

// GetDependenciesOrderNames used for testing
func (p *ProjectRunner) GetDependenciesOrderNames() ([]string, error) {
return p.project.GetDependenciesOrderNames()
}
Expand Down
1 change: 0 additions & 1 deletion src/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ func Load(opts *LoaderOptions) (*types.Project, error) {
validateProcessConfig,
validateNoCircularDependencies,
validateShellConfig,
validateDependenciesExist,
validatePlatformCompatibility,
validateHealthDependencyHasHealthCheck,
validateDependencyIsEnabled,
Expand Down
20 changes: 2 additions & 18 deletions src/loader/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,6 @@ func validatePlatformCompatibility(p *types.Project) error {
return nil
}

func validateDependenciesExist(p *types.Project) error {
for process, config := range p.Processes {
for dependency := range config.DependsOn {
_, exists := p.Processes[dependency]
if !exists {
return fmt.Errorf("dependency process '%s' in process '%s' is not defined", dependency, process)
}
}
}
return nil
}

func validateNoCircularDependencies(p *types.Project) error {
visited := make(map[string]bool, len(p.Processes))
stack := make(map[string]bool)
Expand Down Expand Up @@ -166,13 +154,9 @@ func validateDependencyIsEnabled(p *types.Project) error {
depProc, ok := p.Processes[depName]
if !ok {
errStr := fmt.Sprintf("dependency process '%s' in process '%s' is not defined", depName, procName)
if p.IsStrict {
return errors.New(errStr)
}
log.Error().Msg(errStr)
continue
return errors.New(errStr)
}
if depProc.Disabled {
if depProc.Disabled && !proc.Disabled {
errStr := fmt.Sprintf("dependency process '%s' in process '%s' is disabled", depName, procName)
if p.IsStrict {
return errors.New(errStr)
Expand Down
12 changes: 3 additions & 9 deletions src/types/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ func (p *Project) WithProcesses(names []string, fn ProcessFunc) error {
func (p *Project) GetDependenciesOrderNames() ([]string, error) {
order := []string{}
err := p.WithProcesses([]string{}, func(process ProcessConfig) error {
if process.IsDeferred() {
return nil
}
order = append(order, process.ReplicaName)
return nil
})
Expand All @@ -57,27 +60,18 @@ func (p *Project) GetProcesses(names ...string) ([]ProcessConfig, error) {
processes := []ProcessConfig{}
if len(names) == 0 {
for _, proc := range p.Processes {
if proc.IsDeferred() {
continue
}
processes = append(processes, proc)
}
return processes, nil
}
for _, name := range names {
if proc, ok := p.Processes[name]; ok {
if proc.IsDeferred() {
continue
}
processes = append(processes, proc)
} else {
found := false
for _, process := range p.Processes {
if process.Name == name {
found = true
if process.IsDeferred() {
continue
}
processes = append(processes, process)
}
}
Expand Down
183 changes: 183 additions & 0 deletions src/types/project_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
package types

import (
"github.com/f1bonacc1/process-compose/src/command"
"slices"
"testing"
)

func TestProject_WithProcesses(t *testing.T) {
type fields struct {
Version string
LogLocation string
LogLevel string
LogLength int
LoggerConfig *LoggerConfig
LogFormat string
Processes Processes
Environment Environment
ShellConfig *command.ShellConfig
IsStrict bool
Vars Vars
DisableEnvExpansion bool
IsTuiDisabled bool
ExtendsProject string
FileNames []string
EnvFileNames []string
}
type args struct {
names []string
fn ProcessFunc
}
order := []string{}
tests := []struct {
name string
fields fields
args args
wantErr bool
wantOrder []string
}{
{
name: "ShouldBeOk",
fields: fields{
Processes: map[string]ProcessConfig{
"Process1": {
Name: "Process1",
ReplicaName: "Process1",
},
"Process2": {
Name: "Process2",
ReplicaName: "Process2",
},
},
},
args: args{
names: []string{"Process1", "Process2"},
fn: func(proc ProcessConfig) error {
order = append(order, proc.Name)
return nil
},
},
wantErr: false,
wantOrder: []string{
"Process1",
"Process2",
},
},
{
name: "ShouldBeError",
fields: fields{
Processes: map[string]ProcessConfig{
"Process1": {
Name: "Process1",
ReplicaName: "Process1",
},
"Process2": {
Name: "Process2",
ReplicaName: "Process2",
},
},
},
args: args{
names: []string{"Process1", "Process3"},
fn: func(proc ProcessConfig) error {
order = append(order, proc.Name)
return nil
},
},
wantErr: true,
},
{
name: "ShouldBeOnlyOne",
fields: fields{
Processes: map[string]ProcessConfig{
"Process1": {
Name: "Process1",
ReplicaName: "Process1",
},
"Process2": {
Name: "Process2",
ReplicaName: "Process2",
},
},
},
args: args{
names: []string{"Process1"},
fn: func(proc ProcessConfig) error {
order = append(order, proc.Name)
return nil
},
},
wantErr: false,
wantOrder: []string{
"Process1",
},
},
{
name: "ShouldBeAllNoNames",
fields: fields{
Processes: map[string]ProcessConfig{
"Process1": {
Name: "Process1",
ReplicaName: "Process1",
},
"Process2": {
Name: "Process2",
ReplicaName: "Process2",
},
},
},
args: args{
names: []string{},
fn: func(proc ProcessConfig) error {
order = append(order, proc.Name)
return nil
},
},
wantErr: false,
wantOrder: []string{
"Process1",
"Process2",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
order = []string{}
p := &Project{
Version: tt.fields.Version,
LogLocation: tt.fields.LogLocation,
LogLevel: tt.fields.LogLevel,
LogLength: tt.fields.LogLength,
LoggerConfig: tt.fields.LoggerConfig,
LogFormat: tt.fields.LogFormat,
Processes: tt.fields.Processes,
Environment: tt.fields.Environment,
ShellConfig: tt.fields.ShellConfig,
IsStrict: tt.fields.IsStrict,
Vars: tt.fields.Vars,
DisableEnvExpansion: tt.fields.DisableEnvExpansion,
IsTuiDisabled: tt.fields.IsTuiDisabled,
ExtendsProject: tt.fields.ExtendsProject,
FileNames: tt.fields.FileNames,
EnvFileNames: tt.fields.EnvFileNames,
}
if err := p.WithProcesses(tt.args.names, tt.args.fn); (err != nil) != tt.wantErr {
t.Errorf("WithProcesses() error = %v, wantErr %v", err, tt.wantErr)
}
if tt.wantErr {
return
}

if len(order) != len(tt.wantOrder) {
t.Errorf("WithProcesses() order = %v, wantOrder %v", order, tt.wantOrder)
}

for _, name := range tt.wantOrder {
if !slices.Contains(order, name) {
t.Errorf("WithProcesses() order = %v, wantOrder %v", order, tt.wantOrder)
}
}
})
}
}

0 comments on commit b34afe4

Please sign in to comment.