feat: allow tags passing when creating/editing an issue

resolves #27
This commit is contained in:
Romain Bertrand 2026-02-20 17:41:45 +01:00
parent 65c686997f
commit 0b8f67e438

View file

@ -84,6 +84,7 @@ func init() {
issueCreateCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format") issueCreateCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
issueCreateCmd.Flags().StringP("title", "t", "", "Title for the issue") issueCreateCmd.Flags().StringP("title", "t", "", "Title for the issue")
issueCreateCmd.Flags().StringP("body", "b", "", "Body for the issue") issueCreateCmd.Flags().StringP("body", "b", "", "Body for the issue")
issueCreateCmd.Flags().StringSliceP("label", "l", nil, "Labels to add (can be specified multiple times)")
issueCommentCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format") issueCommentCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
issueCommentCmd.Flags().StringP("body", "b", "", "Comment body") issueCommentCmd.Flags().StringP("body", "b", "", "Comment body")
@ -95,6 +96,8 @@ func init() {
issueEditCmd.Flags().StringP("title", "t", "", "New title for the issue") issueEditCmd.Flags().StringP("title", "t", "", "New title for the issue")
issueEditCmd.Flags().StringP("body", "b", "", "New body for the issue") issueEditCmd.Flags().StringP("body", "b", "", "New body for the issue")
issueEditCmd.Flags().StringP("state", "s", "", "New state for the issue (open or closed)") issueEditCmd.Flags().StringP("state", "s", "", "New state for the issue (open or closed)")
issueEditCmd.Flags().StringSlice("add-label", nil, "Labels to add (can be specified multiple times)")
issueEditCmd.Flags().StringSlice("remove-label", nil, "Labels to remove (can be specified multiple times)")
} }
func runIssueList(cmd *cobra.Command, args []string) error { func runIssueList(cmd *cobra.Command, args []string) error {
@ -233,6 +236,7 @@ func runIssueCreate(cmd *cobra.Command, args []string) error {
repo, _ := cmd.Flags().GetString("repo") repo, _ := cmd.Flags().GetString("repo")
title, _ := cmd.Flags().GetString("title") title, _ := cmd.Flags().GetString("title")
body, _ := cmd.Flags().GetString("body") body, _ := cmd.Flags().GetString("body")
labelNames, _ := cmd.Flags().GetStringSlice("label")
owner, name, err := parseRepo(repo) owner, name, err := parseRepo(repo)
if err != nil { if err != nil {
@ -253,9 +257,18 @@ func runIssueCreate(cmd *cobra.Command, args []string) error {
return err return err
} }
var labelIDs []int64
if len(labelNames) > 0 {
labelIDs, err = resolveLabelIDs(client, owner, name, labelNames)
if err != nil {
return err
}
}
issue, _, err := client.CreateIssue(owner, name, gitea.CreateIssueOption{ issue, _, err := client.CreateIssue(owner, name, gitea.CreateIssueOption{
Title: title, Title: title,
Body: body, Body: body,
Labels: labelIDs,
}) })
if err != nil { if err != nil {
return fmt.Errorf("failed to create issue: %w", err) return fmt.Errorf("failed to create issue: %w", err)
@ -357,6 +370,8 @@ func runIssueEdit(cmd *cobra.Command, args []string) error {
title, _ := cmd.Flags().GetString("title") title, _ := cmd.Flags().GetString("title")
body, _ := cmd.Flags().GetString("body") body, _ := cmd.Flags().GetString("body")
stateStr, _ := cmd.Flags().GetString("state") stateStr, _ := cmd.Flags().GetString("state")
addLabelNames, _ := cmd.Flags().GetStringSlice("add-label")
removeLabelNames, _ := cmd.Flags().GetStringSlice("remove-label")
issueNumber, err := strconv.ParseInt(args[0], 10, 64) issueNumber, err := strconv.ParseInt(args[0], 10, 64)
if err != nil { if err != nil {
@ -368,8 +383,8 @@ func runIssueEdit(cmd *cobra.Command, args []string) error {
return err return err
} }
if title == "" && body == "" && stateStr == "" { if title == "" && body == "" && stateStr == "" && len(addLabelNames) == 0 && len(removeLabelNames) == 0 {
return fmt.Errorf("at least one of --title, --body, or --state must be provided") return fmt.Errorf("at least one of --title, --body, --state, --add-label, or --remove-label must be provided")
} }
cfg, err := config.Load() cfg, err := config.Load()
@ -405,12 +420,73 @@ func runIssueEdit(cmd *cobra.Command, args []string) error {
} }
} }
_, _, err = client.EditIssue(owner, name, issueNumber, editOpt) if title != "" || body != "" || stateStr != "" {
if err != nil { _, _, err = client.EditIssue(owner, name, issueNumber, editOpt)
return fmt.Errorf("failed to edit issue: %w", err) if err != nil {
return fmt.Errorf("failed to edit issue: %w", err)
}
}
if len(addLabelNames) > 0 {
labelIDs, err := resolveLabelIDs(client, owner, name, addLabelNames)
if err != nil {
return err
}
_, _, err = client.AddIssueLabels(owner, name, issueNumber, gitea.IssueLabelsOption{
Labels: labelIDs,
})
if err != nil {
return fmt.Errorf("failed to add labels: %w", err)
}
}
if len(removeLabelNames) > 0 {
labelIDs, err := resolveLabelIDs(client, owner, name, removeLabelNames)
if err != nil {
return err
}
for _, labelID := range labelIDs {
_, err = client.DeleteIssueLabel(owner, name, issueNumber, labelID)
if err != nil {
return fmt.Errorf("failed to remove label %d: %w", labelID, err)
}
}
} }
fmt.Printf("Issue #%d updated\n", issueNumber) fmt.Printf("Issue #%d updated\n", issueNumber)
return nil return nil
} }
func resolveLabelIDs(client *api.Client, owner, name string, labelNames []string) ([]int64, error) {
if len(labelNames) == 0 {
return nil, nil
}
labels, _, err := client.ListRepoLabels(owner, name, gitea.ListLabelsOptions{})
if err != nil {
return nil, fmt.Errorf("failed to list labels: %w", err)
}
labelNameToID := make(map[string]int64)
for _, label := range labels {
labelNameToID[label.Name] = label.ID
}
var labelIDs []int64
var missingLabels []string
for _, labelName := range labelNames {
labelID, exists := labelNameToID[labelName]
if !exists {
missingLabels = append(missingLabels, labelName)
continue
}
labelIDs = append(labelIDs, labelID)
}
if len(missingLabels) > 0 {
return nil, fmt.Errorf("labels not found: %s", strings.Join(missingLabels, ", "))
}
return labelIDs, nil
}