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  }