From 118249b321aeb7638c69b22591bc73ee5c9779a5 Mon Sep 17 00:00:00 2001 From: Jean-Hadrien Chabran Date: Thu, 6 Oct 2022 14:49:04 +0200 Subject: [PATCH 1/3] Add a add subcommand to extsvc In the context of scaletesting, it's pretty useful to be able to add code hosts on the fly, while toying with a test instance. This PR adds such a command. --- cmd/src/extsvc.go | 5 +- cmd/src/extsvc_add.go | 103 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 cmd/src/extsvc_add.go diff --git a/cmd/src/extsvc.go b/cmd/src/extsvc.go index e761dd1714..36d883bce7 100644 --- a/cmd/src/extsvc.go +++ b/cmd/src/extsvc.go @@ -23,6 +23,7 @@ The commands are: list lists the external services on the Sourcegraph instance edit edits external services on the Sourcegraph instance + add adds an external service on the Sourcegaph instance Use "src extsvc [command] -h" for more information about a command. ` @@ -52,6 +53,8 @@ type externalService struct { CreatedAt, UpdatedAt string } +var errServiceNotFound = errors.New("no such external service") + func lookupExternalService(ctx context.Context, client api.Client, byID, byName string) (*externalService, error) { var result struct { ExternalServices struct { @@ -72,5 +75,5 @@ func lookupExternalService(ctx context.Context, client api.Client, byID, byName return svc, nil } } - return nil, errors.New("no such external service") + return nil, errServiceNotFound } diff --git a/cmd/src/extsvc_add.go b/cmd/src/extsvc_add.go new file mode 100644 index 0000000000..ca65c99e24 --- /dev/null +++ b/cmd/src/extsvc_add.go @@ -0,0 +1,103 @@ +package main + +import ( + "context" + "flag" + "fmt" + "io" + "os" + "strings" + + "github.com/mattn/go-isatty" + "github.com/sourcegraph/sourcegraph/lib/errors" + "github.com/sourcegraph/src-cli/internal/api" +) + +func init() { + usage := ` + Examples: + + Add an external service configuration on the Sourcegraph instance: + + $ cat new-config.json | src extsvc add + $ src extsvc add -name 'My GitHub connection' new-config.json + ` + + flagSet := flag.NewFlagSet("add", flag.ExitOnError) + usageFunc := func() { + fmt.Fprintf(flag.CommandLine.Output(), "Usage of 'src extsvc %s':\n", flagSet.Name()) + flagSet.PrintDefaults() + fmt.Println(usage) + } + var ( + nameFlag = flagSet.String("name", "", "exact name of the external service to add") + kindFlag = flagSet.String("kind", "", "kind of the external service to add") + apiFlags = api.NewFlags(flagSet) + ) + + handler := func(args []string) (err error) { + ctx := context.Background() + if err := flagSet.Parse(args); err != nil { + return err + } + + client := cfg.apiClient(apiFlags, flagSet.Output()) + if *nameFlag != "" { + _, err := lookupExternalService(ctx, client, "", *nameFlag) + if err != errServiceNotFound { + return errors.New("service already exists") + } + } + + var addJSON []byte + if len(flagSet.Args()) == 1 { + addJSON, err = os.ReadFile(flagSet.Arg(0)) + if err != nil { + return err + } + } + if !isatty.IsTerminal(os.Stdin.Fd()) { + // stdin is a pipe not a terminal + addJSON, err = io.ReadAll(os.Stdin) + if err != nil { + return err + } + } + + addExternalServiceInput := map[string]interface{}{ + "kind": strings.ToUpper(*kindFlag), + "displayName": *nameFlag, + "config": string(addJSON), + } + + queryVars := map[string]interface{}{ + "input": addExternalServiceInput, + } + + var result struct{} // TODO: future: allow formatting resulting external service + if ok, err := client.NewRequest(externalServicesAddMutation, queryVars).Do(ctx, &result); err != nil { + if strings.Contains(err.Error(), "Additional property exclude is not allowed") { + return errors.New(`specified external service does not support repository "exclude" list`) + } + return err + } else if ok { + fmt.Println("External service created:", *nameFlag) + } + return nil + } + + // Register the command. + extsvcCommands = append(extsvcCommands, &command{ + flagSet: flagSet, + handler: handler, + usageFunc: usageFunc, + }) +} + +const externalServicesAddMutation = ` + mutation AddExternalService($input: AddExternalServiceInput!) { + addExternalService(input: $input) { + id + warning + } + }` From c4bd9ec13697d3f4fc4fdf71a17dd66d7f9a482a Mon Sep 17 00:00:00 2001 From: Jean-Hadrien Chabran Date: Thu, 6 Oct 2022 15:37:49 +0200 Subject: [PATCH 2/3] fixup --- cmd/src/extsvc_add.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/src/extsvc_add.go b/cmd/src/extsvc_add.go index ca65c99e24..98c9bfa961 100644 --- a/cmd/src/extsvc_add.go +++ b/cmd/src/extsvc_add.go @@ -41,6 +41,10 @@ func init() { return err } + if *nameFlag == "" { + return errors.New("-name must be provided") + } + client := cfg.apiClient(apiFlags, flagSet.Output()) if *nameFlag != "" { _, err := lookupExternalService(ctx, client, "", *nameFlag) From 674659ee49e43f39d6bbb4d68e56acb2d78c6f77 Mon Sep 17 00:00:00 2001 From: Jean-Hadrien Chabran Date: Mon, 10 Oct 2022 17:07:51 +0200 Subject: [PATCH 3/3] Small fixes --- cmd/src/extsvc.go | 2 +- cmd/src/{extsvc_add.go => extsvc_create.go} | 44 ++++++++------------- 2 files changed, 17 insertions(+), 29 deletions(-) rename cmd/src/{extsvc_add.go => extsvc_create.go} (62%) diff --git a/cmd/src/extsvc.go b/cmd/src/extsvc.go index 36d883bce7..a716aebc00 100644 --- a/cmd/src/extsvc.go +++ b/cmd/src/extsvc.go @@ -23,7 +23,7 @@ The commands are: list lists the external services on the Sourcegraph instance edit edits external services on the Sourcegraph instance - add adds an external service on the Sourcegaph instance + add add an external service on the Sourcegraph instance Use "src extsvc [command] -h" for more information about a command. ` diff --git a/cmd/src/extsvc_add.go b/cmd/src/extsvc_create.go similarity index 62% rename from cmd/src/extsvc_add.go rename to cmd/src/extsvc_create.go index 98c9bfa961..d79ac48540 100644 --- a/cmd/src/extsvc_add.go +++ b/cmd/src/extsvc_create.go @@ -17,21 +17,21 @@ func init() { usage := ` Examples: - Add an external service configuration on the Sourcegraph instance: + create an external service configuration on the Sourcegraph instance: - $ cat new-config.json | src extsvc add - $ src extsvc add -name 'My GitHub connection' new-config.json + $ cat new-config.json | src extsvc create + $ src extsvc create -name 'My GitHub connection' new-config.json ` - flagSet := flag.NewFlagSet("add", flag.ExitOnError) + flagSet := flag.NewFlagSet("create", flag.ExitOnError) usageFunc := func() { fmt.Fprintf(flag.CommandLine.Output(), "Usage of 'src extsvc %s':\n", flagSet.Name()) flagSet.PrintDefaults() fmt.Println(usage) } var ( - nameFlag = flagSet.String("name", "", "exact name of the external service to add") - kindFlag = flagSet.String("kind", "", "kind of the external service to add") + nameFlag = flagSet.String("name", "", "exact name of the external service to create") + kindFlag = flagSet.String("kind", "", "kind of the external service to create") apiFlags = api.NewFlags(flagSet) ) @@ -40,49 +40,37 @@ func init() { if err := flagSet.Parse(args); err != nil { return err } - if *nameFlag == "" { return errors.New("-name must be provided") } - client := cfg.apiClient(apiFlags, flagSet.Output()) - if *nameFlag != "" { - _, err := lookupExternalService(ctx, client, "", *nameFlag) - if err != errServiceNotFound { - return errors.New("service already exists") - } - } - - var addJSON []byte + var createJSON []byte if len(flagSet.Args()) == 1 { - addJSON, err = os.ReadFile(flagSet.Arg(0)) + createJSON, err = os.ReadFile(flagSet.Arg(0)) if err != nil { return err } } if !isatty.IsTerminal(os.Stdin.Fd()) { // stdin is a pipe not a terminal - addJSON, err = io.ReadAll(os.Stdin) + createJSON, err = io.ReadAll(os.Stdin) if err != nil { return err } } - addExternalServiceInput := map[string]interface{}{ + createExternalServiceInput := map[string]interface{}{ "kind": strings.ToUpper(*kindFlag), "displayName": *nameFlag, - "config": string(addJSON), + "config": string(createJSON), } - queryVars := map[string]interface{}{ - "input": addExternalServiceInput, + "input": createExternalServiceInput, } - var result struct{} // TODO: future: allow formatting resulting external service - if ok, err := client.NewRequest(externalServicesAddMutation, queryVars).Do(ctx, &result); err != nil { - if strings.Contains(err.Error(), "Additional property exclude is not allowed") { - return errors.New(`specified external service does not support repository "exclude" list`) - } + + client := cfg.apiClient(apiFlags, flagSet.Output()) + if ok, err := client.NewRequest(externalServicesCreateMutation, queryVars).Do(ctx, &result); err != nil { return err } else if ok { fmt.Println("External service created:", *nameFlag) @@ -98,7 +86,7 @@ func init() { }) } -const externalServicesAddMutation = ` +const externalServicesCreateMutation = ` mutation AddExternalService($input: AddExternalServiceInput!) { addExternalService(input: $input) { id