X Tutup
package iapi import ( "fmt" "net/http" "time" "github.com/cli/cli/api" "github.com/cli/cli/internal/ghrepo" apiCmd "github.com/cli/cli/pkg/cmd/api" "github.com/cli/cli/pkg/cmdutil" "github.com/cli/cli/pkg/iostreams" "github.com/spf13/cobra" ) type ApiOptions struct { IO *iostreams.IOStreams HttpClient func() (*http.Client, error) BaseRepo func() (ghrepo.Interface, error) Branch func() (string, error) Builder QueryBuilder } func NewCmdApi(f *cmdutil.Factory, runF func(*ApiOptions) error) *cobra.Command { opts := ApiOptions{ IO: f.IOStreams, HttpClient: f.HttpClient, BaseRepo: f.BaseRepo, Branch: f.Branch, } cmd := &cobra.Command{ Use: "iapi", Args: cobra.NoArgs, RunE: func(c *cobra.Command, args []string) error { return apiRun(&opts) }, } return cmd } func apiRun(opts *ApiOptions) error { httpClient, err := opts.HttpClient() if err != nil { return err } cachedClient := api.NewCachedClient(httpClient, time.Hour*48) apiClient := api.NewClientFromHTTP(cachedClient) err = addQuery(apiClient, opts) if err != nil { return err } err = addArguments(apiClient, opts.Builder, true) if err != nil { return err } err = addFields(apiClient, opts.Builder, true) if err != nil { return err } return loop(apiClient, opts) } func loop(client *api.Client, opts *ApiOptions) error { for { next, err := nextSurvey() if err != nil { return err } switch next { case "Add arguments": err = addArguments(client, opts.Builder, false) if err != nil { return err } case "Add fields": err = addFields(client, opts.Builder, false) if err != nil { return err } case "Show query": query := opts.Builder.Generate() fmt.Println(query) case "Run query": query := opts.Builder.Generate() executeQuery(opts, query) case "Exit": return nil } } } func addQuery(client *api.Client, opts *ApiOptions) error { var response queryTypes err := client.GraphQL("github.com", queryTypesQuery(), nil, &response) if err != nil { return err } m := map[string]string{} for _, v := range response.Schema.QueryType.Fields { if v.Type.Name != "" { m[v.Name] = v.Type.Name continue } if v.Type.OfType.Name != "" { m[v.Name] = v.Type.OfType.Name continue } m[v.Name] = v.Name } o := []string{} for k, _ := range m { o = append(o, k) } name, err := queryTypeSurvey(o) if err != nil { return err } opts.Builder = NewQueryBuilder(name) opts.Builder.CurrentNode().AddKind(m[name]) return nil } func addArguments(client *api.Client, builder QueryBuilder, skip bool) error { currentNode := builder.CurrentNode() if !skip { var err error var names []string for _, v := range builder.ArgumentNodes() { names = append(names, v.Name) } name, err := objectsSurvey(names) if err != nil { return err } currentNode = builder.FindNode(name) } options := []string{} var err error parentNode := currentNode.Parent if parentNode == nil { var response queryTypes err = client.GraphQL("github.com", queryTypesQuery(), nil, &response) if err != nil { return err } for _, v := range response.Schema.QueryType.Fields { if v.Name == currentNode.Name { for _, a := range v.Args { options = append(options, a.Name) } } } } else { options, err = retrieveArgumentOpts(client, parentNode.Kind, currentNode.Name) if err != nil { return err } } if len(options) > 0 { currentNode.AddArgumentsAvailable(true) } arguments, err := argumentsSurvey(options) if err != nil { return err } if arguments != nil { currentNode.AddArguments(arguments) } return nil } func addFields(client *api.Client, builder QueryBuilder, skip bool) error { node := builder.CurrentNode() if !skip { var names []string for _, v := range builder.FieldNodes() { names = append(names, v.Name) } name, err := objectsSurvey(names) if err != nil { return err } node = builder.FindNode(name) } m, err := retrieveFieldOpts(client, node.Kind) if err != nil { return err } var options []string for key, _ := range m { options = append(options, key) } if len(options) > 0 { node.AddFieldsAvailable(true) } fields, err := fieldsSurvey(options) if err != nil { return err } for _, v := range fields { nn := node.AddNode(v) nn.AddKind(m[v].Kind) nn.AddArgumentsAvailable(m[v].Args) fa, err := retrieveFieldsAvailable(client, nn.Kind) if err != nil { return err } nn.AddFieldsAvailable(fa) } return nil } func executeQuery(opts *ApiOptions, query string) error { q := fmt.Sprintf("query=%s", query) o := apiCmd.ApiOptions{ HttpClient: opts.HttpClient, IO: opts.IO, BaseRepo: opts.BaseRepo, Branch: opts.Branch, RequestPath: "graphql", RawFields: []string{q}, } return apiCmd.IapiRun(&o) }
X Tutup