I've been struggling horribly to reason through all of this code, and
after much mental gymnastics I identified the culprit as the overloaded
"branch" string returned by parseCurrentBranch.
This value was either the name of the branch that the PR we're looking for
is associated with, or that name prepended with the owner's name and a :
if we're on a branch, so:
PR branch: featureBranch
branch == "featureBranch"
If on Fork belonging to "ForkOwner"
branch == "ForkOwner:featureBranch"
Since this extra information was bundled up into this single string, it
complicated the responsibilities of parseCurrentBranch's "branch" return
value. Thus, I've teased out "branch" into the new PRRefs struct:
type PRRefs struct{
BranchName string
HeadRepo ghrepo.Interface
BaseRepo ghrepo.Interface
}
This allows the new parsePRRefs function to move all the previous
"branch" string's information into structured data, and allows for a new
method on PRRefs, GetPRLabel(), to create the string that "branch"
previously held to pass into its downstream consumer, namely
findForBranch.
This also allowed for better test coverage, directly connecting the PRRefs
fields to the values contained in the git config. Overall, I am now
confident that this is doing what its supposed to do with respect to my
understanding of the various central and triangular git workflows we are
addressing.
75 lines
1.4 KiB
Go
75 lines
1.4 KiB
Go
package git
|
|
|
|
import (
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
// RemoteSet is a slice of git remotes.
|
|
type RemoteSet []*Remote
|
|
|
|
func (r RemoteSet) Len() int { return len(r) }
|
|
func (r RemoteSet) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
|
func (r RemoteSet) Less(i, j int) bool {
|
|
return remoteNameSortScore(r[i].Name) > remoteNameSortScore(r[j].Name)
|
|
}
|
|
|
|
func remoteNameSortScore(name string) int {
|
|
switch strings.ToLower(name) {
|
|
case "upstream":
|
|
return 3
|
|
case "github":
|
|
return 2
|
|
case "origin":
|
|
return 1
|
|
default:
|
|
return 0
|
|
}
|
|
}
|
|
|
|
// Remote is a parsed git remote.
|
|
type Remote struct {
|
|
Name string
|
|
Resolved string
|
|
FetchURL *url.URL
|
|
PushURL *url.URL
|
|
}
|
|
|
|
func (r *Remote) String() string {
|
|
return r.Name
|
|
}
|
|
|
|
func NewRemote(name string, u string) *Remote {
|
|
pu, _ := url.Parse(u)
|
|
return &Remote{
|
|
Name: name,
|
|
FetchURL: pu,
|
|
PushURL: pu,
|
|
}
|
|
}
|
|
|
|
// Ref represents a git commit reference.
|
|
type Ref struct {
|
|
Hash string
|
|
Name string
|
|
}
|
|
|
|
type Commit struct {
|
|
Sha string
|
|
Title string
|
|
Body string
|
|
}
|
|
|
|
type BranchConfig struct {
|
|
RemoteName string
|
|
RemoteURL *url.URL
|
|
// MergeBase is the optional base branch to target in a new PR if `--base` is not specified.
|
|
MergeBase string
|
|
MergeRef string
|
|
// These are used to handle triangular workflows. They can be defined by either
|
|
// a remote.pushDefault or a branch.<name>.pushremote value set on the git config.
|
|
RemotePushDefault string
|
|
PushRemoteURL *url.URL
|
|
PushRemoteName string
|
|
Push string
|
|
}
|