github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/cmd/shellExecute.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "os/exec" 6 "strings" 7 8 "github.com/pkg/errors" 9 10 "github.com/SAP/jenkins-library/pkg/command" 11 piperhttp "github.com/SAP/jenkins-library/pkg/http" 12 "github.com/SAP/jenkins-library/pkg/log" 13 "github.com/SAP/jenkins-library/pkg/piperutils" 14 "github.com/SAP/jenkins-library/pkg/telemetry" 15 ) 16 17 type shellExecuteUtils interface { 18 command.ExecRunner 19 piperutils.FileUtils 20 piperhttp.Downloader 21 } 22 23 type shellExecuteUtilsBundle struct { 24 *command.Command 25 *piperutils.Files 26 *piperhttp.Client 27 } 28 29 const ( 30 argumentDelimter = "," 31 ) 32 33 func newShellExecuteUtils() shellExecuteUtils { 34 utils := shellExecuteUtilsBundle{ 35 Command: &command.Command{}, 36 Files: &piperutils.Files{}, 37 Client: &piperhttp.Client{}, 38 } 39 utils.Stdout(log.Writer()) 40 utils.Stderr(log.Writer()) 41 return &utils 42 } 43 44 func shellExecute(config shellExecuteOptions, telemetryData *telemetry.CustomData) { 45 utils := newShellExecuteUtils() 46 47 err := runShellExecute(&config, telemetryData, utils) 48 if err != nil { 49 log.Entry().WithError(err).Fatal("step execution failed") 50 } 51 } 52 53 func runShellExecute(config *shellExecuteOptions, telemetryData *telemetry.CustomData, utils shellExecuteUtils) error { 54 // check input data 55 // example for script: sources: ["./script.sh"] 56 for position, source := range config.Sources { 57 58 if strings.Contains(source, "https") { 59 scriptLocation, err := piperhttp.DownloadExecutable(config.GithubToken, utils, utils, source) 60 if err != nil { 61 return errors.Wrapf(err, "script download error") 62 } 63 source = scriptLocation 64 } 65 // check if the script is physically present 66 exists, err := utils.FileExists(source) 67 if err != nil { 68 log.Entry().WithError(err).Error("failed to check for defined script") 69 return fmt.Errorf("failed to check for defined script: %w", err) 70 } 71 if !exists { 72 log.Entry().WithError(err).Errorf("the script '%v' could not be found: %v", source, err) 73 return fmt.Errorf("the script '%v' could not be found", source) 74 } 75 76 args := []string{} 77 if len(config.ScriptArguments) > 0 && isArgumentAtPosition(config.ScriptArguments, position) { 78 args = strings.Split(config.ScriptArguments[position], argumentDelimter) 79 } 80 81 log.Entry().Info("starting running script:", source) 82 83 err = utils.RunExecutable(source, args...) 84 if err != nil { 85 log.Entry().Errorln("starting running script:", source) 86 } 87 // handle exit code 88 if ee, ok := err.(*exec.ExitError); ok { 89 switch ee.ExitCode() { 90 case 0: 91 // success 92 return nil 93 case 1: 94 return errors.Wrap(err, "an error occurred while executing the script") 95 default: 96 // exit code 2 or >2 - unstable 97 return errors.Wrap(err, "script execution unstable or something went wrong") 98 } 99 } else if err != nil { 100 return errors.Wrap(err, "script execution error occurred") 101 } 102 } 103 104 return nil 105 } 106 107 func isArgumentAtPosition(scriptArguments []string, index int) bool { 108 return ((len(scriptArguments) > index) && scriptArguments[index] != "") 109 }