Skip to content

Commit

Permalink
Use StoryFetcher
Browse files Browse the repository at this point in the history
  • Loading branch information
ClairePhi committed Nov 7, 2024
1 parent d3a5a50 commit 06317a0
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 43 deletions.
5 changes: 3 additions & 2 deletions cmd/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@ import (
"strings"

"github.com/cupcicm/opp/core"
"github.com/cupcicm/opp/core/story"
"github.com/urfave/cli/v2"
)

func MakeApp(out io.Writer, repo *core.Repo, gh func(context.Context) core.Gh) *cli.App {
func MakeApp(out io.Writer, in io.Reader, repo *core.Repo, gh func(context.Context) core.Gh, sf func(string, string) story.StoryFetcher) *cli.App {
return &cli.App{
Name: "opp",
Usage: "Create, update and merge Github pull requests from the command line.",
Commands: []*cli.Command{
InitCommand(repo),
CleanCommand(repo, gh),
CloseCommand(repo, gh),
PrCommand(repo, gh),
PrCommand(in, repo, gh, sf),
MergeCommand(repo, gh),
StatusCommand(out, repo, gh),
RebaseCommand(repo),
Expand Down
18 changes: 10 additions & 8 deletions cmd/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"io"
"sort"
"strings"

Expand Down Expand Up @@ -52,7 +53,7 @@ whether it reached the base branch or the tip of another PR first when walking b
`)
)

func PrCommand(repo *core.Repo, gh func(context.Context) core.Gh) *cli.Command {
func PrCommand(in io.Reader, repo *core.Repo, gh func(context.Context) core.Gh, sf func(string, string) story.StoryFetcher) *cli.Command {
cmd := &cli.Command{
Name: "pr",
Aliases: []string{"pull-request", "new"},
Expand Down Expand Up @@ -90,7 +91,7 @@ func PrCommand(repo *core.Repo, gh func(context.Context) core.Gh) *cli.Command {
if err != nil {
return err
}
pr := create{Repo: repo, Github: gh(cCtx.Context), StoryService: story.NewStoryService()}
pr := create{Repo: repo, Github: gh(cCtx.Context), StoryFetcher: sf}
args, err := pr.SanitizeArgs(cCtx)
if err != nil {
return err
Expand All @@ -103,7 +104,7 @@ func PrCommand(repo *core.Repo, gh func(context.Context) core.Gh) *cli.Command {
}
args = newArgs
}
localPr, err := pr.Create(cCtx.Context, args)
localPr, err := pr.Create(cCtx.Context, in, args)
if err != nil {
return err
}
Expand Down Expand Up @@ -135,7 +136,7 @@ func PrCommand(repo *core.Repo, gh func(context.Context) core.Gh) *cli.Command {
type create struct {
Repo *core.Repo
Github core.Gh
StoryService story.StoryService
StoryFetcher func(string, string) story.StoryFetcher
}

type args struct {
Expand Down Expand Up @@ -311,11 +312,11 @@ func (c *create) RebasePrCommits(ctx context.Context, previousArgs *args) (*args
}, nil
}

func (c *create) Create(ctx context.Context, args *args) (*core.LocalPr, error) {
func (c *create) Create(ctx context.Context, in io.Reader, args *args) (*core.LocalPr, error) {

// The first commit is the child-most one.
lastCommit := args.Commits[0].Hash
title, body, err := c.GetBodyAndTitle(args.Commits)
title, body, err := c.GetBodyAndTitle(ctx, in, args.Commits)
if err != nil {
return nil, fmt.Errorf("could not get the pull request body and title: %w", err)
}
Expand All @@ -336,13 +337,14 @@ func (c *create) Create(ctx context.Context, args *args) (*core.LocalPr, error)
return localPr, err
}

func (c *create) GetBodyAndTitle(commits []*object.Commit) (string, string, error) {
func (c *create) GetBodyAndTitle(ctx context.Context, in io.Reader, commits []*object.Commit) (string, string, error) {
rawTitle, rawBody := c.getRawBodyAndTitle(commits)
commitMessages := make([]string, len(commits))
for i, c := range commits {
commitMessages[i] = c.Message
}
title, body, err := c.StoryService.EnrichBodyAndTitle(commitMessages, rawTitle, rawBody)
storyService := story.NewStoryService(c.StoryFetcher, in)
title, body, err := storyService.EnrichBodyAndTitle(ctx, commitMessages, rawTitle, rawBody)
if err != nil {
return "", "", fmt.Errorf("could not enrich the PR with the Story: %w", err)
}
Expand Down
115 changes: 108 additions & 7 deletions cmd/pr_story_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import (
"testing"

"github.com/cupcicm/opp/core"
"github.com/cupcicm/opp/core/story"
"github.com/cupcicm/opp/core/tests"
"github.com/google/go-github/v56/github"
)

func TestPrStory(t *testing.T) {
func TestPrStoryInCommits(t *testing.T) {
remote := "cupcicm/pr/2"
base := "master"
draft := false
Expand Down Expand Up @@ -38,12 +39,6 @@ func TestPrStory(t *testing.T) {
expectedTitle: "my title [ABC-123]",
expectedBody: "- Linear [ABC-123](https://my.base.url/browse/ABC-123)\n\nmy body",
},
{
name: "no story",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
expectedTitle: "longest commit message",
expectedBody: "longest commit message body",
},
{
name: "empty body",
commitMessages: []string{"[ABC-123] my commit title", "a\nb"},
Expand Down Expand Up @@ -96,3 +91,109 @@ func TestPrStory(t *testing.T) {
})
}
}

func TestPrStoryFetched(t *testing.T) {
remote := "cupcicm/pr/2"
base := "master"
draft := false

testCases := []struct {
name string
commitMessages []string
fetchedStories []story.Story
errFetchStories bool
selectedStory string
expectedTitle string
expectedBody string
}{
{
name: "no story",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{},
errFetchStories: false,
selectedStory: "",
expectedTitle: "longest commit message",
expectedBody: "longest commit message body",
},
{
name: "error fetching story",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{},
errFetchStories: true,
selectedStory: "",
expectedTitle: "longest commit message",
expectedBody: "longest commit message body",
},
{
name: "one story",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{{Title: "Story Title", Identifier: "ABC-123"}},
errFetchStories: false,
selectedStory: "0",
expectedTitle: "[ABC-123] longest commit message",
expectedBody: "- Linear [ABC-123](https://my.base.url/browse/ABC-123)\n\nlongest commit message body",
},
{
name: "two stories - first chosen",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{{Title: "Story Title", Identifier: "ABC-123"}, {Title: "Other Story Title", Identifier: "ABC-456"}},
errFetchStories: false,
selectedStory: "0",
expectedTitle: "[ABC-123] longest commit message",
expectedBody: "- Linear [ABC-123](https://my.base.url/browse/ABC-123)\n\nlongest commit message body",
},
{
name: "two stories - second chosen",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{{Title: "Story Title", Identifier: "ABC-123"}, {Title: "Other Story Title", Identifier: "ABC-456"}},
errFetchStories: false,
selectedStory: "1",
expectedTitle: "[ABC-456] longest commit message",
expectedBody: "- Linear [ABC-456](https://my.base.url/browse/ABC-456)\n\nlongest commit message body",
},
{
name: "two stories - invalid input",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{{Title: "Story Title", Identifier: "ABC-123"}, {Title: "Other Story Title", Identifier: "ABC-456"}},
errFetchStories: false,
selectedStory: "invalid",
expectedTitle: "longest commit message",
expectedBody: "longest commit message body",
},
{
name: "two stories - no input",
commitMessages: []string{"longest commit message\nlongest commit message body", "a\nb", "c\nd"},
fetchedStories: []story.Story{{Title: "Story Title", Identifier: "ABC-123"}, {Title: "Other Story Title", Identifier: "ABC-456"}},
errFetchStories: false,
selectedStory: "",
expectedTitle: "longest commit message",
expectedBody: "longest commit message body",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
r := tests.NewTestRepo(t)

r.Repo.GitExec(context.Background(), "checkout origin/master").Run()
r.Repo.GitExec(context.Background(), "checkout -b test_branch").Run()

wt := core.Must(r.Source.Worktree())

for _, commitMessage := range tc.commitMessages {
wt.Add("README.md")
r.Commit(commitMessage)
}

prDetails := github.NewPullRequest{
Title: &tc.expectedTitle,
Head: &remote,
Base: &base,
Body: &tc.expectedBody,
Draft: &draft,
}

r.CreatePrAssertPrDetailsWithStories(t, "HEAD", 2, tc.fetchedStories, tc.errFetchStories, tc.selectedStory, prDetails)
})
}
}
4 changes: 4 additions & 0 deletions core/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,7 @@ func GetStoryToolUrl() string {
func EnrichPrBodyWithStoryEnabled() bool {
return viper.GetBool("story.enrich")
}

func GetStoryToolToken() string {
return viper.GetString("story.token")
}
9 changes: 9 additions & 0 deletions core/story/story_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,12 @@ type Story struct {
type StoryFetcher interface {
FetchInProgressStories(context.Context) ([]Story, error)
}

func NewStoryFetcher(tool, token string) StoryFetcher {
switch tool {
case "linear":
return NewLinearStoryFetcher(token)
default:
panic("Story tool not supported to fetch stories")
}
}
Loading

0 comments on commit 06317a0

Please sign in to comment.