11package githubclient
22
33import (
4- "bytes"
54 "context"
65 "fmt"
76 "net/url"
87 "os"
98 "path"
10- "path/filepath"
119 "strings"
1210
1311 "gopkg.in/yaml.v3"
@@ -17,6 +15,7 @@ import (
1715 "github.com/ejoffe/spr/github"
1816 "github.com/ejoffe/spr/github/githubclient/fezzik_types"
1917 "github.com/ejoffe/spr/github/githubclient/gen/genclient"
18+ "github.com/ejoffe/spr/github/template/config_fetcher"
2019 "github.com/rs/zerolog/log"
2120 "golang.org/x/oauth2"
2221)
@@ -384,22 +383,14 @@ func (c *client) CreatePullRequest(ctx context.Context, gitcmd git.GitInterface,
384383 Str ("FromBranch" , headRefName ).Str ("ToBranch" , baseRefName ).
385384 Msg ("CreatePullRequest" )
386385
387- body := formatBody (commit , info .PullRequests , c .config .Repo .ShowPrTitlesInStack )
388- if c .config .Repo .PRTemplatePath != "" {
389- pullRequestTemplate , err := readPRTemplate (gitcmd , c .config .Repo .PRTemplatePath )
390- if err != nil {
391- log .Fatal ().Err (err ).Msg ("failed to read PR template" )
392- }
393- body , err = insertBodyIntoPRTemplate (body , pullRequestTemplate , c .config .Repo , nil )
394- if err != nil {
395- log .Fatal ().Err (err ).Msg ("failed to insert body into PR template" )
396- }
397- }
386+ templatizer := config_fetcher .PRTemplatizer (c .config , gitcmd )
387+
388+ body := templatizer .Body (info , commit )
398389 resp , err := c .api .CreatePullRequest (ctx , genclient.CreatePullRequestInput {
399390 RepositoryId : info .RepositoryID ,
400391 BaseRefName : baseRefName ,
401392 HeadRefName : headRefName ,
402- Title : commit . Subject ,
393+ Title : templatizer . Title ( info , commit ) ,
403394 Body : & body ,
404395 Draft : & c .config .User .CreateDraftPRs ,
405396 })
@@ -427,113 +418,9 @@ func (c *client) CreatePullRequest(ctx context.Context, gitcmd git.GitInterface,
427418 return pr
428419}
429420
430- func formatStackMarkdown (commit git.Commit , stack []* github.PullRequest , showPrTitlesInStack bool ) string {
431- var buf bytes.Buffer
432- for i := len (stack ) - 1 ; i >= 0 ; i -- {
433- isCurrent := stack [i ].Commit == commit
434- var suffix string
435- if isCurrent {
436- suffix = " ⬅"
437- } else {
438- suffix = ""
439- }
440- var prTitle string
441- if showPrTitlesInStack {
442- prTitle = fmt .Sprintf ("%s " , stack [i ].Title )
443- } else {
444- prTitle = ""
445- }
446-
447- buf .WriteString (fmt .Sprintf ("- %s#%d%s\n " , prTitle , stack [i ].Number , suffix ))
448- }
449-
450- return buf .String ()
451- }
452-
453- func formatBody (commit git.Commit , stack []* github.PullRequest , showPrTitlesInStack bool ) string {
454- if len (stack ) <= 1 {
455- return strings .TrimSpace (commit .Body )
456- }
457-
458- if commit .Body == "" {
459- return fmt .Sprintf ("**Stack**:\n %s" ,
460- addManualMergeNotice (formatStackMarkdown (commit , stack , showPrTitlesInStack )))
461- }
462-
463- return fmt .Sprintf ("%s\n \n ---\n \n **Stack**:\n %s" ,
464- commit .Body ,
465- addManualMergeNotice (formatStackMarkdown (commit , stack , showPrTitlesInStack )))
466- }
467-
468- // Reads the specified PR template file and returns it as a string
469- func readPRTemplate (gitcmd git.GitInterface , templatePath string ) (string , error ) {
470- repoRootDir := gitcmd .RootDir ()
471- fullTemplatePath := filepath .Clean (path .Join (repoRootDir , templatePath ))
472- pullRequestTemplateBytes , err := os .ReadFile (fullTemplatePath )
473- if err != nil {
474- return "" , fmt .Errorf ("%w: unable to read template %v" , err , fullTemplatePath )
475- }
476- return string (pullRequestTemplateBytes ), nil
477- }
478-
479- // insertBodyIntoPRTemplate inserts a text body into the given PR template and returns the result as a string.
480- // It uses the PRTemplateInsertStart and PRTemplateInsertEnd values defined in RepoConfig to determine where the body
481- // should be inserted in the PR template. If there are issues finding the correct place to insert the body
482- // an error will be returned.
483- //
484- // NOTE: on PR update, rather than using the PR template, it will use the existing PR body, which should have
485- // the PR template from the initial PR create.
486- func insertBodyIntoPRTemplate (body , prTemplate string , repo * config.RepoConfig , pr * github.PullRequest ) (string , error ) {
487- templateOrExistingPRBody := prTemplate
488- if pr != nil && pr .Body != "" {
489- templateOrExistingPRBody = pr .Body
490- }
491-
492- startPRTemplateSection , err := getSectionOfPRTemplate (templateOrExistingPRBody , repo .PRTemplateInsertStart , BeforeMatch )
493- if err != nil {
494- return "" , fmt .Errorf ("%w: PR template insert start = '%v'" , err , repo .PRTemplateInsertStart )
495- }
496-
497- endPRTemplateSection , err := getSectionOfPRTemplate (templateOrExistingPRBody , repo .PRTemplateInsertEnd , AfterMatch )
498- if err != nil {
499- return "" , fmt .Errorf ("%w: PR template insert end = '%v'" , err , repo .PRTemplateInsertEnd )
500- }
501-
502- return fmt .Sprintf ("%v%v\n %v\n \n %v%v" , startPRTemplateSection , repo .PRTemplateInsertStart , body ,
503- repo .PRTemplateInsertEnd , endPRTemplateSection ), nil
504- }
505-
506- const (
507- BeforeMatch = iota
508- AfterMatch
509- )
510-
511- // getSectionOfPRTemplate searches text for a matching searchString and will return the text before or after the
512- // match as a string. If there are no matches or more than one match is found, an error will be returned.
513- func getSectionOfPRTemplate (text , searchString string , returnMatch int ) (string , error ) {
514- split := strings .Split (text , searchString )
515- switch len (split ) {
516- case 2 :
517- if returnMatch == BeforeMatch {
518- return split [0 ], nil
519- } else if returnMatch == AfterMatch {
520- return split [1 ], nil
521- }
522- return "" , fmt .Errorf ("invalid enum value" )
523- case 1 :
524- return "" , fmt .Errorf ("no matches found" )
525- default :
526- return "" , fmt .Errorf ("multiple matches found" )
527- }
528- }
529-
530- func addManualMergeNotice (body string ) string {
531- return body + "\n \n " +
532- "⚠️ *Part of a stack created by [spr](https://github.com/ejoffe/spr). " +
533- "Do not merge manually using the UI - doing so may have unexpected results.*"
534- }
535-
536- func (c * client ) UpdatePullRequest (ctx context.Context , gitcmd git.GitInterface , pullRequests []* github.PullRequest , pr * github.PullRequest , commit git.Commit , prevCommit * git.Commit ) {
421+ func (c * client ) UpdatePullRequest (ctx context.Context , gitcmd git.GitInterface ,
422+ info * github.GitHubInfo , pullRequests []* github.PullRequest , pr * github.PullRequest ,
423+ commit git.Commit , prevCommit * git.Commit ) {
537424
538425 if c .config .User .LogGitHubCalls {
539426 fmt .Printf ("> github update %d : %s\n " , pr .Number , pr .Title )
@@ -548,34 +435,23 @@ func (c *client) UpdatePullRequest(ctx context.Context, gitcmd git.GitInterface,
548435 Str ("FromBranch" , pr .FromBranch ).Str ("ToBranch" , baseRefName ).
549436 Interface ("PR" , pr ).Msg ("UpdatePullRequest" )
550437
551- body := formatBody (commit , pullRequests , c .config .Repo .ShowPrTitlesInStack )
552- if c .config .Repo .PRTemplatePath != "" {
553- pullRequestTemplate , err := readPRTemplate (gitcmd , c .config .Repo .PRTemplatePath )
554- if err != nil {
555- log .Fatal ().Err (err ).Msg ("failed to read PR template" )
556- }
557- body , err = insertBodyIntoPRTemplate (body , pullRequestTemplate , c .config .Repo , pr )
558- if err != nil {
559- log .Fatal ().Err (err ).Msg ("failed to insert body into PR template" )
560- }
561- }
562- title := & commit .Subject
563-
438+ templatizer := config_fetcher .PRTemplatizer (c .config , gitcmd )
439+ title := templatizer .Title (info , commit )
440+ body := templatizer .Body (info , commit )
564441 input := genclient.UpdatePullRequestInput {
565442 PullRequestId : pr .ID ,
566- Title : title ,
443+ Title : & title ,
567444 Body : & body ,
568445 }
569-
570- if ! pr .InQueue {
571- input .BaseRefName = & baseRefName
572- }
573-
574446 if c .config .User .PreserveTitleAndBody {
575447 input .Title = nil
576448 input .Body = nil
577449 }
578450
451+ if ! pr .InQueue {
452+ input .BaseRefName = & baseRefName
453+ }
454+
579455 _ , err := c .api .UpdatePullRequest (ctx , input )
580456
581457 if err != nil {
0 commit comments