2022-08-23 19:38:41 +00:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/AlecAivazis/survey/v2"
|
|
|
|
"github.com/go-git/go-git/v5"
|
|
|
|
"github.com/go-git/go-git/v5/plumbing/object"
|
|
|
|
"github.com/peterbourgon/ff/v3/ffcli"
|
|
|
|
)
|
|
|
|
|
2022-09-03 21:58:02 +00:00
|
|
|
func (h *Handler) Frontport() *ffcli.Command {
|
|
|
|
fs := flag.NewFlagSet("frontport", flag.ContinueOnError)
|
2022-12-27 03:01:50 +00:00
|
|
|
fromFlag := fs.String("from", "", "Release to frontport from (ex: `17`, default: <latest>)")
|
2022-09-03 21:58:02 +00:00
|
|
|
fs.StringVar(fromFlag, "f", *fromFlag, "--from")
|
|
|
|
toFlag := fs.String("to", "", "Release to frontport to (ex: `main`, default: `main`)")
|
|
|
|
fs.StringVar(toFlag, "t", *toFlag, "--to")
|
2023-01-24 04:41:10 +00:00
|
|
|
pushFlag := fs.Bool("push", false, "Push immediately")
|
|
|
|
fs.BoolVar(pushFlag, "p", *pushFlag, "--push")
|
2022-09-03 21:58:02 +00:00
|
|
|
return &ffcli.Command{
|
2022-08-23 19:38:41 +00:00
|
|
|
Name: "frontport",
|
2022-09-03 21:58:02 +00:00
|
|
|
FlagSet: fs,
|
2022-08-30 18:58:49 +00:00
|
|
|
ShortUsage: "frontport --from [release=latest] --to [release=main]",
|
2022-09-03 21:58:02 +00:00
|
|
|
ShortHelp: "frontport cherry-picks a commit and applies it to a clean branch based on `release`",
|
2022-08-30 18:58:49 +00:00
|
|
|
Exec: func(ctx context.Context, _ []string) error {
|
2022-09-03 21:58:02 +00:00
|
|
|
if err := h.checkInit(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
from := *fromFlag
|
2022-08-30 18:58:49 +00:00
|
|
|
if from == "" {
|
2022-09-03 21:58:02 +00:00
|
|
|
from = h.latestRelease()
|
2022-08-23 19:38:41 +00:00
|
|
|
}
|
|
|
|
if !strings.HasPrefix(from, "release") {
|
2022-08-30 18:58:49 +00:00
|
|
|
from = fmt.Sprintf("release/v%s", from)
|
2022-08-23 19:38:41 +00:00
|
|
|
}
|
|
|
|
|
2022-09-03 21:58:02 +00:00
|
|
|
h.fetch(ctx)
|
2022-08-23 19:38:41 +00:00
|
|
|
|
2022-09-03 21:58:02 +00:00
|
|
|
commits, err := h.repo().Log(&git.LogOptions{
|
|
|
|
From: h.head(from),
|
2022-08-23 19:38:41 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-12-27 03:01:50 +00:00
|
|
|
optMap := make(map[string]string)
|
2022-08-23 19:38:41 +00:00
|
|
|
var opts []string
|
|
|
|
if err := commits.ForEach(func(c *object.Commit) error {
|
|
|
|
title := strings.Split(c.Message, "\n")[0]
|
|
|
|
opts = append(opts, title)
|
2022-12-27 03:01:50 +00:00
|
|
|
optMap[title] = c.Hash.String()
|
2022-08-23 19:38:41 +00:00
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var resp string
|
|
|
|
if err := survey.AskOne(&survey.Select{
|
|
|
|
Message: "Commit to cherry-pick",
|
|
|
|
Options: opts,
|
|
|
|
}, &resp, survey.WithValidator(survey.Required)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-12-27 03:01:50 +00:00
|
|
|
index := optMap[resp]
|
|
|
|
m := indexRe.FindStringSubmatch(resp)
|
|
|
|
if m != nil {
|
|
|
|
index = m[1]
|
|
|
|
}
|
|
|
|
|
2023-01-11 03:57:47 +00:00
|
|
|
branch := fmt.Sprintf("frontport-%s-%s", from, index)
|
2022-08-30 18:58:49 +00:00
|
|
|
|
2022-09-03 21:58:02 +00:00
|
|
|
base := *toFlag
|
2022-08-30 18:58:49 +00:00
|
|
|
if base == "" {
|
|
|
|
base = "upstream/main"
|
|
|
|
}
|
|
|
|
if !strings.HasPrefix(base, "upstream") {
|
|
|
|
base = fmt.Sprintf("upstream/release/v1.%s", base)
|
2022-08-23 19:38:41 +00:00
|
|
|
}
|
2022-09-03 21:58:02 +00:00
|
|
|
if err := h.Branch().ParseAndRun(ctx, []string{branch, base}); err != nil {
|
2022-08-23 19:38:41 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-01-24 04:41:10 +00:00
|
|
|
if err := run(ctx, h.Config.WorkspaceBranch(branch), "git", "cherry-pick", optMap[resp]); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if *pushFlag {
|
|
|
|
return run(ctx, h.Config.WorkspaceBranch(branch), "git", "push", "origin", "HEAD")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2022-08-23 19:38:41 +00:00
|
|
|
},
|
|
|
|
}
|
2022-09-03 21:58:02 +00:00
|
|
|
}
|