2021-07-26 07:47:43 +02:00
package cmd
import (
2021-11-18 08:24:00 +02:00
"encoding/json"
"fmt"
2021-07-26 07:47:43 +02:00
"io"
"os"
"github.com/SAP/jenkins-library/pkg/config"
"github.com/SAP/jenkins-library/pkg/log"
2021-11-18 08:24:00 +02:00
"github.com/SAP/jenkins-library/pkg/piperutils"
2021-07-26 07:47:43 +02:00
"github.com/bmatcuk/doublestar"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
type checkStepActiveCommandOptions struct {
openFile func ( s string , t map [ string ] string ) ( io . ReadCloser , error )
stageConfigFile string
stepName string
stageName string
2021-11-18 08:24:00 +02:00
v1Active bool
stageOutputFile string
stepOutputFile string
2021-07-26 07:47:43 +02:00
}
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
var checkStepActiveCmd = & cobra . Command {
Use : "checkIfStepActive" ,
Short : "Checks if a step is active in a defined stage." ,
2022-03-08 13:12:56 +02:00
PreRun : func ( cmd * cobra . Command , _ [ ] string ) {
2021-07-26 07:47:43 +02:00
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 ) {
2021-11-18 08:24:00 +02:00
utils := & piperutils . Files { }
err := checkIfStepActive ( utils )
2021-07-26 07:47:43 +02:00
if err != nil {
log . SetErrorCategory ( log . ErrorConfiguration )
log . Entry ( ) . WithError ( err ) . Fatal ( "Checking for an active step failed" )
}
} ,
}
addCheckStepActiveFlags ( checkStepActiveCmd )
return checkStepActiveCmd
}
2021-11-18 08:24:00 +02:00
func checkIfStepActive ( utils piperutils . FileUtils ) error {
2022-03-08 13:12:56 +02:00
// 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" )
}
2021-07-26 07:47:43 +02:00
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 )
}
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 ( )
2021-11-18 08:24:00 +02:00
runSteps := map [ string ] map [ string ] bool { }
runStages := map [ string ] bool { }
2021-07-26 07:47:43 +02:00
// load and evaluate step conditions
2021-11-18 08:24:00 +02:00
if checkStepActiveOptions . v1Active {
runConfig := config . RunConfig { StageConfigFile : stageConfigFile }
runConfigV1 := & config . RunConfigV1 { RunConfig : runConfig }
err = runConfigV1 . InitRunConfigV1 ( projectConfig , nil , nil , nil , nil , utils )
if err != nil {
return err
}
runSteps = runConfigV1 . RunSteps
runStages = runConfigV1 . RunStages
} else {
runConfig := & config . RunConfig { StageConfigFile : stageConfigFile }
err = runConfig . InitRunConfig ( projectConfig , nil , nil , nil , nil , doublestar . Glob , checkStepActiveOptions . openFile )
if err != nil {
return err
}
runSteps = runConfig . RunSteps
runStages = runConfig . RunStages
2021-07-26 07:47:43 +02:00
}
2021-11-18 08:24:00 +02:00
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
}
2021-07-26 07:47:43 +02:00
2021-11-18 08:24:00 +02:00
if ! runSteps [ checkStepActiveOptions . stageName ] [ checkStepActiveOptions . stepName ] {
2021-07-26 07:47:43 +02:00
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" )
2021-11-18 08:24:00 +02:00
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" )
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" )
2021-07-26 07:47:43 +02:00
cmd . MarkFlagRequired ( "step" )
}
func initializeConfig ( pConfig * config . Config ) ( * config . Config , error ) {
projectConfigFile := getProjectConfigFile ( GeneralConfig . CustomConfig )
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 ( )
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 { } ,
}
2021-12-15 16:07:47 +02:00
_ , err = pConfig . GetStepConfig ( flags , "" , customConfig , defaultConfig , GeneralConfig . IgnoreCustomDefaults , filter , config . StepData { } , nil , "" , "" )
2021-07-26 07:47:43 +02:00
if err != nil {
return nil , errors . Wrap ( err , "getting step config failed" )
}
return pConfig , nil
}