github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/cmd/step/create/pr/step_create_pr_go.go (about) 1 package pr 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/olli-ai/jx/v2/pkg/cmd/opts/step" 8 9 "github.com/olli-ai/jx/v2/pkg/gits/operations" 10 11 "github.com/olli-ai/jx/v2/pkg/gits" 12 "github.com/pkg/errors" 13 14 "github.com/jenkins-x/jx-logging/pkg/log" 15 "github.com/olli-ai/jx/v2/pkg/cmd/helper" 16 "github.com/olli-ai/jx/v2/pkg/cmd/opts" 17 "github.com/olli-ai/jx/v2/pkg/cmd/templates" 18 "github.com/olli-ai/jx/v2/pkg/util" 19 "github.com/spf13/cobra" 20 ) 21 22 var ( 23 createtPullRequestGoLong = templates.LongDesc(` 24 Creates a Pull Request to change a go module dependency, updating the go.mod and go.sum files to use a new version 25 26 Files named Makefile or Makefile.* will be updated 27 `) 28 29 createtPullRequestGoExample = templates.Examples(` 30 # update a go dependency 31 jx step create pr go --name github.com/myorg/myrepo --version v1.2.3 --repo https://github.com/jenkins-x/cloud-environments.git 32 33 # update a go dependency using a custom build step (to update the 'go.sum' file) 34 jx step create pr go --name github.com/myorg/myrepo --version v1.2.3 --build "make something" --repo https://github.com/jenkins-x/cloud-environments.git 35 `) 36 ) 37 38 // StepCreatetPullRequestGoOptions contains the command line flags 39 type StepCreatetPullRequestGoOptions struct { 40 StepCreatePrOptions 41 42 Name string 43 BuildCommand string 44 FailOnBuild bool 45 } 46 47 // NewCmdStepCreatePullRequestGo Creates a new Command object 48 func NewCmdStepCreatePullRequestGo(commonOpts *opts.CommonOptions) *cobra.Command { 49 options := &StepCreatetPullRequestGoOptions{ 50 StepCreatePrOptions: StepCreatePrOptions{ 51 StepCreateOptions: step.StepCreateOptions{ 52 StepOptions: step.StepOptions{ 53 CommonOptions: commonOpts, 54 }, 55 }, 56 }, 57 } 58 59 cmd := &cobra.Command{ 60 Use: "go", 61 Short: "Creates a Pull Request on a git repository updating a go module dependency", 62 Long: createtPullRequestGoLong, 63 Example: createtPullRequestGoExample, 64 Aliases: []string{"golang"}, 65 Run: func(cmd *cobra.Command, args []string) { 66 options.Cmd = cmd 67 options.Args = args 68 err := options.Run() 69 helper.CheckErr(err) 70 }, 71 } 72 AddStepCreatePrFlags(cmd, &options.StepCreatePrOptions) 73 cmd.Flags().StringVarP(&options.Name, "name", "", "", "The name of the go module dependency to use when doing updates") 74 cmd.Flags().StringVarP(&options.BuildCommand, "build", "", "make build", "The build command to update the 'go.sum' file after the change to the source") 75 cmd.Flags().BoolVarP(&options.FailOnBuild, "fail-on-build", "", false, "Should we fail to create the Pull Request if the build command fails. Its common for incompatible changes to the go code to fail to build so we usually want to go ahead with the Pull Request anyway") 76 return cmd 77 } 78 79 // ValidateGoOptions validates the common options for make pr steps 80 func (o *StepCreatetPullRequestGoOptions) ValidateGoOptions() error { 81 if err := o.ValidateOptions(false); err != nil { 82 return errors.WithStack(err) 83 } 84 if o.Name == "" { 85 return util.MissingOption("name") 86 } 87 if o.SrcGitURL == "" { 88 log.Logger().Warnf("srcRepo is not provided so generated PR will not be correctly linked in release notesPR") 89 } 90 91 return nil 92 } 93 94 // Run implements this command 95 func (o *StepCreatetPullRequestGoOptions) Run() error { 96 // lets make sure the version starts with a v for go style version tags 97 if !strings.HasPrefix(o.Version, "v") { 98 o.Version = "v" + o.Version 99 } 100 if err := o.ValidateGoOptions(); err != nil { 101 return errors.WithStack(err) 102 } 103 regex := fmt.Sprintf(`(?m)^\s*\Q%s\E\s+(?P<version>.+)`, o.Name) 104 regexFn, err := operations.CreatePullRequestRegexFn(o.Version, regex, "go.mod") 105 if err != nil { 106 return errors.WithStack(err) 107 } 108 fn := func(dir string, gitInfo *gits.GitRepository) ([]string, error) { 109 answer, err := regexFn(dir, gitInfo) 110 if err != nil { 111 return nil, errors.WithStack(err) 112 } 113 err = o.runGoBuild(dir) 114 if err != nil { 115 log.Logger().Errorf("failed to run build after modifying go.mod") 116 return nil, errors.WithStack(err) 117 } 118 return answer, nil 119 } 120 err = o.CreatePullRequest("go", fn) 121 if err != nil { 122 return errors.WithStack(err) 123 } 124 return nil 125 } 126 127 func (o *StepCreatetPullRequestGoOptions) runGoBuild(dir string) error { 128 build := o.BuildCommand 129 if build == "" { 130 log.Logger().Warn("no build command so we will not change the 'go.sum' command") 131 return nil 132 } 133 log.Logger().Infof("running the build command: %s in the directory %s to update the 'go.sum' file\n", util.ColorInfo(build), dir) 134 135 values := strings.Split(build, " ") 136 cmd := util.Command{ 137 Dir: dir, 138 Name: values[0], 139 Args: values[1:], 140 } 141 _, err := cmd.RunWithoutRetry() 142 if err != nil { 143 if o.FailOnBuild { 144 return errors.Wrapf(err, "running %s", cmd.String()) 145 } 146 log.Logger().Warnf("failed to run %s so the Pull Request will probably need some manual work to make it pass the CI tests. Failure: %s", cmd.String(), err.Error()) 147 } 148 return nil 149 }