~xenrox/hut

e625b16a9c939cb0ab0b90c07d7e4da9263a9a42 — Thorben Günther 2 months ago fdbae66
git: Add git webhook create
5 files changed, 129 insertions(+), 0 deletions(-)

M doc/hut.1.scd
M git.go
M srht/gitsrht/gql.go
M srht/gitsrht/operations.graphql
M srht/gitsrht/strings.go
M doc/hut.1.scd => doc/hut.1.scd +15 -0
@@ 338,6 338,21 @@ Options are:
*user-webhook list*
	List user webhooks.

*webhook create* [list] [options...]
	Create a git webhook.

	Options are:

	*-e*, *--events* <strings...>
		List of events that should trigger the webhook (GIT_PRE_RECEIVE,
		GIT_POST_RECEIVE). Required.

	*--stdin*
		Read query from _stdin_.

	*-u*, *--url* <URL>
		The payload URL which receives the _POST_ request. Required.

## hg

Options are:

M git.go => git.go +82 -0
@@ 35,6 35,7 @@ func newGitCommand() *cobra.Command {
	cmd.AddCommand(newGitShowCommand())
	cmd.AddCommand(newGitUserWebhookCommand())
	cmd.AddCommand(newGitUpdateCommand())
	cmd.AddCommand(newGitWebhookCommand())
	cmd.PersistentFlags().StringP("repo", "r", "", "name of repository")
	cmd.RegisterFlagCompletionFunc("repo", completeGitRepo)
	return cmd


@@ 992,6 993,75 @@ func newGitUpdateCommand() *cobra.Command {
	return cmd
}

func newGitWebhookCommand() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "webhook",
		Short: "Manage git webhooks",
	}
	cmd.AddCommand(newGitWebhookCreateCommand())
	return cmd
}

func newGitWebhookCreateCommand() *cobra.Command {
	var events []string
	var stdin bool
	var url string
	run := func(cmd *cobra.Command, args []string) {
		ctx := cmd.Context()

		var name, owner, instance string
		if len(args) > 0 {
			name, owner, instance = parseResourceName(args[0])
		} else {
			var err error
			name, owner, instance, err = getGitRepoName(ctx, cmd)
			if err != nil {
				log.Fatal(err)
			}
		}

		c := createClientWithInstance("git", cmd, instance)
		id, err := getGitRepoID(c, ctx, name, owner)
		if err != nil {
			log.Fatal(err)
		}

		var config gitsrht.GitWebhookInput
		config.RepositoryID = id
		config.Url = url

		whEvents, err := gitsrht.ParseGitWebhookEvents(events)
		if err != nil {
			log.Fatal(err)
		}
		config.Events = whEvents
		config.Query = readWebhookQuery(stdin)

		webhook, err := gitsrht.CreateGitWebhook(c.Client, ctx, config)
		if err != nil {
			log.Fatal(err)
		}

		log.Printf("Created git webhook with ID %d\n", webhook.Id)
	}

	cmd := &cobra.Command{
		Use:               "Create [repo]",
		Short:             "Create a git webhook",
		Args:              cobra.MaximumNArgs(1),
		ValidArgsFunction: completeGitRepo,
		Run:               run,
	}
	cmd.Flags().StringSliceVarP(&events, "events", "e", nil, "webhook events")
	cmd.RegisterFlagCompletionFunc("events", completeGitWebhookEvents)
	cmd.MarkFlagRequired("events")
	cmd.Flags().BoolVar(&stdin, "stdin", !isStdinTerminal, "read webhook query from stdin")
	cmd.Flags().StringVarP(&url, "url", "u", "", "payload url")
	cmd.RegisterFlagCompletionFunc("url", cobra.NoFileCompletions)
	cmd.MarkFlagRequired("url")
	return cmd
}

func getGitRepoName(ctx context.Context, cmd *cobra.Command) (repoName, owner, instance string, err error) {
	repoName, err = cmd.Flags().GetString("repo")
	if err != nil {


@@ 1219,6 1289,18 @@ func completeGitUserWebhookID(cmd *cobra.Command, args []string, toComplete stri
	return webhookList, cobra.ShellCompDirectiveNoFileComp
}

func completeGitWebhookEvents(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
	var eventList []string
	events := [2]string{"git_pre_receive", "git_post_receive"}
	set := strings.ToLower(cmd.Flag("events").Value.String())
	for _, event := range events {
		if !strings.Contains(set, event) {
			eventList = append(eventList, event)
		}
	}
	return eventList, cobra.ShellCompDirectiveNoFileComp
}

func completeBranches(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
	ctx := cmd.Context()
	repoName, owner, instace, err := getGitRepoName(ctx, cmd)

M srht/gitsrht/gql.go => srht/gitsrht/gql.go +10 -0
@@ 957,3 957,13 @@ func ClearDescription(client *gqlclient.Client, ctx context.Context, id int32) (
	err = client.Execute(ctx, op, &respData)
	return respData.UpdateRepository, err
}

func CreateGitWebhook(client *gqlclient.Client, ctx context.Context, config GitWebhookInput) (createGitWebhook *WebhookSubscription, err error) {
	op := gqlclient.NewOperation("mutation createGitWebhook ($config: GitWebhookInput!) {\n\tcreateGitWebhook(config: $config) {\n\t\tid\n\t}\n}\n")
	op.Var("config", config)
	var respData struct {
		CreateGitWebhook *WebhookSubscription
	}
	err = client.Execute(ctx, op, &respData)
	return respData.CreateGitWebhook, err
}

M srht/gitsrht/operations.graphql => srht/gitsrht/operations.graphql +6 -0
@@ 316,3 316,9 @@ mutation clearDescription($id: Int!) {
        name
    }
}

mutation createGitWebhook($config: GitWebhookInput!) {
    createGitWebhook(config: $config) {
        id
    }
}

M srht/gitsrht/strings.go => srht/gitsrht/strings.go +16 -0
@@ 64,3 64,19 @@ func ParseEvents(events []string) ([]WebhookEvent, error) {

	return whEvents, nil
}

func ParseGitWebhookEvents(events []string) ([]WebhookEvent, error) {
	var whEvents []WebhookEvent
	for _, event := range events {
		switch strings.ToLower(event) {
		case "git_pre_receive":
			whEvents = append(whEvents, WebhookEventGitPreReceive)
		case "git_post_receive":
			whEvents = append(whEvents, WebhookEventGitPostReceive)
		default:
			return whEvents, fmt.Errorf("invalid event: %q", event)
		}
	}

	return whEvents, nil
}