github.com/jfrog/frogbot@v1.1.1-0.20231221090046-821a26f50338/commands.go (about)

     1  package main
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  
     8  	"github.com/jfrog/frogbot/scanpullrequest"
     9  	"github.com/jfrog/frogbot/scanrepository"
    10  	"github.com/jfrog/frogbot/utils"
    11  	"github.com/jfrog/frogbot/utils/outputwriter"
    12  	"github.com/jfrog/froggit-go/vcsclient"
    13  	"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
    14  	"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
    15  	"github.com/jfrog/jfrog-client-go/utils/log"
    16  	clitool "github.com/urfave/cli/v2"
    17  )
    18  
    19  type FrogbotCommand interface {
    20  	// Run the command
    21  	Run(config utils.RepoAggregator, client vcsclient.VcsClient, frogbotRepoConnection *utils.UrlAccessChecker) error
    22  }
    23  
    24  func GetCommands() []*clitool.Command {
    25  	return []*clitool.Command{
    26  		{
    27  			Name:    utils.ScanPullRequest,
    28  			Aliases: []string{"spr"},
    29  			Usage:   "Scans a pull request with JFrog Xray for security vulnerabilities.",
    30  			Action: func(ctx *clitool.Context) error {
    31  				return Exec(&scanpullrequest.ScanPullRequestCmd{}, ctx.Command.Name)
    32  			},
    33  			Flags: []clitool.Flag{},
    34  		},
    35  		{
    36  			Name:    utils.ScanRepository,
    37  			Aliases: []string{"cfpr", "create-fix-pull-requests"},
    38  			Usage:   "Scan the current branch and create pull requests with fixes if needed",
    39  			Action: func(ctx *clitool.Context) error {
    40  				return Exec(&scanrepository.ScanRepositoryCmd{}, ctx.Command.Name)
    41  			},
    42  			Flags: []clitool.Flag{},
    43  		},
    44  		{
    45  			Name:    utils.ScanAllPullRequests,
    46  			Aliases: []string{"sprs", "scan-pull-requests"},
    47  			Usage:   "Scans all the open pull requests within a single or multiple repositories with JFrog Xray for security vulnerabilities",
    48  			Action: func(ctx *clitool.Context) error {
    49  				return Exec(&scanpullrequest.ScanAllPullRequestsCmd{}, ctx.Command.Name)
    50  			},
    51  			Flags: []clitool.Flag{},
    52  		},
    53  		{
    54  			Name:    utils.ScanMultipleRepositories,
    55  			Aliases: []string{"scan-and-fix-repos", "safr"},
    56  			Usage:   "Scan single or multiple repositories and create pull requests with fixes if any security vulnerabilities are found",
    57  			Action: func(ctx *clitool.Context) error {
    58  				return Exec(&scanrepository.ScanMultipleRepositories{}, ctx.Command.Name)
    59  			},
    60  			Flags: []clitool.Flag{},
    61  		},
    62  	}
    63  }
    64  
    65  func Exec(command FrogbotCommand, commandName string) (err error) {
    66  	// Get frogbotDetails that contains the config, server, and VCS client
    67  	log.Info("Frogbot version:", utils.FrogbotVersion)
    68  	frogbotDetails, err := utils.GetFrogbotDetails(commandName)
    69  	if err != nil {
    70  		return err
    71  	}
    72  	// Check if the user has access to the frogbot repository (to access the resources needed)
    73  	frogbotRepoConnection := utils.CheckConnection(outputwriter.FrogbotRepoUrl)
    74  
    75  	// Build the server configuration file
    76  	originalJfrogHomeDir, tempJFrogHomeDir, err := utils.BuildServerConfigFile(frogbotDetails.ServerDetails)
    77  	if err != nil {
    78  		return err
    79  	}
    80  	defer func() {
    81  		err = errors.Join(err, os.Setenv(utils.JfrogHomeDirEnv, originalJfrogHomeDir), fileutils.RemoveTempDir(tempJFrogHomeDir))
    82  	}()
    83  
    84  	// Set releases remote repository env if needed
    85  	previousReleasesRepoEnv := os.Getenv(coreutils.ReleasesRemoteEnv)
    86  	if frogbotDetails.ReleasesRepo != "" {
    87  		if err = os.Setenv(coreutils.ReleasesRemoteEnv, fmt.Sprintf("frogbot/%s", frogbotDetails.ReleasesRepo)); err != nil {
    88  			return
    89  		}
    90  		defer func() {
    91  			err = errors.Join(err, os.Setenv(coreutils.ReleasesRemoteEnv, previousReleasesRepoEnv))
    92  		}()
    93  	}
    94  
    95  	// Send a usage report
    96  	waitForUsageResponse := utils.ReportUsageOnCommand(commandName, frogbotDetails.ServerDetails, frogbotDetails.Repositories)
    97  
    98  	// Invoke the command interface
    99  	log.Info(fmt.Sprintf("Running Frogbot %q command", commandName))
   100  	err = command.Run(frogbotDetails.Repositories, frogbotDetails.GitClient, frogbotRepoConnection)
   101  
   102  	// Wait for usage reporting to finish.
   103  	waitForUsageResponse()
   104  
   105  	if err == nil {
   106  		log.Info(fmt.Sprintf("Frogbot %q command finished successfully", commandName))
   107  	}
   108  	return err
   109  }