github.com/xgoffin/jenkins-library@v1.154.0/cmd/checkIfStepActive.go (about) 1 package cmd 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "os" 8 9 "github.com/SAP/jenkins-library/pkg/config" 10 "github.com/SAP/jenkins-library/pkg/log" 11 "github.com/SAP/jenkins-library/pkg/piperutils" 12 "github.com/bmatcuk/doublestar" 13 "github.com/pkg/errors" 14 "github.com/spf13/cobra" 15 ) 16 17 type checkStepActiveCommandOptions struct { 18 openFile func(s string, t map[string]string) (io.ReadCloser, error) 19 stageConfigFile string 20 stepName string 21 stageName string 22 v1Active bool 23 stageOutputFile string 24 stepOutputFile string 25 } 26 27 var checkStepActiveOptions checkStepActiveCommandOptions 28 29 // CheckStepActiveCommand is the entry command for checking if a step is active in a defined stage 30 func CheckStepActiveCommand() *cobra.Command { 31 checkStepActiveOptions.openFile = config.OpenPiperFile 32 var checkStepActiveCmd = &cobra.Command{ 33 Use: "checkIfStepActive", 34 Short: "Checks if a step is active in a defined stage.", 35 PreRun: func(cmd *cobra.Command, _ []string) { 36 path, _ := os.Getwd() 37 fatalHook := &log.FatalHook{CorrelationID: GeneralConfig.CorrelationID, Path: path} 38 log.RegisterHook(fatalHook) 39 initStageName(false) 40 log.SetVerbose(GeneralConfig.Verbose) 41 GeneralConfig.GitHubAccessTokens = ResolveAccessTokens(GeneralConfig.GitHubTokens) 42 }, 43 Run: func(cmd *cobra.Command, _ []string) { 44 utils := &piperutils.Files{} 45 err := checkIfStepActive(utils) 46 if err != nil { 47 log.SetErrorCategory(log.ErrorConfiguration) 48 log.Entry().WithError(err).Fatal("Checking for an active step failed") 49 } 50 }, 51 } 52 addCheckStepActiveFlags(checkStepActiveCmd) 53 return checkStepActiveCmd 54 } 55 56 func checkIfStepActive(utils piperutils.FileUtils) error { 57 // make the stageName the leading parameter 58 if len(checkStepActiveOptions.stageName) == 0 && GeneralConfig.StageName != "" { 59 checkStepActiveOptions.stageName = GeneralConfig.StageName 60 } 61 if checkStepActiveOptions.stageName == "" { 62 return errors.New("stage name must not be empty") 63 } 64 var pConfig config.Config 65 66 // load project config and defaults 67 projectConfig, err := initializeConfig(&pConfig) 68 if err != nil { 69 log.Entry().Errorf("Failed to load project config: %v", err) 70 } 71 72 stageConfigFile, err := checkStepActiveOptions.openFile(checkStepActiveOptions.stageConfigFile, GeneralConfig.GitHubAccessTokens) 73 if err != nil { 74 return errors.Wrapf(err, "config: open stage configuration file '%v' failed", checkStepActiveOptions.stageConfigFile) 75 } 76 defer stageConfigFile.Close() 77 78 runSteps := map[string]map[string]bool{} 79 runStages := map[string]bool{} 80 81 // load and evaluate step conditions 82 if checkStepActiveOptions.v1Active { 83 runConfig := config.RunConfig{StageConfigFile: stageConfigFile} 84 runConfigV1 := &config.RunConfigV1{RunConfig: runConfig} 85 err = runConfigV1.InitRunConfigV1(projectConfig, nil, nil, nil, nil, utils, GeneralConfig.EnvRootPath) 86 if err != nil { 87 return err 88 } 89 runSteps = runConfigV1.RunSteps 90 runStages = runConfigV1.RunStages 91 } else { 92 runConfig := &config.RunConfig{StageConfigFile: stageConfigFile} 93 err = runConfig.InitRunConfig(projectConfig, nil, nil, nil, nil, doublestar.Glob, checkStepActiveOptions.openFile) 94 if err != nil { 95 return err 96 } 97 runSteps = runConfig.RunSteps 98 runStages = runConfig.RunStages 99 } 100 101 log.Entry().Debugf("RunSteps: %v", runSteps) 102 log.Entry().Debugf("RunStages: %v", runStages) 103 104 if len(checkStepActiveOptions.stageOutputFile) > 0 || len(checkStepActiveOptions.stepOutputFile) > 0 { 105 if len(checkStepActiveOptions.stageOutputFile) > 0 { 106 result, err := json.Marshal(runStages) 107 if err != nil { 108 return fmt.Errorf("error marshalling json: %w", err) 109 } 110 log.Entry().Infof("Writing stage condition file %v", checkStepActiveOptions.stageOutputFile) 111 err = utils.FileWrite(checkStepActiveOptions.stageOutputFile, result, 0666) 112 if err != nil { 113 return fmt.Errorf("error writing file '%v': %w", checkStepActiveOptions.stageOutputFile, err) 114 } 115 } 116 117 if len(checkStepActiveOptions.stepOutputFile) > 0 { 118 result, err := json.Marshal(runSteps) 119 if err != nil { 120 return fmt.Errorf("error marshalling json: %w", err) 121 } 122 log.Entry().Infof("Writing step condition file %v", checkStepActiveOptions.stepOutputFile) 123 err = utils.FileWrite(checkStepActiveOptions.stepOutputFile, result, 0666) 124 if err != nil { 125 return fmt.Errorf("error writing file '%v': %w", checkStepActiveOptions.stepOutputFile, err) 126 } 127 } 128 129 // do not perform a check if output files are written 130 return nil 131 } 132 133 if !runSteps[checkStepActiveOptions.stageName][checkStepActiveOptions.stepName] { 134 return errors.Errorf("Step %s in stage %s is not active", checkStepActiveOptions.stepName, checkStepActiveOptions.stageName) 135 } 136 log.Entry().Infof("Step %s in stage %s is active", checkStepActiveOptions.stepName, checkStepActiveOptions.stageName) 137 138 return nil 139 } 140 141 func addCheckStepActiveFlags(cmd *cobra.Command) { 142 cmd.Flags().StringVar(&checkStepActiveOptions.stageConfigFile, "stageConfig", ".resources/piper-stage-config.yml", 143 "Default config of piper pipeline stages") 144 cmd.Flags().StringVar(&checkStepActiveOptions.stepName, "step", "", "Name of the step being checked") 145 cmd.Flags().StringVar(&checkStepActiveOptions.stageName, "stage", "", "Name of the stage in which contains the step being checked") 146 cmd.Flags().BoolVar(&checkStepActiveOptions.v1Active, "useV1", false, "Use new CRD-style stage configuration") 147 cmd.Flags().StringVar(&checkStepActiveOptions.stageOutputFile, "stageOutputFile", "", "Defines a file path. If set, the stage output will be written to the defined file") 148 cmd.Flags().StringVar(&checkStepActiveOptions.stepOutputFile, "stepOutputFile", "", "Defines a file path. If set, the step output will be written to the defined file") 149 cmd.MarkFlagRequired("step") 150 } 151 152 func initializeConfig(pConfig *config.Config) (*config.Config, error) { 153 projectConfigFile := getProjectConfigFile(GeneralConfig.CustomConfig) 154 customConfig, err := checkStepActiveOptions.openFile(projectConfigFile, GeneralConfig.GitHubAccessTokens) 155 if err != nil { 156 return nil, errors.Wrapf(err, "config: open configuration file '%v' failed", projectConfigFile) 157 } 158 defer customConfig.Close() 159 160 defaultConfig := []io.ReadCloser{} 161 for _, f := range GeneralConfig.DefaultConfig { 162 fc, err := checkStepActiveOptions.openFile(f, GeneralConfig.GitHubAccessTokens) 163 // only create error for non-default values 164 if err != nil && f != ".pipeline/defaults.yaml" { 165 return nil, errors.Wrapf(err, "config: getting defaults failed: '%v'", f) 166 } 167 if err == nil { 168 defaultConfig = append(defaultConfig, fc) 169 } 170 } 171 var flags map[string]interface{} 172 filter := config.StepFilters{ 173 All: []string{}, 174 General: []string{}, 175 Stages: []string{}, 176 Steps: []string{}, 177 Env: []string{}, 178 } 179 180 _, err = pConfig.GetStepConfig(flags, "", customConfig, defaultConfig, GeneralConfig.IgnoreCustomDefaults, filter, config.StepData{}, nil, "", "") 181 if err != nil { 182 return nil, errors.Wrap(err, "getting step config failed") 183 } 184 return pConfig, nil 185 }