github.com/gopinath-langote/1build@v1.7.0/cmd/exec/exec.go (about) 1 package exec 2 3 import ( 4 "fmt" 5 "os" 6 "time" 7 8 "github.com/codeskyblue/go-sh" 9 "github.com/gopinath-langote/1build/cmd/config" 10 "github.com/gopinath-langote/1build/cmd/models" 11 "github.com/gopinath-langote/1build/cmd/utils" 12 "github.com/spf13/viper" 13 ) 14 15 // ExecutePlan executes the Execution plan 16 func ExecutePlan(commands ...string) { 17 18 executeStart := time.Now() 19 20 configuration, err := config.LoadOneBuildConfiguration() 21 if err != nil { 22 fmt.Println(err) 23 return 24 } 25 26 executionPlan := buildExecutionPlan(configuration, commands...) 27 executionPlan.Print() 28 29 if executionPlan.HasBefore() { 30 executeAndStopIfFailed(executionPlan.Before, executeStart) 31 } 32 33 if executionPlan.HasCommands() { 34 for _, commandContext := range executionPlan.Commands { 35 executeAndStopIfFailed(commandContext, executeStart) 36 } 37 } 38 39 if executionPlan.HasAfter() { 40 executeAndStopIfFailed(executionPlan.After, executeStart) 41 } 42 43 printResultsBanner(true, executeStart) 44 } 45 46 func executeAndStopIfFailed(command *models.CommandContext, executeStart time.Time) { 47 command.PrintPhaseBanner() 48 if !viper.GetBool("quiet") { 49 session := command.CommandSession 50 session.SetStdin(os.Stdin) 51 err := session.Run() 52 if err != nil { 53 exitCode := (err.Error())[12:] 54 text := "\nExecution failed in phase '" + command.Name + "' – exit code: " + exitCode 55 utils.CPrintln(text, utils.Style{Color: utils.RED}) 56 printResultsBanner(false, executeStart) 57 utils.ExitWithCode(exitCode) 58 } 59 } else { 60 _, err := command.CommandSession.CombinedOutput() 61 if err != nil { 62 exitCode := (err.Error())[12:] 63 printResultsBanner(false, executeStart) 64 utils.ExitWithCode(exitCode) 65 } 66 } 67 68 } 69 70 func buildExecutionPlan(config config.OneBuildConfiguration, commands ...string) models.OneBuildExecutionPlan { 71 72 before := config.Before 73 var executionPlan models.OneBuildExecutionPlan 74 if before != "" { 75 executionPlan.Before = &models.CommandContext{ 76 Name: "before", Command: before, CommandSession: bashCommand(sh.NewSession(), before)} 77 } 78 79 for _, name := range commands { 80 executionCommand := config.GetCommand(name) 81 if executionCommand == "" { 82 utils.CPrintln("\nError building execution plan. Command \""+name+"\" not found.", 83 utils.Style{Color: utils.RED, Bold: true}) 84 config.Print() 85 utils.ExitWithCode("127") 86 } 87 executionPlan.Commands = append(executionPlan.Commands, &models.CommandContext{ 88 Name: name, Command: executionCommand, CommandSession: bashCommand(sh.NewSession(), executionCommand)}) 89 } 90 91 after := config.After 92 if after != "" { 93 executionPlan.After = &models.CommandContext{ 94 Name: "after", Command: after, CommandSession: bashCommand(sh.NewSession(), after)} 95 } 96 97 return executionPlan 98 } 99 100 func bashCommand(s *sh.Session, command string) *sh.Session { 101 configFileAbsoluteDir, _ := config.GetAbsoluteDirPathOfConfigFile() 102 s.SetDir(configFileAbsoluteDir) 103 return s.Command("bash", "-c", command) 104 } 105 106 // PrintResultsBanner prints result banner at the end of the test 107 func printResultsBanner(isSuccess bool, startTime time.Time) { 108 timeDelta := time.Since(startTime) 109 minutes := int64(timeDelta.Minutes()) 110 secs := int64(timeDelta.Seconds()) % 60 111 var timeStr string 112 if minutes == 0 { 113 timeStr = fmt.Sprintf("%.2ds", secs) 114 } else { 115 timeStr = fmt.Sprintf("%.2dm %.2ds", minutes, secs) 116 } 117 fmt.Println() 118 fmt.Println(utils.Dash()) 119 if isSuccess { 120 utils.CPrint("SUCCESS", utils.Style{Color: utils.CYAN, Bold: true}) 121 } else { 122 utils.CPrint("FAILURE", utils.Style{Color: utils.RED, Bold: true}) 123 } 124 fmt.Println(fmt.Sprintf(" - Total Time: %s", timeStr)) 125 fmt.Println(utils.Dash()) 126 }