github.com/SAP/jenkins-library@v1.362.0/cmd/abapEnvironmentCheckoutBranch.go (about)

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"time"
     7  
     8  	"github.com/SAP/jenkins-library/pkg/abaputils"
     9  	"github.com/SAP/jenkins-library/pkg/command"
    10  	piperhttp "github.com/SAP/jenkins-library/pkg/http"
    11  	"github.com/SAP/jenkins-library/pkg/log"
    12  	"github.com/SAP/jenkins-library/pkg/telemetry"
    13  	"github.com/pkg/errors"
    14  )
    15  
    16  func abapEnvironmentCheckoutBranch(options abapEnvironmentCheckoutBranchOptions, _ *telemetry.CustomData) {
    17  
    18  	// for command execution use Command
    19  	c := command.Command{}
    20  	// reroute command output to logging framework
    21  	c.Stdout(log.Writer())
    22  	c.Stderr(log.Writer())
    23  
    24  	var autils = abaputils.AbapUtils{
    25  		Exec: &c,
    26  	}
    27  
    28  	apiManager := abaputils.SoftwareComponentApiManager{
    29  		Client:        &piperhttp.Client{},
    30  		PollIntervall: 5 * time.Second,
    31  	}
    32  
    33  	// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end
    34  	err := runAbapEnvironmentCheckoutBranch(&options, &autils, &apiManager)
    35  	if err != nil {
    36  		log.Entry().WithError(err).Fatal("step execution failed")
    37  	}
    38  }
    39  
    40  func runAbapEnvironmentCheckoutBranch(options *abapEnvironmentCheckoutBranchOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) {
    41  
    42  	// Mapping for options
    43  	subOptions := convertCheckoutConfig(options)
    44  
    45  	//  Determine the host, user and password, either via the input parameters or via a cloud foundry service key
    46  	connectionDetails, errorGetInfo := com.GetAbapCommunicationArrangementInfo(subOptions, "")
    47  	if errorGetInfo != nil {
    48  		log.Entry().WithError(errorGetInfo).Fatal("Parameters for the ABAP Connection not available")
    49  	}
    50  	connectionDetails.CertificateNames = options.CertificateNames
    51  
    52  	repositories := []abaputils.Repository{}
    53  	err = checkCheckoutBranchRepositoryConfiguration(*options)
    54  	if err != nil {
    55  		return errors.Wrap(err, "Configuration is not consistent")
    56  	}
    57  	repositories, err = abaputils.GetRepositories(&abaputils.RepositoriesConfig{BranchName: options.BranchName, RepositoryName: options.RepositoryName, Repositories: options.Repositories}, true)
    58  	if err != nil {
    59  		return errors.Wrap(err, "Could not read repositories")
    60  	}
    61  	err = checkoutBranches(repositories, connectionDetails, apiManager)
    62  	if err != nil {
    63  		return fmt.Errorf("Something failed during the checkout: %w", err)
    64  	}
    65  	log.Entry().Infof("-------------------------")
    66  	log.Entry().Info("All branches were checked out successfully")
    67  	return nil
    68  }
    69  
    70  func checkoutBranches(repositories []abaputils.Repository, checkoutConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) {
    71  	log.Entry().Infof("Start switching %v branches", len(repositories))
    72  	for _, repo := range repositories {
    73  		err = handleCheckout(repo, checkoutConnectionDetails, apiManager)
    74  		if err != nil {
    75  			break
    76  		}
    77  	}
    78  	return err
    79  }
    80  
    81  func checkCheckoutBranchRepositoryConfiguration(options abapEnvironmentCheckoutBranchOptions) error {
    82  	if options.Repositories == "" && options.RepositoryName == "" && options.BranchName == "" {
    83  		return errors.New("You have not specified any repository or branch configuration to be checked out in the ABAP Environment System. Please make sure that you specified the repositories with their branches that should be checked out either in a dedicated file or via the parameters 'repositoryName' and 'branchName'. For more information please read the user documentation")
    84  	}
    85  	if options.Repositories != "" && options.RepositoryName != "" && options.BranchName != "" {
    86  		log.Entry().Info("It seems like you have specified repositories directly via the configuration parameters 'repositoryName' and 'branchName' as well as in the dedicated repositories configuration file. Please note that in this case both configurations will be handled and checked out.")
    87  	}
    88  	if options.Repositories != "" && ((options.RepositoryName == "") != (options.BranchName == "")) {
    89  		log.Entry().Info("It seems like you have specified a dedicated repository configuration file but also a wrong configuration for the parameters 'repositoryName' and 'branchName' to be checked out.")
    90  		if options.RepositoryName != "" {
    91  			log.Entry().Info("Please also add the value for the branchName parameter or remove the repositoryName parameter.")
    92  		} else {
    93  			log.Entry().Info("Please also add the value for the repositoryName parameter or remove the branchName parameter.")
    94  		}
    95  	}
    96  	return nil
    97  }
    98  
    99  func handleCheckout(repo abaputils.Repository, checkoutConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) {
   100  
   101  	if reflect.DeepEqual(abaputils.Repository{}, repo) {
   102  		return fmt.Errorf("Failed to read repository configuration: %w", errors.New("Error in configuration, most likely you have entered empty or wrong configuration values. Please make sure that you have correctly specified the branches in the repositories to be checked out"))
   103  	}
   104  	startCheckoutLogs(repo.Branch, repo.Name)
   105  
   106  	api, errGetAPI := apiManager.GetAPI(checkoutConnectionDetails, repo)
   107  	if errGetAPI != nil {
   108  		return errors.Wrap(errGetAPI, "Could not initialize the connection to the system")
   109  	}
   110  
   111  	err = api.CheckoutBranch()
   112  	if err != nil {
   113  		return fmt.Errorf("Failed to trigger Checkout: %w", errors.New("Checkout of "+repo.Branch+" for software component "+repo.Name+" failed on the ABAP System"))
   114  	}
   115  
   116  	// Polling the status of the repository import on the ABAP Environment system
   117  	status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall())
   118  	if errorPollEntity != nil {
   119  		return fmt.Errorf("Failed to poll Checkout: %w", errors.New("Status of checkout action on repository"+repo.Name+" failed on the ABAP System"))
   120  	}
   121  	const abapStatusCheckoutFail = "E"
   122  	if status == abapStatusCheckoutFail {
   123  		return fmt.Errorf("Checkout failed: %w", errors.New("Checkout of branch "+repo.Branch+" failed on the ABAP System"))
   124  	}
   125  	finishCheckoutLogs(repo.Branch, repo.Name)
   126  
   127  	return err
   128  }
   129  
   130  func startCheckoutLogs(branchName string, repositoryName string) {
   131  	log.Entry().Infof("Starting to switch branch to branch '%v' on repository '%v'", branchName, repositoryName)
   132  	log.Entry().Infof("-------------------------")
   133  	log.Entry().Info("Start checkout branch: " + branchName)
   134  	log.Entry().Infof("-------------------------")
   135  }
   136  
   137  func finishCheckoutLogs(branchName string, repositoryName string) {
   138  	log.Entry().Infof("-------------------------")
   139  	log.Entry().Infof("Checkout of branch %v on repository %v was successful", branchName, repositoryName)
   140  	log.Entry().Infof("-------------------------")
   141  }
   142  
   143  func convertCheckoutConfig(config *abapEnvironmentCheckoutBranchOptions) abaputils.AbapEnvironmentOptions {
   144  	subOptions := abaputils.AbapEnvironmentOptions{}
   145  
   146  	subOptions.CfAPIEndpoint = config.CfAPIEndpoint
   147  	subOptions.CfServiceInstance = config.CfServiceInstance
   148  	subOptions.CfServiceKeyName = config.CfServiceKeyName
   149  	subOptions.CfOrg = config.CfOrg
   150  	subOptions.CfSpace = config.CfSpace
   151  	subOptions.Host = config.Host
   152  	subOptions.Password = config.Password
   153  	subOptions.Username = config.Username
   154  	return subOptions
   155  }