mirror of
				https://gitea.com/gitea/tea.git
				synced 2025-10-30 16:55:25 +01:00 
			
		
		
		
	Add --fields to notification & milestone listings (#422)
				
					
				
			Together with #415 this finally adds the field flag to all entity listings. closes #342 ### ⚠️ breaking changes ⚠️ This changes the column names of `tea milestones ls`: ```diff - TITLE | OPEN/CLOSED ISSUES | DUEDATE + TITLE | ITEMS | DUEDATE ``` Co-authored-by: Norwin <git@nroo.de> Co-authored-by: 6543 <6543@obermui.de> Reviewed-on: https://gitea.com/gitea/tea/pulls/422 Reviewed-by: delvh <dev.lh@web.de> Reviewed-by: 6543 <6543@obermui.de> Co-authored-by: Norwin <noerw@noreply.gitea.io> Co-committed-by: Norwin <noerw@noreply.gitea.io>
This commit is contained in:
		| @@ -13,6 +13,10 @@ import ( | ||||
| 	"github.com/urfave/cli/v2" | ||||
| ) | ||||
|  | ||||
| var fieldsFlag = flags.FieldsFlag(print.MilestoneFields, []string{ | ||||
| 	"title", "items", "duedate", | ||||
| }) | ||||
|  | ||||
| // CmdMilestonesList represents a sub command of milestones to list milestones | ||||
| var CmdMilestonesList = cli.Command{ | ||||
| 	Name:        "list", | ||||
| @@ -22,6 +26,7 @@ var CmdMilestonesList = cli.Command{ | ||||
| 	ArgsUsage:   " ", // command does not accept arguments | ||||
| 	Action:      RunMilestonesList, | ||||
| 	Flags: append([]cli.Flag{ | ||||
| 		fieldsFlag, | ||||
| 		&cli.StringFlag{ | ||||
| 			Name:        "state", | ||||
| 			Usage:       "Filter by milestone state (all|open|closed)", | ||||
| @@ -37,10 +42,18 @@ func RunMilestonesList(cmd *cli.Context) error { | ||||
| 	ctx := context.InitCommand(cmd) | ||||
| 	ctx.Ensure(context.CtxRequirement{RemoteRepo: true}) | ||||
|  | ||||
| 	fields, err := fieldsFlag.GetValues(cmd) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	state := gitea.StateOpen | ||||
| 	switch ctx.String("state") { | ||||
| 	case "all": | ||||
| 		state = gitea.StateAll | ||||
| 		if !cmd.IsSet("fields") { // add to default fields | ||||
| 			fields = append(fields, "state") | ||||
| 		} | ||||
| 	case "closed": | ||||
| 		state = gitea.StateClosed | ||||
| 	} | ||||
| @@ -55,6 +68,6 @@ func RunMilestonesList(cmd *cli.Context) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	print.MilestonesList(milestones, ctx.Output, state) | ||||
| 	print.MilestonesList(milestones, ctx.Output, fields) | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -15,7 +15,11 @@ import ( | ||||
| 	"github.com/urfave/cli/v2" | ||||
| ) | ||||
|  | ||||
| var notifTypeFlag = flags.NewCsvFlag("types", "subject types to filter by", []string{"t"}, | ||||
| var notifyFieldsFlag = flags.FieldsFlag(print.NotificationFields, []string{ | ||||
| 	"id", "status", "index", "type", "state", "title", | ||||
| }) | ||||
|  | ||||
| var notifyTypeFlag = flags.NewCsvFlag("types", "subject types to filter by", []string{"t"}, | ||||
| 	[]string{"issue", "pull", "repository", "commit"}, nil) | ||||
|  | ||||
| // CmdNotificationsList represents a sub command of notifications to list notifications | ||||
| @@ -26,7 +30,10 @@ var CmdNotificationsList = cli.Command{ | ||||
| 	Description: `List notifications`, | ||||
| 	ArgsUsage:   " ", // command does not accept arguments | ||||
| 	Action:      RunNotificationsList, | ||||
| 	Flags:       append([]cli.Flag{notifTypeFlag}, flags.NotificationFlags...), | ||||
| 	Flags: append([]cli.Flag{ | ||||
| 		notifyFieldsFlag, | ||||
| 		notifyTypeFlag, | ||||
| 	}, flags.NotificationFlags...), | ||||
| } | ||||
|  | ||||
| // RunNotificationsList list notifications | ||||
| @@ -41,7 +48,7 @@ func RunNotificationsList(ctx *cli.Context) error { | ||||
| 	} | ||||
|  | ||||
| 	var types []gitea.NotifySubjectType | ||||
| 	typesStr, err := notifTypeFlag.GetValues(ctx) | ||||
| 	typesStr, err := notifyTypeFlag.GetValues(ctx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -67,7 +74,17 @@ func listNotifications(cmd *cli.Context, status []gitea.NotifyStatus, subjects [ | ||||
| 		listOpts.Page = 1 | ||||
| 	} | ||||
|  | ||||
| 	fields, err := notifyFieldsFlag.GetValues(cmd) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if all { | ||||
| 		// add repository to the default fields | ||||
| 		if !cmd.IsSet("fields") { | ||||
| 			fields = append(fields, "repository") | ||||
| 		} | ||||
|  | ||||
| 		news, _, err = client.ListNotifications(gitea.ListNotificationOptions{ | ||||
| 			ListOptions:  listOpts, | ||||
| 			Status:       status, | ||||
| @@ -85,6 +102,6 @@ func listNotifications(cmd *cli.Context, status []gitea.NotifyStatus, subjects [ | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	print.NotificationsList(news, ctx.Output, all) | ||||
| 	print.NotificationsList(news, ctx.Output, fields) | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -28,7 +28,7 @@ var CmdNotificationsMarkRead = cli.Command{ | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if !flags.NotificationStateFlag.IsSet() { | ||||
| 		if !cmd.IsSet(flags.NotificationStateFlag.Name) { | ||||
| 			filter = []string{string(gitea.NotifyStatusUnread)} | ||||
| 		} | ||||
| 		return markNotificationAs(cmd, filter, gitea.NotifyStatusRead) | ||||
| @@ -49,7 +49,7 @@ var CmdNotificationsMarkUnread = cli.Command{ | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if !flags.NotificationStateFlag.IsSet() { | ||||
| 		if !cmd.IsSet(flags.NotificationStateFlag.Name) { | ||||
| 			filter = []string{string(gitea.NotifyStatusRead)} | ||||
| 		} | ||||
| 		return markNotificationAs(cmd, filter, gitea.NotifyStatusUnread) | ||||
| @@ -70,7 +70,7 @@ var CmdNotificationsMarkPinned = cli.Command{ | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if !flags.NotificationStateFlag.IsSet() { | ||||
| 		if !cmd.IsSet(flags.NotificationStateFlag.Name) { | ||||
| 			filter = []string{string(gitea.NotifyStatusUnread)} | ||||
| 		} | ||||
| 		return markNotificationAs(cmd, filter, gitea.NotifyStatusPinned) | ||||
|   | ||||
| @@ -24,40 +24,65 @@ func MilestoneDetails(milestone *gitea.Milestone) { | ||||
| } | ||||
|  | ||||
| // MilestonesList prints a listing of milestones | ||||
| func MilestonesList(miles []*gitea.Milestone, output string, state gitea.StateType) { | ||||
| 	headers := []string{ | ||||
| 		"Title", | ||||
| func MilestonesList(news []*gitea.Milestone, output string, fields []string) { | ||||
| 	var printables = make([]printable, len(news)) | ||||
| 	for i, x := range news { | ||||
| 		printables[i] = &printableMilestone{x} | ||||
| 	} | ||||
| 	if state == gitea.StateAll { | ||||
| 		headers = append(headers, "State") | ||||
| 	} | ||||
| 	headers = append(headers, | ||||
| 		"Open/Closed Issues", | ||||
| 		"DueDate", | ||||
| 	) | ||||
|  | ||||
| 	t := table{headers: headers} | ||||
|  | ||||
| 	for _, m := range miles { | ||||
| 		var deadline = "" | ||||
|  | ||||
| 		if m.Deadline != nil && !m.Deadline.IsZero() { | ||||
| 			deadline = FormatTime(*m.Deadline, isMachineReadable(output)) | ||||
| 		} | ||||
|  | ||||
| 		item := []string{ | ||||
| 			m.Title, | ||||
| 		} | ||||
| 		if state == gitea.StateAll { | ||||
| 			item = append(item, string(m.State)) | ||||
| 		} | ||||
| 		item = append(item, | ||||
| 			fmt.Sprintf("%d/%d", m.OpenIssues, m.ClosedIssues), | ||||
| 			deadline, | ||||
| 		) | ||||
| 		t.addRowSlice(item) | ||||
| 	} | ||||
|  | ||||
| 	t := tableFromItems(fields, printables, isMachineReadable(output)) | ||||
| 	t.sort(0, true) | ||||
| 	t.print(output) | ||||
| } | ||||
|  | ||||
| // MilestoneFields are all available fields to print with MilestonesList | ||||
| var MilestoneFields = []string{ | ||||
| 	"title", | ||||
| 	"state", | ||||
| 	"items_open", | ||||
| 	"items_closed", | ||||
| 	"items", | ||||
| 	"duedate", | ||||
| 	"description", | ||||
| 	"created", | ||||
| 	"updated", | ||||
| 	"closed", | ||||
| 	"id", | ||||
| } | ||||
|  | ||||
| type printableMilestone struct { | ||||
| 	*gitea.Milestone | ||||
| } | ||||
|  | ||||
| func (m printableMilestone) FormatField(field string, machineReadable bool) string { | ||||
| 	switch field { | ||||
| 	case "title": | ||||
| 		return m.Title | ||||
| 	case "state": | ||||
| 		return string(m.State) | ||||
| 	case "items_open": | ||||
| 		return fmt.Sprintf("%d", m.OpenIssues) | ||||
| 	case "items_closed": | ||||
| 		return fmt.Sprintf("%d", m.ClosedIssues) | ||||
| 	case "items": | ||||
| 		return fmt.Sprintf("%d/%d", m.OpenIssues, m.ClosedIssues) | ||||
| 	case "duedate": | ||||
| 		if m.Deadline != nil && !m.Deadline.IsZero() { | ||||
| 			return FormatTime(*m.Deadline, machineReadable) | ||||
| 		} | ||||
| 	case "id": | ||||
| 		return fmt.Sprintf("%d", m.ID) | ||||
| 	case "description": | ||||
| 		return m.Description | ||||
| 	case "created": | ||||
| 		return FormatTime(m.Created, machineReadable) | ||||
| 	case "updated": | ||||
| 		if m.Updated != nil { | ||||
| 			return FormatTime(*m.Updated, machineReadable) | ||||
| 		} | ||||
| 	case "closed": | ||||
| 		if m.Closed != nil { | ||||
| 			return FormatTime(*m.Closed, machineReadable) | ||||
| 		} | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|   | ||||
| @@ -12,26 +12,51 @@ import ( | ||||
| ) | ||||
|  | ||||
| // NotificationsList prints a listing of notification threads | ||||
| func NotificationsList(news []*gitea.NotificationThread, output string, showRepository bool) { | ||||
| 	headers := []string{ | ||||
| 		"ID", | ||||
| 		"Status", | ||||
| 		"Type", | ||||
| 		"State", | ||||
| 		"Index", | ||||
| 		"Title", | ||||
| func NotificationsList(news []*gitea.NotificationThread, output string, fields []string) { | ||||
| 	var printables = make([]printable, len(news)) | ||||
| 	for i, x := range news { | ||||
| 		printables[i] = &printableNotification{x} | ||||
| 	} | ||||
| 	if showRepository { | ||||
| 		headers = append(headers, "Repository") | ||||
| 	t := tableFromItems(fields, printables, isMachineReadable(output)) | ||||
| 	t.print(output) | ||||
| } | ||||
|  | ||||
| 	t := table{headers: headers} | ||||
| // NotificationFields are all available fields to print with NotificationsList | ||||
| var NotificationFields = []string{ | ||||
| 	"id", | ||||
| 	"status", | ||||
| 	"updated", | ||||
|  | ||||
| 	for _, n := range news { | ||||
| 		if n.Subject == nil { | ||||
| 			continue | ||||
| 	// these are about the notification subject | ||||
| 	"index", | ||||
| 	"type", | ||||
| 	"state", | ||||
| 	"title", | ||||
| 	"repository", | ||||
| } | ||||
| 		// if pull or Issue get Index | ||||
|  | ||||
| type printableNotification struct { | ||||
| 	*gitea.NotificationThread | ||||
| } | ||||
|  | ||||
| func (n printableNotification) FormatField(field string, machineReadable bool) string { | ||||
| 	switch field { | ||||
| 	case "id": | ||||
| 		return fmt.Sprintf("%d", n.ID) | ||||
|  | ||||
| 	case "status": | ||||
| 		status := "read" | ||||
| 		if n.Pinned { | ||||
| 			status = "pinned" | ||||
| 		} else if n.Unread { | ||||
| 			status = "unread" | ||||
| 		} | ||||
| 		return status | ||||
|  | ||||
| 	case "updated": | ||||
| 		return FormatTime(n.UpdatedAt, machineReadable) | ||||
|  | ||||
| 	case "index": | ||||
| 		var index string | ||||
| 		if n.Subject.Type == "Issue" || n.Subject.Type == "Pull" { | ||||
| 			index = n.Subject.URL | ||||
| @@ -39,31 +64,20 @@ func NotificationsList(news []*gitea.NotificationThread, output string, showRepo | ||||
| 			if len(urlParts) != 0 { | ||||
| 				index = urlParts[len(urlParts)-1] | ||||
| 			} | ||||
| 			index = "#" + index | ||||
| 		} | ||||
| 		return index | ||||
|  | ||||
| 		status := "read" | ||||
| 		if n.Pinned { | ||||
| 			status = "pinned" | ||||
| 		} else if n.Unread { | ||||
| 			status = "unread" | ||||
| 		} | ||||
| 	case "type": | ||||
| 		return string(n.Subject.Type) | ||||
|  | ||||
| 		item := []string{ | ||||
| 			fmt.Sprint(n.ID), | ||||
| 			status, | ||||
| 			string(n.Subject.Type), | ||||
| 			string(n.Subject.State), | ||||
| 			index, | ||||
| 			n.Subject.Title, | ||||
| 		} | ||||
| 		if showRepository { | ||||
| 			item = append(item, n.Repository.FullName) | ||||
| 		} | ||||
| 		t.addRowSlice(item) | ||||
| 	} | ||||
| 	case "state": | ||||
| 		return string(n.Subject.State) | ||||
|  | ||||
| 	if t.Len() != 0 { | ||||
| 		t.print(output) | ||||
| 	case "title": | ||||
| 		return n.Subject.Title | ||||
|  | ||||
| 	case "repo", "repository": | ||||
| 		return n.Repository.FullName | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Norwin
					Norwin