1
1
package policy
2
2
3
3
import (
4
- "bytes"
5
4
"fmt"
6
5
"os"
7
6
"path/filepath"
7
+ "slices"
8
8
"time"
9
9
10
+ "maps"
11
+
12
+ "dario.cat/mergo"
10
13
"github.com/jinzhu/copier"
11
14
"github.com/rs/zerolog/log"
12
15
"github.com/spf13/viper"
13
- "golang.org/x/exp/maps"
14
16
)
15
17
16
18
// repoConfig contains all the attributes of a repo. Each element here
@@ -20,15 +22,11 @@ import (
20
22
// levels
21
23
type repoConfig struct {
22
24
Owner string
23
- Description string
24
- PCRepo string
25
- DHRepo string
26
- CSRepo string
27
- PackageName string
28
- Reviewers []string
29
25
ExposePorts string
26
+ PackageName string
30
27
Binary string
31
28
Buildenv string
29
+ Builds buildMap
32
30
BaseImage string
33
31
DistrolessBaseImage string
34
32
Cgo bool
@@ -42,6 +40,26 @@ type repoConfig struct {
42
40
Repos map [string ]repoConfig `copier:"-"`
43
41
}
44
42
43
+ // build models the variations in build and their corresponding packages
44
+ type build struct {
45
+ Flags []string
46
+ BuildPackageName string
47
+ Description string
48
+ ImageTitle string
49
+ PCRepo string
50
+ DHRepo string
51
+ CSRepo string
52
+ CIRepo string
53
+ Env []string
54
+ Archs []struct {
55
+ Docker string
56
+ Deb string
57
+ Go string
58
+ }
59
+ }
60
+
61
+ type buildMap map [string ]* build
62
+
45
63
// Policies models the config file structure. There are three levels
46
64
// at which a particular value can be set: group-level, repo, branch.
47
65
// The group level is applicable for all the repos in that group.
@@ -66,6 +84,7 @@ type branchVals struct {
66
84
UpgradeFromVer string
67
85
Tests []string
68
86
Features []string
87
+ Builds buildMap
69
88
DeletedFiles []string
70
89
}
71
90
@@ -77,13 +96,10 @@ type branchVals struct {
77
96
type RepoPolicy struct {
78
97
Owner string
79
98
Name string
80
- Description string
81
99
Default string
82
- PCRepo string
83
- DHRepo string
84
- CSRepo string
85
- Binary string
86
100
PackageName string
101
+ Binary string
102
+ Builds buildMap
87
103
Reviewers []string
88
104
ExposePorts string
89
105
Cgo bool
@@ -93,9 +109,7 @@ type RepoPolicy struct {
93
109
Branch string
94
110
Branchvals branchVals
95
111
Branches map [string ]branchVals
96
- prBranch string
97
112
Timestamp string
98
- Visibility string
99
113
}
100
114
101
115
// PushOptions collects the input required to update templates for a
@@ -115,7 +129,6 @@ func (rp *RepoPolicy) SetTimestamp(ts time.Time) {
115
129
ts = time .Now ().UTC ()
116
130
}
117
131
rp .Timestamp = ts .Format (time .UnixDate )
118
-
119
132
}
120
133
121
134
// GetTimeStamp returns the timestamp currently set for the given repopolicy.
@@ -126,7 +139,7 @@ func (rp *RepoPolicy) GetTimeStamp() (time.Time, error) {
126
139
return ts , err
127
140
}
128
141
129
- // SetBranch sets the Branch and Branchvals properties so that templates can simply access them instead of looking them up in the Branches map
142
+ // SetBranch sets the Branch and Branchvals properties so that templates can simply access them instead of looking them up in the Branches map. This must be called before calling Render()
130
143
func (rp * RepoPolicy ) SetBranch (branch string ) error {
131
144
bv , found := rp .Branches [branch ]
132
145
if ! found {
@@ -140,7 +153,7 @@ func (rp *RepoPolicy) SetBranch(branch string) error {
140
153
141
154
// GetAllBranches returns all the branches that are managed for this repo
142
155
func (rp * RepoPolicy ) GetAllBranches () []string {
143
- return maps .Keys (rp .Branches )
156
+ return slices . Sorted ( maps .Keys (rp .Branches ) )
144
157
}
145
158
146
159
// GetRepoPolicy will fetch the RepoPolicy for the supplied repo with
@@ -193,6 +206,9 @@ func (p *Policies) GetRepoPolicy(repo string) (RepoPolicy, error) {
193
206
if err != nil {
194
207
return rp , err
195
208
}
209
+ // builds are merged
210
+ log .Debug ().Msgf ("Merging builds for %s/%s" , rp .Name , b )
211
+ rbv .Builds = mergeBuilds (r .Builds , bbv .Builds )
196
212
// attributes that are unions
197
213
rbv .Features = newSetFromSlices (group .Features , r .Features , bbv .Features ).Members ()
198
214
rbv .DeletedFiles = newSetFromSlices (p .DeletedFiles , group .DeletedFiles , r .DeletedFiles , bbv .DeletedFiles ).Members ()
@@ -204,6 +220,16 @@ func (p *Policies) GetRepoPolicy(repo string) (RepoPolicy, error) {
204
220
return rp , nil
205
221
}
206
222
223
+ // mergeBuilds returns a merged build map from _r_epo and _b_ranch level
224
+ func mergeBuilds (r , b buildMap ) buildMap {
225
+ merged := make (buildMap )
226
+ maps .Copy (merged , r )
227
+ if err := mergo .Merge (& merged , b , mergo .WithOverride , mergo .WithAppendSlice ); err != nil {
228
+ log .Fatal ().Interface ("dst" , merged ).Interface ("src" , b ).Msgf ("could not merge branch-level build definitions for: %v" , err )
229
+ }
230
+ return merged
231
+ }
232
+
207
233
// ProcessBranch will render the templates into a git worktree for the supplied branch, commit and push the changes upstream
208
234
// The upstream branch name is the supplied branch name prefixed with releng/ and is returned
209
235
func (rp * RepoPolicy ) ProcessBranch (pushOpts * PushOptions ) error {
@@ -270,36 +296,6 @@ func (rp *RepoPolicy) ProcessBranch(pushOpts *PushOptions) error {
270
296
return nil
271
297
}
272
298
273
- // Stringer implementation for Policies
274
- func (p Policies ) String () string {
275
- w := new (bytes.Buffer )
276
- for _ , grp := range p .Groups {
277
- for repo , crPol := range grp .Repos {
278
- fmt .Fprintf (w , "%s: package %s, image %s" , repo , crPol .PackageName , crPol .DHRepo )
279
- rp , err := p .GetRepoPolicy (repo )
280
- if err != nil {
281
- log .Fatal ().Str ("repo" , repo ).Err (err ).Msg ("failed to get policy, this should not happen" )
282
- }
283
- fmt .Fprintf (w , " %s\n " , rp )
284
- }
285
- }
286
- return w .String ()
287
- }
288
-
289
- // Stringer implementation for RepoPolicy
290
- func (rp RepoPolicy ) String () string {
291
- w := new (bytes.Buffer )
292
- for b , bv := range rp .Branches {
293
- fmt .Fprintf (w , " %s: package %s, image %s, features %v" , b , rp .PackageName , rp .DHRepo , bv .Features )
294
- if len (bv .Buildenv ) > 0 {
295
- fmt .Fprintf (w , " built on %s" , bv .Buildenv )
296
- } else {
297
- fmt .Fprintf (w , " not built" )
298
- }
299
- }
300
- return w .String ()
301
- }
302
-
303
299
// LoadRepoPolicies populates the supplied policies with the policy key from a the config file
304
300
// This will panic if the type assertions fail
305
301
func LoadRepoPolicies (policies * Policies ) error {
0 commit comments