-
Notifications
You must be signed in to change notification settings - Fork 582
/
checkIfStepActive.go
186 lines (166 loc) · 7.1 KB
/
checkIfStepActive.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
package cmd
import (
"encoding/json"
"fmt"
"io"
"os"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/SAP/jenkins-library/pkg/config"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/piperutils"
)
type checkStepActiveCommandOptions struct {
openFile func(s string, t map[string]string) (io.ReadCloser, error)
fileExists func(filename string) (bool, error)
stageConfigFile string
stepName string
stageName string
v1Active bool
stageOutputFile string
stepOutputFile string
}
var checkStepActiveOptions checkStepActiveCommandOptions
// CheckStepActiveCommand is the entry command for checking if a step is active in a defined stage
func CheckStepActiveCommand() *cobra.Command {
checkStepActiveOptions.openFile = config.OpenPiperFile
checkStepActiveOptions.fileExists = piperutils.FileExists
var checkStepActiveCmd = &cobra.Command{
Use: "checkIfStepActive",
Short: "Checks if a step is active in a defined stage.",
PreRun: func(cmd *cobra.Command, _ []string) {
path, _ := os.Getwd()
fatalHook := &log.FatalHook{CorrelationID: GeneralConfig.CorrelationID, Path: path}
log.RegisterHook(fatalHook)
initStageName(false)
log.SetVerbose(GeneralConfig.Verbose)
GeneralConfig.GitHubAccessTokens = ResolveAccessTokens(GeneralConfig.GitHubTokens)
},
Run: func(cmd *cobra.Command, _ []string) {
utils := &piperutils.Files{}
err := checkIfStepActive(utils)
if err != nil {
log.SetErrorCategory(log.ErrorConfiguration)
log.Entry().WithError(err).Fatal("Checking for an active step failed")
}
},
}
addCheckStepActiveFlags(checkStepActiveCmd)
return checkStepActiveCmd
}
func checkIfStepActive(utils piperutils.FileUtils) error {
// make the stageName the leading parameter
if len(checkStepActiveOptions.stageName) == 0 && GeneralConfig.StageName != "" {
checkStepActiveOptions.stageName = GeneralConfig.StageName
}
if checkStepActiveOptions.stageName == "" {
return errors.New("stage name must not be empty")
}
if checkStepActiveOptions.v1Active {
log.Entry().Warning("Please do not use --useV1 flag since it is deprecated and will be removed in future releases")
}
var pConfig config.Config
// load project config and defaults
projectConfig, err := initializeConfig(&pConfig)
if err != nil {
log.Entry().Errorf("Failed to load project config: %v", err)
return errors.Wrapf(err, "Failed to load project config failed")
}
stageConfigFile, err := checkStepActiveOptions.openFile(checkStepActiveOptions.stageConfigFile, GeneralConfig.GitHubAccessTokens)
if err != nil {
return errors.Wrapf(err, "config: open stage configuration file '%v' failed", checkStepActiveOptions.stageConfigFile)
}
defer stageConfigFile.Close()
// load and evaluate step conditions
runConfig := config.RunConfig{StageConfigFile: stageConfigFile}
runConfigV1 := &config.RunConfigV1{RunConfig: runConfig}
err = runConfigV1.InitRunConfigV1(projectConfig, utils, GeneralConfig.EnvRootPath)
if err != nil {
return err
}
runSteps := runConfigV1.RunSteps
runStages := runConfigV1.RunStages
log.Entry().Debugf("RunSteps: %v", runSteps)
log.Entry().Debugf("RunStages: %v", runStages)
if len(checkStepActiveOptions.stageOutputFile) > 0 || len(checkStepActiveOptions.stepOutputFile) > 0 {
if len(checkStepActiveOptions.stageOutputFile) > 0 {
result, err := json.Marshal(runStages)
if err != nil {
return fmt.Errorf("error marshalling json: %w", err)
}
log.Entry().Infof("Writing stage condition file %v", checkStepActiveOptions.stageOutputFile)
err = utils.FileWrite(checkStepActiveOptions.stageOutputFile, result, 0666)
if err != nil {
return fmt.Errorf("error writing file '%v': %w", checkStepActiveOptions.stageOutputFile, err)
}
}
if len(checkStepActiveOptions.stepOutputFile) > 0 {
result, err := json.Marshal(runSteps)
if err != nil {
return fmt.Errorf("error marshalling json: %w", err)
}
log.Entry().Infof("Writing step condition file %v", checkStepActiveOptions.stepOutputFile)
err = utils.FileWrite(checkStepActiveOptions.stepOutputFile, result, 0666)
if err != nil {
return fmt.Errorf("error writing file '%v': %w", checkStepActiveOptions.stepOutputFile, err)
}
}
// do not perform a check if output files are written
return nil
}
if !runSteps[checkStepActiveOptions.stageName][checkStepActiveOptions.stepName] {
return errors.Errorf("Step %s in stage %s is not active", checkStepActiveOptions.stepName, checkStepActiveOptions.stageName)
}
log.Entry().Infof("Step %s in stage %s is active", checkStepActiveOptions.stepName, checkStepActiveOptions.stageName)
return nil
}
func addCheckStepActiveFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&checkStepActiveOptions.stageConfigFile, "stageConfig", ".resources/piper-stage-config.yml",
"Default config of piper pipeline stages")
cmd.Flags().StringVar(&checkStepActiveOptions.stepName, "step", "", "Name of the step being checked")
cmd.Flags().StringVar(&checkStepActiveOptions.stageName, "stage", "", "Name of the stage in which contains the step being checked")
cmd.Flags().BoolVar(&checkStepActiveOptions.v1Active, "useV1", false, "Use new CRD-style stage configuration (deprecated)")
cmd.Flags().StringVar(&checkStepActiveOptions.stageOutputFile, "stageOutputFile", "", "Defines a file path. If set, the stage output will be written to the defined file")
cmd.Flags().StringVar(&checkStepActiveOptions.stepOutputFile, "stepOutputFile", "", "Defines a file path. If set, the step output will be written to the defined file")
_ = cmd.MarkFlagRequired("step")
}
func initializeConfig(pConfig *config.Config) (*config.Config, error) {
projectConfigFile := getProjectConfigFile(GeneralConfig.CustomConfig)
var customConfig io.ReadCloser
var err error
//accept that config file cannot be loaded as its not mandatory here
if exists, err := checkStepActiveOptions.fileExists(projectConfigFile); exists {
log.Entry().Infof("Project config: '%s'", projectConfigFile)
customConfig, err = checkStepActiveOptions.openFile(projectConfigFile, GeneralConfig.GitHubAccessTokens)
if err != nil {
return nil, errors.Wrapf(err, "config: open configuration file '%v' failed", projectConfigFile)
}
defer customConfig.Close()
} else {
log.Entry().Infof("Project config: NONE ('%s' does not exist)", projectConfigFile)
}
defaultConfig := []io.ReadCloser{}
for _, f := range GeneralConfig.DefaultConfig {
fc, err := checkStepActiveOptions.openFile(f, GeneralConfig.GitHubAccessTokens)
// only create error for non-default values
if err != nil && f != ".pipeline/defaults.yaml" {
return nil, errors.Wrapf(err, "config: getting defaults failed: '%v'", f)
}
if err == nil {
defaultConfig = append(defaultConfig, fc)
}
}
var flags map[string]interface{}
filter := config.StepFilters{
All: []string{},
General: []string{},
Stages: []string{},
Steps: []string{},
Env: []string{},
}
_, err = pConfig.GetStepConfig(flags, "", customConfig, defaultConfig, GeneralConfig.IgnoreCustomDefaults, filter, config.StepData{}, nil, "", "")
if err != nil {
return nil, errors.Wrap(err, "getting step config failed")
}
return pConfig, nil
}