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  }