Skip to content

Commit ebabc6f

Browse files
committed
introduce WithSelectedJob
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
1 parent f37d49c commit ebabc6f

2 files changed

Lines changed: 94 additions & 0 deletions

File tree

types/project.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,31 @@ func (p *Project) WithSelectedServices(names []string, options ...DependencyOpti
550550
return newProject, nil
551551
}
552552

553+
// WithSelectedJob returns a new Project containing only the services required
554+
// by the named job's DependsOn. The job itself is NOT added to Services.
555+
func (p *Project) WithSelectedJob(name string, options ...DependencyOption) (*Project, error) {
556+
job, ok := p.Jobs[name]
557+
if !ok {
558+
return nil, fmt.Errorf("no such job: %s", name)
559+
}
560+
561+
var deps []string
562+
for dep := range job.DependsOn {
563+
deps = append(deps, dep)
564+
}
565+
566+
if len(deps) == 0 {
567+
// Job has no service dependencies: return project with all services disabled
568+
newProject := p.deepCopy()
569+
for name := range newProject.Services {
570+
newProject = newProject.WithServicesDisabled(name)
571+
}
572+
return newProject, nil
573+
}
574+
575+
return p.WithSelectedServices(deps, options...)
576+
}
577+
553578
// WithServicesDisabled removes from the project model the given services and their references in all dependencies
554579
// It returns a new Project instance with the changes and keep the original Project unchanged
555580
func (p *Project) WithServicesDisabled(names ...string) *Project {

types/project_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,75 @@ func TestProject_WithServicesEnvironmentResolved(t *testing.T) {
522522
})
523523
}
524524

525+
func TestWithSelectedJob(t *testing.T) {
526+
project := &Project{
527+
Services: Services{
528+
"db": {
529+
Name: "db",
530+
ContainerSpec: ContainerSpec{
531+
Image: "postgres",
532+
},
533+
},
534+
"redis": {
535+
Name: "redis",
536+
ContainerSpec: ContainerSpec{
537+
Image: "redis",
538+
},
539+
},
540+
"web": {
541+
Name: "web",
542+
ContainerSpec: ContainerSpec{
543+
Image: "myapp",
544+
DependsOn: DependsOnConfig{
545+
"db": {Condition: "service_healthy"},
546+
},
547+
},
548+
},
549+
},
550+
Jobs: Jobs{
551+
"migrate": {
552+
Name: "migrate",
553+
ContainerSpec: ContainerSpec{
554+
Image: "myapp",
555+
Command: ShellCommand{"migrate"},
556+
DependsOn: DependsOnConfig{
557+
"db": {Condition: "service_healthy"},
558+
},
559+
},
560+
},
561+
"seed": {
562+
Name: "seed",
563+
ContainerSpec: ContainerSpec{
564+
Image: "myapp",
565+
},
566+
},
567+
},
568+
}
569+
570+
t.Run("job with dependencies includes only required services", func(t *testing.T) {
571+
result, err := project.WithSelectedJob("migrate")
572+
assert.NilError(t, err)
573+
assert.Equal(t, len(result.Services), 1)
574+
_, hasDB := result.Services["db"]
575+
assert.Assert(t, hasDB)
576+
_, hasRedis := result.Services["redis"]
577+
assert.Assert(t, !hasRedis)
578+
_, hasWeb := result.Services["web"]
579+
assert.Assert(t, !hasWeb)
580+
})
581+
582+
t.Run("job without dependencies returns empty services", func(t *testing.T) {
583+
result, err := project.WithSelectedJob("seed")
584+
assert.NilError(t, err)
585+
assert.Equal(t, len(result.Services), 0)
586+
})
587+
588+
t.Run("unknown job returns error", func(t *testing.T) {
589+
_, err := project.WithSelectedJob("nonexistent")
590+
assert.ErrorContains(t, err, "no such job: nonexistent")
591+
})
592+
}
593+
525594
func ptr[T any](s T) *T {
526595
return &s
527596
}

0 commit comments

Comments
 (0)