github.com/jenkins-x/jx/v2@v2.1.155/pkg/cmd/step/create/pr/step_create_pr_quickstarts.go (about) 1 package pr 2 3 import ( 4 "fmt" 5 6 v1 "github.com/jenkins-x/jx-api/pkg/apis/jenkins.io/v1" 7 "github.com/jenkins-x/jx-logging/pkg/log" 8 "github.com/jenkins-x/jx/v2/pkg/auth" 9 "github.com/jenkins-x/jx/v2/pkg/cmd/opts/step" 10 "github.com/jenkins-x/jx/v2/pkg/config" 11 "github.com/jenkins-x/jx/v2/pkg/gits/operations" 12 "github.com/jenkins-x/jx/v2/pkg/quickstarts" 13 "github.com/jenkins-x/jx/v2/pkg/util" 14 "github.com/jenkins-x/jx/v2/pkg/versionstream" 15 16 "github.com/jenkins-x/jx/v2/pkg/gits" 17 "github.com/pkg/errors" 18 19 "github.com/jenkins-x/jx/v2/pkg/cmd/helper" 20 21 "github.com/jenkins-x/jx/v2/pkg/cmd/opts" 22 "github.com/jenkins-x/jx/v2/pkg/cmd/templates" 23 "github.com/spf13/cobra" 24 ) 25 26 var ( 27 createPullRequestQuickStartsLong = templates.LongDesc(` 28 Creates a Pull Request a version stream to include all the quickstarts found in a github organisation 29 `) 30 31 createPullRequestQuickStartsExample = templates.Examples(` 32 `) 33 ) 34 35 // StepCreatePullRequestQuickStartsOptions contains the command line flags 36 type StepCreatePullRequestQuickStartsOptions struct { 37 StepCreatePrOptions 38 39 Location v1.QuickStartLocation 40 } 41 42 // NewCmdStepCreatePullRequestQuickStarts Creates a new Command object 43 func NewCmdStepCreatePullRequestQuickStarts(commonOpts *opts.CommonOptions) *cobra.Command { 44 options := &StepCreatePullRequestQuickStartsOptions{ 45 StepCreatePrOptions: StepCreatePrOptions{ 46 StepCreateOptions: step.StepCreateOptions{ 47 StepOptions: step.StepOptions{ 48 CommonOptions: commonOpts, 49 }, 50 }, 51 }, 52 } 53 54 cmd := &cobra.Command{ 55 Use: "quickstarts", 56 Short: "Creates a Pull Request on a version stream to include all the quickstarts found in a github organisation", 57 Long: createPullRequestQuickStartsLong, 58 Example: createPullRequestQuickStartsExample, 59 Aliases: []string{"quickstart", "qs"}, 60 Run: func(cmd *cobra.Command, args []string) { 61 options.Cmd = cmd 62 options.Args = args 63 err := options.Run() 64 helper.CheckErr(err) 65 }, 66 } 67 cmd.Flags().StringVarP(&options.Location.Owner, "owner", "n", "jenkins-x-quickstarts", "The name of the git owner (user or organisation) to query for quickstart git repositories") 68 cmd.Flags().StringVarP(&options.Location.GitKind, "git-kind", "k", "github", "The kind of git provider") 69 cmd.Flags().StringVarP(&options.Location.GitURL, "git-server", "", "https://github.com", "The git server to find the quickstarts") 70 cmd.Flags().StringArrayVarP(&options.Location.Includes, "filter", "f", []string{"*"}, "The name patterns to include - such as '*' for all names") 71 cmd.Flags().StringArrayVarP(&options.Location.Excludes, "excludes", "x", []string{"WIP-*"}, "The name patterns to exclude") 72 AddStepCreatePrFlags(cmd, &options.StepCreatePrOptions) 73 return cmd 74 } 75 76 // ValidateQuickStartsOptions validates the common options for quickStarts pr steps 77 func (o *StepCreatePullRequestQuickStartsOptions) ValidateQuickStartsOptions() error { 78 if len(o.GitURLs) == 0 { 79 // Default in the versions repo 80 o.GitURLs = []string{config.DefaultVersionsURL} 81 } 82 if err := o.ValidateOptions(true); err != nil { 83 return errors.WithStack(err) 84 } 85 return nil 86 } 87 88 // Run implements this command 89 func (o *StepCreatePullRequestQuickStartsOptions) Run() error { 90 authConfig := auth.NewMemoryAuthConfigService() 91 model, err := o.LoadQuickStartsFromLocations([]v1.QuickStartLocation{o.Location}, authConfig.Config()) 92 if err != nil { 93 return fmt.Errorf("failed to load quickstarts: %s", err) 94 } 95 96 found := model.Quickstarts 97 if len(found) == 0 { 98 log.Logger().Warnf("did not find any quickstarts for the location %#v", o.Location) 99 return nil 100 } 101 102 for _, q := range model.Quickstarts { 103 o.SrcGitURL = o.sourceGitURL(q) 104 break 105 } 106 107 if err := o.ValidateQuickStartsOptions(); err != nil { 108 return errors.WithStack(err) 109 } 110 111 type Change struct { 112 Pro operations.PullRequestOperation 113 QuickStart quickstarts.Quickstart 114 ChangeFn func(from *quickstarts.Quickstart, dir string, gitInfo *gits.GitRepository) ([]string, error) 115 } 116 117 modifyFns := []Change{} 118 for _, name := range model.SortedNames() { 119 q := model.Quickstarts[name] 120 if q == nil { 121 continue 122 } 123 version := q.Version 124 o.SrcGitURL = o.sourceGitURL(q) 125 126 pro := operations.PullRequestOperation{ 127 CommonOptions: o.CommonOptions, 128 GitURLs: o.GitURLs, 129 SrcGitURL: o.SrcGitURL, 130 Base: o.Base, 131 BranchName: o.BranchName, 132 Version: version, 133 DryRun: o.DryRun, 134 } 135 136 authorName, authorEmail, err := gits.EnsureUserAndEmailSetup(o.Git()) 137 if err != nil { 138 pro.AuthorName = authorName 139 pro.AuthorEmail = authorEmail 140 } 141 callback := func(from *quickstarts.Quickstart, dir string, gitInfo *gits.GitRepository) ([]string, error) { 142 quickstarts, err := versionstream.GetQuickStarts(dir) 143 if err != nil { 144 return nil, errors.Wrapf(err, "loading quickstarts from version stream in dir %s", dir) 145 } 146 if quickstarts.DefaultOwner == "" { 147 quickstarts.DefaultOwner = o.Location.Owner 148 } 149 o.upsertQuickStart(from, quickstarts) 150 err = versionstream.SaveQuickStarts(dir, quickstarts) 151 if err != nil { 152 return nil, errors.Wrapf(err, "saving quickstarts to the version stream in dir %s", dir) 153 } 154 return nil, nil 155 } 156 157 modifyFns = append(modifyFns, Change{ 158 QuickStart: *q, 159 ChangeFn: callback, 160 Pro: pro, 161 }) 162 } 163 164 o.SrcGitURL = "" // there is no src url for the overall PR 165 o.SkipCommit = true // As we've done all the commits already 166 return o.CreatePullRequest("versionstream", func(dir string, gitInfo *gits.GitRepository) ([]string, error) { 167 for _, fn := range modifyFns { 168 changeFn := fn.Pro.WrapChangeFilesWithCommitFn("quickstart", func(dir string, gitInfo *gits.GitRepository) ([]string, error) { 169 return fn.ChangeFn(&fn.QuickStart, dir, gitInfo) 170 }) 171 _, err := changeFn(dir, gitInfo) 172 if err != nil { 173 return nil, errors.WithStack(err) 174 } 175 } 176 return nil, nil 177 }) 178 } 179 180 func (o *StepCreatePullRequestQuickStartsOptions) upsertQuickStart(from *quickstarts.Quickstart, qs *versionstream.QuickStarts) { 181 upsert := func(from *quickstarts.Quickstart, to *versionstream.QuickStart) { 182 if to.Name == "" { 183 to.Name = from.Name 184 } 185 if from.Version != "" { 186 to.Version = from.Version 187 } 188 if from.DownloadZipURL != "" { 189 to.DownloadZipURL = from.DownloadZipURL 190 } 191 if from.Language != "" { 192 to.Language = from.Language 193 } 194 if from.Framework != "" { 195 to.Framework = from.Framework 196 } 197 if len(from.Tags) == 0 { 198 to.Tags = from.Tags 199 } 200 } 201 found := false 202 for _, to := range qs.QuickStarts { 203 if from.Name == to.Name { 204 if from.Owner == to.Owner || (from.Owner == qs.DefaultOwner && to.Owner == "") { 205 upsert(from, to) 206 found = true 207 } 208 209 } 210 } 211 if !found { 212 to := &versionstream.QuickStart{} 213 upsert(from, to) 214 qs.QuickStarts = append(qs.QuickStarts, to) 215 216 // lets sort the quickstarts in name order 217 qs.Sort() 218 } 219 } 220 221 func (o *StepCreatePullRequestQuickStartsOptions) sourceGitURL(qs *quickstarts.Quickstart) string { 222 owner := qs.Owner 223 if owner == "" { 224 owner = o.Location.Owner 225 } 226 return util.UrlJoin(o.Location.GitURL, owner, qs.Name) + ".git" 227 }