thinking of a better solution, wip. BaseRepo() might be better split up
This commit is contained in:
parent
a98395f4e8
commit
ca5e9a49b5
4 changed files with 219 additions and 131 deletions
|
|
@ -59,6 +59,93 @@ type ResolvedRemotes struct {
|
|||
apiClient *api.Client
|
||||
}
|
||||
|
||||
func GetBaseRepo(remotes Remotes) (ghrepo.Interface, error) {
|
||||
for _, r := range remotes {
|
||||
if r.Resolved == "base" {
|
||||
return r, nil
|
||||
} else if r.Resolved != "" {
|
||||
repo, err := ghrepo.FromFullName(r.Resolved)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ghrepo.NewWithHost(repo.RepoOwner(), repo.RepoName(), r.RepoHost()), nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("a default repo has not been set, use `gh repo default` to set a default repo")
|
||||
}
|
||||
|
||||
func RemoveBaseRepo(remotes Remotes) {
|
||||
for _, remote := range remotes {
|
||||
if remote.Resolved == "base" {
|
||||
remote.Resolved = ""
|
||||
git.UnsetRemoteResolution(remote.Remote.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ResolvedRemotes) SetGitConfigBaseRepo(io *iostreams.IOStreams) error {
|
||||
resolution := "base"
|
||||
if !io.CanPrompt() {
|
||||
git.SetRemoteResolution(r.remotes[0].Name, resolution)
|
||||
return nil
|
||||
}
|
||||
|
||||
// from here on, consult the API
|
||||
if r.network == nil {
|
||||
err := resolveNetwork(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var repoNames []string
|
||||
repoMap := map[string]*api.Repository{}
|
||||
add := func(r *api.Repository) {
|
||||
fn := ghrepo.FullName(r)
|
||||
if _, ok := repoMap[fn]; !ok {
|
||||
repoMap[fn] = r
|
||||
repoNames = append(repoNames, fn)
|
||||
}
|
||||
}
|
||||
|
||||
for _, repo := range r.network.Repositories {
|
||||
if repo == nil {
|
||||
continue
|
||||
}
|
||||
if repo.Parent != nil {
|
||||
add(repo.Parent)
|
||||
}
|
||||
add(repo)
|
||||
}
|
||||
|
||||
if len(repoNames) == 0 {
|
||||
git.SetRemoteResolution(r.remotes[0].Name, resolution)
|
||||
return nil
|
||||
}
|
||||
|
||||
baseName := repoNames[0]
|
||||
if len(repoNames) > 1 {
|
||||
err := prompt.SurveyAskOne(&survey.Select{
|
||||
Message: "Which should be the base repository (used for e.g. querying issues) for this directory?",
|
||||
Options: repoNames,
|
||||
}, &baseName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// determine corresponding git remote
|
||||
selectedRepo := repoMap[baseName]
|
||||
remote, _ := r.RemoteForRepo(selectedRepo)
|
||||
if remote == nil {
|
||||
remote = r.remotes[0]
|
||||
resolution = ghrepo.FullName(selectedRepo)
|
||||
}
|
||||
|
||||
// cache the result to git config
|
||||
return git.SetRemoteResolution(remote.Name, resolution)
|
||||
}
|
||||
|
||||
func (r *ResolvedRemotes) BaseRepo(io *iostreams.IOStreams) (ghrepo.Interface, error) {
|
||||
if r.baseOverride != nil {
|
||||
return r.baseOverride, nil
|
||||
|
|
|
|||
|
|
@ -169,9 +169,9 @@ func SetRemoteResolution(name, resolution string) error {
|
|||
}
|
||||
|
||||
func UnsetRemoteResolution(name string) error {
|
||||
addCmd, err := GitCommand("config", "--unset-all", fmt.Sprintf("remote.%s.gh-resolved", name))
|
||||
unsetCmd, err := GitCommand("config", "--unset-all", fmt.Sprintf("remote.%s.gh-resolved", name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return run.PrepareCmd(addCmd).Run()
|
||||
return run.PrepareCmd(unsetCmd).Run()
|
||||
}
|
||||
|
|
|
|||
43
pkg/cmd/base/base.go
Normal file
43
pkg/cmd/base/base.go
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
package base
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/cli/cli/v2/context"
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
"github.com/cli/cli/v2/pkg/prompt"
|
||||
|
||||
"github.com/cli/cli/v2/api"
|
||||
)
|
||||
|
||||
func GetAllResolvedRemotes(Remotes func() (context.Remotes, error), HttpClient func() (*http.Client, error)) ([]func(ghrepo.Interface, error), error) {
|
||||
// return []func() (ghrepo.Interface, error) {
|
||||
httpClient, err := HttpClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
apiClient := api.NewClientFromHTTP(httpClient)
|
||||
|
||||
remotes, err := Remotes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repoContext, err := context.ResolveRemotesToRepos(remotes, apiClient, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repoContext.GetBaseRepo()
|
||||
// baseRepo, err := repoContext.BaseRepo(f.IOStreams)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// return baseRepo, nil
|
||||
// }
|
||||
// urn nil
|
||||
}
|
||||
|
|
@ -1,129 +1,87 @@
|
|||
package base
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/cli/cli/v2/api"
|
||||
"github.com/cli/cli/v2/context"
|
||||
"github.com/cli/cli/v2/git"
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/pkg/cmdutil"
|
||||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type DefaultOptions struct {
|
||||
IO *iostreams.IOStreams
|
||||
Remotes func() (context.Remotes, error)
|
||||
BaseRepo func() (ghrepo.Interface, error)
|
||||
HttpClient func() (*http.Client, error)
|
||||
|
||||
RemoteName string
|
||||
ListFlag bool
|
||||
}
|
||||
|
||||
func NewCmdDefault(f *cmdutil.Factory, runF func(*DefaultOptions) error) *cobra.Command {
|
||||
opts := &DefaultOptions{
|
||||
IO: f.IOStreams,
|
||||
HttpClient: f.HttpClient,
|
||||
BaseRepo: f.BaseRepo,
|
||||
Remotes: f.Remotes,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "default <git remote name>",
|
||||
Short: "Configure the default repository used for various commands",
|
||||
Long: heredoc.Doc(`
|
||||
The default repository is used to determine which repository gh
|
||||
should automatically query for the commands:
|
||||
issue, pr, browse, run, repo rename, secret, workflow
|
||||
`),
|
||||
Example: heredoc.Doc(`
|
||||
$ gh repo default upstream
|
||||
`),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) > 0 {
|
||||
opts.RemoteName = args[0]
|
||||
}
|
||||
if !opts.IO.CanPrompt() && !opts.ListFlag && opts.RemoteName == "" {
|
||||
return cmdutil.FlagErrorf("remote name is required when not running interactively, use `--list` to see available remotes")
|
||||
}
|
||||
if err := cmdutil.MutuallyExclusive(
|
||||
"args cannot be passed in with --list",
|
||||
opts.RemoteName != "",
|
||||
opts.ListFlag,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if runF != nil {
|
||||
return runF(opts)
|
||||
}
|
||||
return defaultRun(opts)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVarP(&opts.ListFlag, "list", "l", false, "list the current and available repositories")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func defaultRun(opts *DefaultOptions) error {
|
||||
remotes, err := opts.Remotes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.ListFlag {
|
||||
found := false
|
||||
list := &strings.Builder{}
|
||||
for _, remote := range remotes {
|
||||
if remote.Resolved == "base" {
|
||||
list.WriteString(fmt.Sprintf("* %s\n", remote.Remote.Name))
|
||||
found = true
|
||||
} else {
|
||||
list.WriteString(fmt.Sprintf(" %s\n", remote.Remote.Name))
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
fmt.Fprint(opts.IO.Out, "the default repo has not been set\n")
|
||||
}
|
||||
fmt.Fprint(opts.IO.Out, list.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
if opts.RemoteName != "" {
|
||||
for _, remote := range remotes {
|
||||
if opts.RemoteName == remote.Remote.Name {
|
||||
removeBaseRepo(remotes)
|
||||
git.SetRemoteResolution(remote.Name, "base")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("could not find local remote name %s", opts.RemoteName)
|
||||
}
|
||||
removeBaseRepo(remotes)
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
apiClient := api.NewClientFromHTTP(httpClient)
|
||||
repoContext, err := context.ResolveRemotesToRepos(remotes, apiClient, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = repoContext.BaseRepo(opts.IO)
|
||||
return err
|
||||
}
|
||||
|
||||
func removeBaseRepo(remotes context.Remotes) {
|
||||
for _, remote := range remotes {
|
||||
if remote.Resolved == "base" {
|
||||
remote.Resolved = ""
|
||||
git.UnsetRemoteResolution(remote.Remote.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
package base
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/cli/cli/v2/api"
|
||||
"github.com/cli/cli/v2/context"
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/pkg/cmdutil"
|
||||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type DefaultOptions struct {
|
||||
IO *iostreams.IOStreams
|
||||
BaseRepo func() (ghrepo.Interface, error)
|
||||
Remotes func() (context.Remotes, error)
|
||||
HttpClient func() (*http.Client, error)
|
||||
|
||||
ViewFlag bool
|
||||
}
|
||||
|
||||
func NewCmdDefault(f *cmdutil.Factory, runF func(*DefaultOptions) error) *cobra.Command {
|
||||
opts := &DefaultOptions{
|
||||
IO: f.IOStreams,
|
||||
HttpClient: f.HttpClient,
|
||||
BaseRepo: f.BaseRepo,
|
||||
Remotes: f.Remotes,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "default",
|
||||
Short: "Configure the default repository used for various commands",
|
||||
Long: heredoc.Doc(`
|
||||
The default repository is used to determine which repository gh
|
||||
should automatically query for the commands:
|
||||
issue, pr, browse, run, repo rename, secret, workflow
|
||||
`),
|
||||
Example: heredoc.Doc(`
|
||||
$ gh repo default cli/cli
|
||||
`),
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if !opts.IO.CanPrompt() && !opts.ViewFlag {
|
||||
return cmdutil.FlagErrorf("a repository name is required when not running interactively")
|
||||
}
|
||||
|
||||
if runF != nil {
|
||||
return runF(opts)
|
||||
}
|
||||
return defaultRun(opts)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVarP(&opts.ViewFlag, "view", "v", false, "view the default repository used for various commands")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func defaultRun(opts *DefaultOptions) error {
|
||||
remotes, err := opts.Remotes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.ViewFlag {
|
||||
baseRepo, err := context.GetBaseRepo(remotes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(opts.IO.Out, ghrepo.FullName(baseRepo))
|
||||
return nil
|
||||
}
|
||||
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
apiClient := api.NewClientFromHTTP(httpClient)
|
||||
context.RemoveBaseRepo(remotes)
|
||||
repoContext, err := context.ResolveRemotesToRepos(remotes, apiClient, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return repoContext.SetGitConfigBaseRepo(opts.IO)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue