fj/cmd/notification_states.go

61 lines
1.6 KiB
Go
Raw Normal View History

feat: times, branch protection, release assets, milestone issues, notification states Five parallel tea-parity additions (~1100 LOC): - fgj time {list,add,delete,reset} (aliases: times, t) Tracked time entries. 'list' with no arg uses ListMyTrackedTimes across all your repos; with an issue number uses ListIssueTrackedTimes. 'add' accepts Go duration strings (30m, 1h30m). 'delete' removes a single entry by id; 'reset' clears all times on an issue. Confirmation on delete/reset unless --yes or no TTY. - fgj branch {protect,unprotect} Branch protection rules. 'protect' idempotently creates-or-edits via Get/Create/EditBranchProtection with --require-approvals, --require-signed-commits, --dismiss-stale-approvals, --block-on-rejected-reviews, --block-on-outdated-branch, --push-whitelist, --merge-whitelist, --require-status-checks. Empty whitelist flags leave existing rule fields untouched. 'unprotect' deletes; 404 is a friendly no-op. - fgj release asset {list,create,delete} (alias: assets) Granular attachment management. Resolves the release by tag or "latest" using the existing helpers in cmd/release.go. 'create' validates all paths up front then uploads each. 'delete' accepts numeric ids OR filenames (cross-references the attachment list). Per-asset confirmation unless --yes. - fgj milestone issues {add,remove} (alias: i) Associate/disassociate issues with a milestone. Milestone accepted as title or numeric id (reuses resolveMilestone from milestone.go). 'remove' passes EditIssueOption{Milestone: &zero} — the Gitea/Forgejo convention for clearing the association. Continues on per-issue failure and exits 1 if any failed. - fgj notification {unread,pin,unpin} Complement the existing list/read. Factory pattern over ReadNotification(id, NotifyStatus) with three distinct constants. All five files are self-contained: each has its own init() attaching to the existing parent cobra.Command (branchCmd, milestoneCmd, notificationCmd, releaseCmd) without modifying any other file. Built by parallel sub-agents; all compile, vet, and test clean.
2026-04-19 22:24:53 -06:00
package cmd
import (
"fmt"
"code.gitea.io/sdk/gitea"
"github.com/spf13/cobra"
)
var notificationUnreadCmd = &cobra.Command{
Use: "unread <id>",
Short: "Mark a notification as unread",
Long: "Mark a single notification thread as unread by its ID.",
Args: cobra.ExactArgs(1),
RunE: runNotificationState(gitea.NotifyStatusUnread, "unread"),
}
var notificationPinCmd = &cobra.Command{
Use: "pin <id>",
Short: "Pin a notification",
Long: "Mark a single notification thread as pinned by its ID.",
Args: cobra.ExactArgs(1),
RunE: runNotificationState(gitea.NotifyStatusPinned, "pinned"),
}
var notificationUnpinCmd = &cobra.Command{
Use: "unpin <id>",
Short: "Un-pin a notification",
Long: "Un-pin a notification thread (marks it as read).",
Args: cobra.ExactArgs(1),
RunE: runNotificationState(gitea.NotifyStatusRead, "unpinned"),
}
func init() {
notificationCmd.AddCommand(notificationUnreadCmd)
notificationCmd.AddCommand(notificationPinCmd)
notificationCmd.AddCommand(notificationUnpinCmd)
}
func runNotificationState(status gitea.NotifyStatus, verb string) func(*cobra.Command, []string) error {
return func(cmd *cobra.Command, args []string) error {
id, err := parseIssueArg(args[0])
if err != nil {
return fmt.Errorf("invalid notification id %q: %w", args[0], err)
}
client, err := loadClient()
if err != nil {
return err
}
if _, _, err := client.ReadNotification(id, status); err != nil {
return fmt.Errorf("failed to mark notification %d as %s: %w", id, verb, err)
}
cs := ios.ColorScheme()
fmt.Fprintf(ios.Out, "%s Marked notification %d as %s\n", cs.SuccessIcon(), id, verb)
return nil
}
}