@@ -15,27 +15,34 @@ type TagXReposTasks struct {
15
15
Gerrit GerritClient
16
16
}
17
17
18
+ func (x * TagXReposTasks ) NewDefinition () * wf.Definition {
19
+ wd := wf .New ()
20
+ repos := wf .Task0 (wd , "Select repositories" , x .SelectRepos )
21
+ wf .Expand1 (wd , "Create plan" , x .BuildPlan , repos )
22
+ return wd
23
+ }
24
+
18
25
type TagRepo struct {
19
26
Name string
20
27
Next string
21
28
Deps []string
22
29
}
23
30
24
- func (x * TagXReposTasks ) SelectRepos (ctx * wf.TaskContext ) ([]* TagRepo , error ) {
31
+ func (x * TagXReposTasks ) SelectRepos (ctx * wf.TaskContext ) ([]TagRepo , error ) {
25
32
projects , err := x .Gerrit .ListProjects (ctx )
26
33
if err != nil {
27
34
return nil , err
28
35
}
29
36
30
37
ctx .Printf ("Examining repositories %v" , projects )
31
- var repos []* TagRepo
38
+ var repos []TagRepo
32
39
for _ , p := range projects {
33
40
repo , err := x .readRepo (ctx , p )
34
41
if err != nil {
35
42
return nil , err
36
43
}
37
44
if repo != nil {
38
- repos = append (repos , repo )
45
+ repos = append (repos , * repo )
39
46
}
40
47
}
41
48
return repos , nil
@@ -99,3 +106,55 @@ func (x *TagXReposTasks) readRepo(ctx *wf.TaskContext, project string) (*TagRepo
99
106
}
100
107
return result , nil
101
108
}
109
+
110
+ func (x * TagXReposTasks ) BuildPlan (wd * wf.Definition , repos []TagRepo ) error {
111
+ updated := map [string ]wf.Dependency {}
112
+
113
+ // Find all repositories whose dependencies are satisfied and update
114
+ // them, proceeding until all are updated or no progress can be made.
115
+ for len (updated ) != len (repos ) {
116
+ progress := false
117
+ for _ , repo := range repos {
118
+ dep , ok := x .planRepo (wd , repo , updated )
119
+ if ! ok {
120
+ continue
121
+ }
122
+ updated [repo .Name ] = dep
123
+ progress = true
124
+ }
125
+
126
+ if ! progress {
127
+ return fmt .Errorf ("cycle detected, sorry" )
128
+ }
129
+ }
130
+ return nil
131
+ }
132
+
133
+ func (x * TagXReposTasks ) planRepo (wd * wf.Definition , repo TagRepo , updated map [string ]wf.Dependency ) (wf.Dependency , bool ) {
134
+ var deps []wf.Dependency
135
+ for _ , repoDeps := range repo .Deps {
136
+ if dep , ok := updated [repoDeps ]; ok {
137
+ deps = append (deps , dep )
138
+ } else {
139
+ return nil , false
140
+ }
141
+ }
142
+ wd = wd .Sub (repo .Name )
143
+ commit := wf .Task1 (wd , "update go.mod" , x .UpdateGoMod , wf .Const (repo ), wf .After (deps ... ))
144
+ green := wf .Action2 (wd , "wait for green post-submit" , x .AwaitGreen , wf .Const (repo ), commit )
145
+ tagged := wf .Task2 (wd , "tag" , x .TagRepo , wf .Const (repo ), commit , wf .After (green ))
146
+ wf .Output (wd , "tagged version" , tagged )
147
+ return tagged , true
148
+ }
149
+
150
+ func (x * TagXReposTasks ) UpdateGoMod (ctx * wf.TaskContext , repo TagRepo ) (string , error ) {
151
+ return "" , nil
152
+ }
153
+
154
+ func (x * TagXReposTasks ) AwaitGreen (ctx * wf.TaskContext , repo TagRepo , commit string ) error {
155
+ return nil
156
+ }
157
+
158
+ func (x * TagXReposTasks ) TagRepo (ctx * wf.TaskContext , repo TagRepo , commit string ) (string , error ) {
159
+ return repo .Next , nil
160
+ }
0 commit comments