forked from edaniszewski/chart-releaser
-
Notifications
You must be signed in to change notification settings - Fork 0
/
context.go
224 lines (197 loc) · 6.48 KB
/
context.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
package ctx
import (
"bytes"
"context"
"fmt"
"io"
"os"
"regexp"
"strings"
"time"
"github.com/apex/log"
"github.com/davecgh/go-spew/spew"
"github.com/vapor-ware/chart-releaser/pkg/client"
"github.com/vapor-ware/chart-releaser/pkg/errs"
version "github.com/vapor-ware/chart-releaser/pkg/semver"
"github.com/vapor-ware/chart-releaser/pkg/strategies"
v1 "github.com/vapor-ware/chart-releaser/pkg/v1/cfg"
"github.com/fatih/color"
"github.com/mgutz/ansi"
)
// RepoType defines the type of repository container the Helm Chart.
type RepoType string
// RepoTypes supported by chart-releaser
const (
RepoGithub RepoType = "github"
)
// ListRepoTypes returns all of the RepoTypes supported by chart-releaser.
func ListRepoTypes() []RepoType {
return []RepoType{
RepoGithub,
}
}
// RepoTypeFromString gets a RepoType corresponding to a string.
func RepoTypeFromString(s string) (RepoType, error) {
switch strings.ToLower(s) {
case "github", "github.com":
return RepoGithub, nil
default:
return "", fmt.Errorf("unsupported repository type: %s (supported: %v)", s, ListRepoTypes())
}
}
// App version information.
type App struct {
NewVersion version.Semver
PreviousVersion version.Semver
}
// Author information for the committer.
type Author struct {
Name string
Email string
}
// Chart version, metadata, and contents information.
type Chart struct {
Name string
SubPath string
File File
NewVersion version.Semver
PreviousVersion version.Semver
}
// File holds basic data about a file, its previous contents,
// and its updated contents.
type File struct {
Path string
PreviousContents []byte
NewContents []byte
}
// HasChanges determines whether the previous contents of the file differ from the
// new contents of the file.
func (f *File) HasChanges() bool {
return !bytes.Equal(f.PreviousContents, f.NewContents)
}
// Git information used for publishing chart updates.
type Git struct {
Tag string
Ref string
Base string
}
// Repository metadata.
type Repository struct {
Type RepoType
Owner string
Name string
}
// Release metadata used for generating the release messages (commits, PRs).
type Release struct {
PRTitle string
PRBody string
ChartCommitMsg string
ExtrasCommitMsg string
Matches []*regexp.Regexp
Ignores []*regexp.Regexp
}
// Context holds information that is used by chart-releaser throughout
// the update process. Its values get populated and updated as various
// stages operate on it. It holds all release state.
type Context struct {
context.Context
Config *v1.Config
Out io.Writer
Token string
PublishStrategy strategies.PublishStrategy
UpdateStrategy strategies.UpdateStrategy
App App
Author Author
Chart Chart
Client client.Client
Files []File
Git Git
Repository Repository
Release Release
// CurrentFile holds a reference to a extras file that is currently being
// worked on when publishing changes. This allows template rendering to
// access information about the file, e.g. .CurrentFile.Path
CurrentFile File
AllowDirty bool
DryRun bool
ShowDiff bool
errors errs.Collector
}
// Dump the Context to console.
//nolint:gosimple
func (ctx *Context) Dump() {
if ctx.Out == nil {
log.Error("unable to dump context: context output writer is nil")
return
}
_, _ = fmt.Fprintln(ctx.Out, color.New(color.Bold).Sprint("\n=== Context ==="))
_, _ = fmt.Fprintln(ctx.Out, fmt.Sprintf("AllowDirty:\t\t%v", ctx.AllowDirty))
_, _ = fmt.Fprintln(ctx.Out, fmt.Sprintf("DryRun:\t\t\t%v", ctx.DryRun))
_, _ = fmt.Fprintln(ctx.Out, fmt.Sprintf("ShowDiff:\t\t%v", ctx.ShowDiff))
_, _ = fmt.Fprintln(ctx.Out, fmt.Sprintf("PublishStrategy:\t%s", ctx.PublishStrategy))
_, _ = fmt.Fprintln(ctx.Out, fmt.Sprintf("UpdateStrategy:\t\t%s", ctx.UpdateStrategy))
_, _ = fmt.Fprintln(ctx.Out, fmt.Sprintf("Token:\t\t\t%s****", ctx.Token[0:4]))
_, _ = fmt.Fprintln(ctx.Out, color.New(color.Bold).Sprint("Config"))
_, _ = fmt.Fprintln(ctx.Out, spew.Sdump(ctx.Config))
_, _ = fmt.Fprintln(ctx.Out, color.New(color.Bold).Sprint("App"))
_, _ = fmt.Fprintln(ctx.Out, spew.Sdump(ctx.App))
_, _ = fmt.Fprintln(ctx.Out, color.New(color.Bold).Sprint("Author"))
_, _ = fmt.Fprintln(ctx.Out, spew.Sdump(ctx.Author))
_, _ = fmt.Fprintln(ctx.Out, color.New(color.Bold).Sprint("Chart"))
_, _ = fmt.Fprintln(ctx.Out, spew.Sdump(ctx.Chart))
_, _ = fmt.Fprintln(ctx.Out, color.New(color.Bold).Sprint("Files"))
_, _ = fmt.Fprintln(ctx.Out, spew.Sdump(ctx.Files))
_, _ = fmt.Fprintln(ctx.Out, color.New(color.Bold).Sprint("Git"))
_, _ = fmt.Fprintln(ctx.Out, spew.Sdump(ctx.Git))
_, _ = fmt.Fprintln(ctx.Out, color.New(color.Bold).Sprint("Repository"))
_, _ = fmt.Fprintln(ctx.Out, spew.Sdump(ctx.Repository))
_, _ = fmt.Fprintln(ctx.Out, color.New(color.Bold).Sprint("Release"))
_, _ = fmt.Fprintln(ctx.Out, spew.Sdump(ctx.Release))
}
// PrintErrors prints any errors encountered and collected by the Context's error
// collector.
func (ctx *Context) PrintErrors() {
if ctx.errors.HasErrors() {
_, _ = fmt.Fprint(ctx.Out, ansi.Color("\ndry-run completed with errors", "red"))
_, _ = fmt.Fprint(ctx.Out, ctx.errors.Error())
} else {
_, _ = fmt.Fprint(ctx.Out, ansi.Color("dry-run completed without errors\n", "green"))
}
}
// Errors returns the errors collected by the Context.
func (ctx *Context) Errors() error {
if ctx.errors.HasErrors() {
return &ctx.errors
}
return nil
}
// CheckDryRun checks whether the Context is configured for a dry-run, and if so,
// to only log the provided error. If it is not in a dry-run state, it will return
// the same error it was given for the caller to propagate appropriately.
func (ctx *Context) CheckDryRun(err error) error {
if ctx.DryRun {
log.WithError(err).Warn("dry-run: ignoring error")
ctx.errors.Add(err)
return nil
}
return err
}
// New creates a new v1 Context for the given v1 Config.
func New(config *v1.Config) *Context {
return Wrap(context.Background(), config)
}
// NewWithTimeout creates a new v1 Context for the given v1 Config, with
// an timeout to cancel the context.
func NewWithTimeout(config *v1.Config, timeout time.Duration) (*Context, context.CancelFunc) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
return Wrap(ctx, config), cancel
}
// Wrap an existing context.Context into a v1 Context.
func Wrap(ctx context.Context, config *v1.Config) *Context {
return &Context{
Context: ctx,
Config: config,
Out: os.Stdout,
errors: *errs.NewCollector(),
}
}