Pretty similar to `hut todo ticket comment`, except we need to
provide both a subject and a body. Add commented instructions when
using an editor, similar to git-commit's behavior.
---
doc/hut.1.scd | 8 +++
srht/todosrht/gql.go | 11 +++++
srht/todosrht/operations.graphql | 6 +++
todo.go | 85 ++++++++++++++++++++++++++++++++
4 files changed, 110 insertions(+)
diff --git a/doc/hut.1.scd b/doc/hut.1.scd
index ef4291fc8ad7..5dc1307b2b19 100644
--- a/doc/hut.1.scd
+++ b/doc/hut.1.scd
@@ -640,6 +640,14 @@ Options are:
*--stdin*
Read comment from _stdin_.
+*ticket create*
+ Create a new ticket with _$EDITOR_.
+
+ Options are:
+
+ *--stdin*
+ Read ticket from _stdin_.
+
*ticket delete* <ID> [options...]
Delete a ticket.
diff --git a/srht/todosrht/gql.go b/srht/todosrht/gql.go
index 9330741bcae9..77f1874ecaea 100644
--- a/srht/todosrht/gql.go
+++ b/srht/todosrht/gql.go
@@ -1134,3 +1134,14 @@ func DeleteTrackerWebhook(client *gqlclient.Client, ctx context.Context, id int3
err = client.Execute(ctx, op, &respData)
return respData.DeleteTrackerWebhook, err
}
+
+func SubmitTicket(client *gqlclient.Client, ctx context.Context, trackerId int32, input SubmitTicketInput) (submitTicket *Ticket, err error) {
+ op := gqlclient.NewOperation("mutation submitTicket ($trackerId: Int!, $input: SubmitTicketInput!) {\n\tsubmitTicket(trackerId: $trackerId, input: $input) {\n\t\tid\n\t}\n}\n")
+ op.Var("trackerId", trackerId)
+ op.Var("input", input)
+ var respData struct {
+ SubmitTicket *Ticket
+ }
+ err = client.Execute(ctx, op, &respData)
+ return respData.SubmitTicket, err
+}
diff --git a/srht/todosrht/operations.graphql b/srht/todosrht/operations.graphql
index c8db6201934e..3e316d424e4b 100644
--- a/srht/todosrht/operations.graphql
+++ b/srht/todosrht/operations.graphql
@@ -541,3 +541,9 @@ mutation deleteTrackerWebhook($id: Int!) {
id
}
}
+
+mutation submitTicket($trackerId: Int!, $input: SubmitTicketInput!) {
+ submitTicket(trackerId: $trackerId, input: $input) {
+ id
+ }
+}
diff --git a/todo.go b/todo.go
index e5046030bf63..43124dd8508e 100644
--- a/todo.go
+++ b/todo.go
@@ -1,6 +1,7 @@
package main
import (
+ "bufio"
"context"
"errors"
"fmt"
@@ -272,6 +273,7 @@ func newTodoTicketCommand() *cobra.Command {
cmd.AddCommand(newTodoTicketDeleteCommand())
cmd.AddCommand(newTodoTicketShowCommand())
cmd.AddCommand(newTodoTicketWebhookCommand())
+ cmd.AddCommand(newTodoTicketCreateCommand())
return cmd
}
@@ -1382,6 +1384,89 @@ func newTodoUserWebhookDeleteCommand() *cobra.Command {
return cmd
}
+const todoTicketCreatePrefill = `
+<!--
+Please enter the subject of the new ticket above. The subject line
+can be followed by a blank line and a Markdown description. An
+empty subject aborts the ticket.
+-->`
+
+func newTodoTicketCreateCommand() *cobra.Command {
+ var stdin bool
+ run := func(cmd *cobra.Command, args []string) {
+ ctx := cmd.Context()
+ name, owner, instance, err := getTrackerName(ctx, cmd)
+ if err != nil {
+ log.Fatal(err)
+ }
+ c := createClientWithInstance("todo", cmd, instance)
+ trackerID := getTrackerID(c, ctx, name, owner)
+
+ var input todosrht.SubmitTicketInput
+ if stdin {
+ br := bufio.NewReader(os.Stdin)
+ fmt.Printf("Subject: ")
+
+ var err error
+ input.Subject, err = br.ReadString('\n')
+ if err != nil {
+ log.Fatalf("failed to read subject: %v", err)
+ }
+ input.Subject = strings.TrimSpace(input.Subject)
+ if input.Subject == "" {
+ fmt.Println("Aborting due to empty subject.")
+ os.Exit(1)
+ }
+
+ fmt.Printf("Description %s:\n", termfmt.Dim.String("(Markdown supported)"))
+ bodyBytes, err := io.ReadAll(br)
+ if err != nil {
+ log.Fatalf("failed to read description: %v", err)
+ }
+ if body := strings.TrimSpace(string(bodyBytes)); body != "" {
+ input.Body = &body
+ }
+ } else {
+ text, err := getInputWithEditor("hut_ticket*.md", todoTicketCreatePrefill)
+ if err != nil {
+ log.Fatalf("failed to read ticket subject and description: %v", err)
+ }
+
+ text = dropComment(text, todoTicketCreatePrefill)
+
+ parts := strings.SplitN(text, "\n", 2)
+ input.Subject = strings.TrimSpace(parts[0])
+ if len(parts) > 1 {
+ body := strings.TrimSpace(parts[1])
+ input.Body = &body
+ }
+ }
+
+ if input.Subject == "" {
+ fmt.Println("Aborting due to empty subject.")
+ os.Exit(1)
+ }
+
+ ticket, err := todosrht.SubmitTicket(c.Client, ctx, trackerID, input)
+ if err != nil {
+ log.Fatal(err)
+ } else if ticket == nil {
+ log.Fatal("failed to create ticket")
+ }
+
+ fmt.Printf("Created new ticket %v\n", termfmt.DarkYellow.Sprintf("#%v", ticket.Id))
+ }
+
+ cmd := &cobra.Command{
+ Use: "create",
+ Short: "Create a new ticket",
+ Args: cobra.ExactArgs(0),
+ Run: run,
+ }
+ cmd.Flags().BoolVar(&stdin, "stdin", false, "read ticket from stdin")
+ return cmd
+}
+
func getTrackerID(c *Client, ctx context.Context, name, owner string) int32 {
var (
user *todosrht.User
--
2.39.1
On Fri, Mar 10, 2023 at 04:23:35PM +0100, jlk wrote:
> Good day,
>
> it's me again, the guy packaging hut for openSUSE and asking for a new
> release occasionally. :)
> The recently merged feature to create tickets via todo is something that I
> waited for and I am quite happy that it is included now, therefore I would
> like to update my package.
> What do you think about a new release as v0.2.0 is now 7 months old?
Hello,
Even though hut has not received a lot of commits since the last
release, there are a few features that were repeatedly asked for (pager,
ticket creation, git custom README, pages cache control, pages publish
increased timeout), so a release could be beneficial for lots of users.
I would at least like to get in artifact support [1] (should send a
patch soon-ish) and improved todo label support (blocked by [2]).
>
> On a broader note: Is it ok that I contact you like this from time to time
> to ask for a release or would you prefer me to handle this differently?
>
> Best regards
> Jan-Luca
I certainly don't mind, but it would probably be better to start a new
thread instead of replying to a patch.
Kind regards
[1]: https://todo.sr.ht/~emersion/hut/26
[2]: https://lists.sr.ht/~sircmpwn/sr.ht-dev/patches/39702