@@ -10,6 +10,7 @@ import (
10
10
"github.com/benchkram/bob/bob/bobfile"
11
11
"github.com/benchkram/bob/pkg/boberror"
12
12
"github.com/benchkram/bob/pkg/ctl"
13
+ "github.com/benchkram/bob/pkg/sliceutil"
13
14
)
14
15
15
16
// Examples of possible interactive usecase
@@ -20,8 +21,7 @@ import (
20
21
// 2: [Done] plain docker-compose run with dependcies to build-cmds
21
22
// containing instructions how to build the container image.
22
23
//
23
- // TODO:
24
- // 3: init script requiring a executable to run before
24
+ // 3: [Done] init script requiring a executable to run before
25
25
// containing a health endpoint (REST?). So the init script can be
26
26
// sure about the service to be functional.
27
27
//
@@ -31,30 +31,26 @@ import (
31
31
//
32
32
// Canceling the cmd from the outside must be done through the context.
33
33
//
34
- // TODO : Forbid circular dependecys.
35
- func (b * B ) Run (ctx context.Context , runName string ) (_ ctl.Commander , err error ) {
34
+ // FIXME : Forbid circular dependecys.
35
+ func (b * B ) Run (ctx context.Context , runTaskName string ) (_ ctl.Commander , err error ) {
36
36
defer errz .Recover (& err )
37
37
38
38
aggregate , err := b .Aggregate ()
39
39
errz .Fatal (err )
40
40
41
41
b .PrintVersionCompatibility (aggregate )
42
42
43
- runTask , ok := aggregate .RTasks [runName ]
43
+ runTask , ok := aggregate .RTasks [runTaskName ]
44
44
if ! ok {
45
45
return nil , ErrRunDoesNotExist
46
46
}
47
47
48
48
// gather interactive tasks
49
- childInteractiveTasks := b . runTasksInPipeline (runName , aggregate )
49
+ childInteractiveTasks := runTasksInPipeline (runTaskName , aggregate )
50
50
interactiveTasks := []string {runTask .Name ()}
51
51
interactiveTasks = append (interactiveTasks , childInteractiveTasks ... )
52
52
53
53
// build dependencies & main runTask
54
- for _ , task := range interactiveTasks {
55
- err = executeBuildTasksInPipeline (ctx , task , aggregate , b .nix )
56
- errz .Fatal (err )
57
- }
58
54
59
55
// generate run controls to steer the run cmd.
60
56
runCommands := []ctl.Command {}
@@ -67,7 +63,7 @@ func (b *B) Run(ctx context.Context, runName string) (_ ctl.Commander, err error
67
63
runCommands = append (runCommands , command )
68
64
}
69
65
70
- builder := NewBuilder (b , runName , aggregate , executeBuildTasksInPipeline )
66
+ builder := NewBuilder (b , runTaskName , aggregate , executeBuildTasksInPipeline )
71
67
commander := ctl .NewCommander (ctx , builder , runCommands ... )
72
68
73
69
return commander , nil
@@ -78,10 +74,10 @@ func (b *B) Run(ctx context.Context, runName string) (_ ctl.Commander, err error
78
74
//
79
75
// It will not error but return a empty error in case the runName
80
76
// does not exists.
81
- func ( b * B ) runTasksInPipeline (runName string , aggregate * bobfile.Bobfile ) []string {
77
+ func runTasksInPipeline (runTaskName string , aggregate * bobfile.Bobfile ) []string {
82
78
runTasks := []string {}
83
79
84
- run , ok := aggregate .RTasks [runName ]
80
+ run , ok := aggregate .RTasks [runTaskName ]
85
81
if ! ok {
86
82
return nil
87
83
}
@@ -93,7 +89,7 @@ func (b *B) runTasksInPipeline(runName string, aggregate *bobfile.Bobfile) []str
93
89
runTasks = append (runTasks , task )
94
90
95
91
// assure all it's dependent runTasks are also added.
96
- childs := b . runTasksInPipeline (task , aggregate )
92
+ childs := runTasksInPipeline (task , aggregate )
97
93
runTasks = append (runTasks , childs ... )
98
94
}
99
95
@@ -137,40 +133,49 @@ func isRunTask(name string, aggregate *bobfile.Bobfile) bool {
137
133
// return ok
138
134
// }
139
135
140
- // executeBuildTasksInPipeline takes a run task but only executes the dependent build tasks
141
- func executeBuildTasksInPipeline (ctx context.Context , runname string , aggregate * bobfile.Bobfile , nix * NixBuilder ) (err error ) {
136
+ // executeBuildTasksInPipeline takes a run task and starts the required builds.
137
+ func executeBuildTasksInPipeline (
138
+ ctx context.Context ,
139
+ runTaskName string ,
140
+ aggregate * bobfile.Bobfile ,
141
+ nix * NixBuilder ,
142
+ ) (err error ) {
142
143
defer errz .Recover (& err )
143
144
144
- interactive , ok := aggregate .RTasks [runname ]
145
+ _ , ok := aggregate .RTasks [runTaskName ]
145
146
if ! ok {
146
147
return ErrRunDoesNotExist
147
148
}
149
+ runTasksInPipeline := runTasksInPipeline (runTaskName , aggregate )
148
150
149
- // Gather build tasks
150
- buildTasks := []string {}
151
- for _ , child := range interactive .DependsOn {
152
- if isRunTask (child , aggregate ) {
153
- continue
154
- }
155
- buildTasks = append (buildTasks , child )
151
+ // Gather build tasks from run task dependencies.
152
+ // This is required to get the top most build tasks and start a build for each.
153
+ // Each run task could have could have distinct build pipeline beneth it.
154
+ // This implies that multiple unrelated builds could be started
155
+ // on a run invocation.
156
+
157
+ // umbrella run task
158
+ buildTasks , err := gatherBuildTasks (runTaskName , aggregate )
159
+ errz .Fatal (err )
160
+ // child run tasks
161
+ for _ , runTaskName := range runTasksInPipeline {
162
+ childBuildTasks , err := gatherBuildTasks (runTaskName , aggregate )
163
+ errz .Fatal (err )
164
+ buildTasks = append (buildTasks , childBuildTasks ... )
156
165
}
166
+ buildTasks = sliceutil .Unique (buildTasks )
157
167
158
168
// Build nix dependencies
159
169
if nix != nil {
160
170
fmt .Println ("Building nix dependencies..." )
161
171
err = nix .BuildNixDependencies (aggregate , buildTasks )
162
172
errz .Fatal (err )
163
- fmt .Println ("Succeded building nix dependencies" )
173
+ fmt .Println ("Succeeded building nix dependencies" )
164
174
}
165
175
166
- // Run dependent build tasks
167
- // before starting the run task
168
- for _ , child := range interactive .DependsOn {
169
- if isRunTask (child , aggregate ) {
170
- continue
171
- }
172
-
173
- playbook , err := aggregate .Playbook (child )
176
+ // Initiate each build
177
+ for _ , buildTask := range buildTasks {
178
+ playbook , err := aggregate .Playbook (buildTask )
174
179
if err != nil {
175
180
if errors .Is (err , boberror .ErrTaskDoesNotExist ) {
176
181
continue
@@ -184,3 +189,21 @@ func executeBuildTasksInPipeline(ctx context.Context, runname string, aggregate
184
189
185
190
return nil
186
191
}
192
+
193
+ // gatherBuildTasks returns all direct build tasks in the pipeline of a run task.
194
+ func gatherBuildTasks (runTaskName string , aggregate * bobfile.Bobfile ) ([]string , error ) {
195
+ runTask , ok := aggregate .RTasks [runTaskName ]
196
+ if ! ok {
197
+ return nil , ErrRunDoesNotExist
198
+ }
199
+
200
+ buildTasks := []string {}
201
+ for _ , child := range runTask .DependsOn {
202
+ if isRunTask (child , aggregate ) {
203
+ continue
204
+ }
205
+ buildTasks = append (buildTasks , child )
206
+ }
207
+
208
+ return buildTasks , nil
209
+ }
0 commit comments