github.com/zaquestion/lab@v0.25.1/cmd/issue_show.go (about)

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"time"
     7  
     8  	"github.com/MakeNowJust/heredoc/v2"
     9  	"github.com/charmbracelet/glamour"
    10  	"github.com/rsteube/carapace"
    11  	"github.com/spf13/cobra"
    12  	gitlab "github.com/xanzy/go-gitlab"
    13  	"github.com/zaquestion/lab/internal/action"
    14  	lab "github.com/zaquestion/lab/internal/gitlab"
    15  )
    16  
    17  var issueShowCmd = &cobra.Command{
    18  	Use:        "show [remote] <id>",
    19  	Aliases:    []string{"get"},
    20  	ArgAliases: []string{"s"},
    21  	Short:      "Describe an issue",
    22  	Example: heredoc.Doc(`
    23  		lab issue show 1
    24  		lab issue show origin 1 -c
    25  		lab issue show upstream 1 -M
    26  		lab issue show upstream 1 --since "1970-01-01 00:00:00.000 +0000 UTC"`),
    27  	PersistentPreRun: labPersistentPreRun,
    28  	Run: func(cmd *cobra.Command, args []string) {
    29  
    30  		rn, issueNum, err := parseArgsRemoteAndID(args)
    31  		if err != nil {
    32  			log.Fatal(err)
    33  		}
    34  		if issueNum == 0 {
    35  			log.Fatalf("Specify <id> of issue to be shown")
    36  		}
    37  
    38  		issue, err := lab.IssueGet(rn, int(issueNum))
    39  		if err != nil {
    40  			log.Fatal(err)
    41  		}
    42  
    43  		renderMarkdown := false
    44  		if isOutputTerminal() {
    45  			noMarkdown, _ := cmd.Flags().GetBool("no-markdown")
    46  			if err != nil {
    47  				log.Fatal(err)
    48  			}
    49  			renderMarkdown = !noMarkdown
    50  		}
    51  
    52  		pager := newPager(cmd.Flags())
    53  		defer pager.Close()
    54  
    55  		printIssue(issue, rn, renderMarkdown)
    56  
    57  		var noteLevel = NoteLevelNone
    58  
    59  		showComments, _ := cmd.Flags().GetBool("comments")
    60  		showActivities, _ := cmd.Flags().GetBool("activities")
    61  		showFull, _ := cmd.Flags().GetBool("full")
    62  
    63  		if showFull || showComments && showActivities {
    64  			noteLevel = NoteLevelFull
    65  		} else if showComments {
    66  			noteLevel = NoteLevelComments
    67  		} else if showActivities {
    68  			noteLevel = NoteLevelActivities
    69  		}
    70  
    71  		if noteLevel != NoteLevelNone {
    72  			discussions, err := lab.IssueListDiscussions(rn, int(issueNum))
    73  			if err != nil {
    74  				log.Fatal(err)
    75  			}
    76  
    77  			since, err := cmd.Flags().GetString("since")
    78  			if err != nil {
    79  				log.Fatal(err)
    80  			}
    81  
    82  			printDiscussions(rn, discussions, since, "issues", int(issueNum), renderMarkdown, noteLevel)
    83  		}
    84  	},
    85  }
    86  
    87  func printIssue(issue *gitlab.Issue, project string, renderMarkdown bool) {
    88  	milestone := "None"
    89  	timestats := "None"
    90  	dueDate := "None"
    91  	subscribed := "No"
    92  	state := map[string]string{
    93  		"opened": "Open",
    94  		"closed": "Closed",
    95  	}[issue.State]
    96  	if issue.Milestone != nil {
    97  		milestone = issue.Milestone.Title
    98  	}
    99  	if issue.TimeStats != nil && issue.TimeStats.HumanTimeEstimate != "" &&
   100  		issue.TimeStats.HumanTotalTimeSpent != "" {
   101  		timestats = fmt.Sprintf(
   102  			"Estimated %s, Spent %s",
   103  			issue.TimeStats.HumanTimeEstimate,
   104  			issue.TimeStats.HumanTotalTimeSpent)
   105  	}
   106  	if issue.DueDate != nil {
   107  		dueDate = time.Time(*issue.DueDate).String()
   108  	}
   109  	assignees := make([]string, len(issue.Assignees))
   110  	if len(issue.Assignees) > 0 && issue.Assignees[0].Username != "" {
   111  		for i, a := range issue.Assignees {
   112  			assignees[i] = a.Username
   113  		}
   114  	}
   115  
   116  	if renderMarkdown {
   117  		r, err := getTermRenderer(glamour.WithAutoStyle())
   118  		if err != nil {
   119  			log.Fatal(err)
   120  		}
   121  		issue.Description, _ = r.Render(issue.Description)
   122  	}
   123  
   124  	relatedMRs, err := lab.ListMRsRelatedToIssue(project, issue.IID)
   125  	if err != nil {
   126  		log.Fatal(err)
   127  	}
   128  	closingMRs, err := lab.ListMRsClosingIssue(project, issue.IID)
   129  	if err != nil {
   130  		log.Fatal(err)
   131  	}
   132  
   133  	if issue.Subscribed {
   134  		subscribed = "Yes"
   135  	}
   136  
   137  	fmt.Printf(
   138  		heredoc.Doc(`#%d %s
   139  			===================================
   140  			%s
   141  			-----------------------------------
   142  			Project: %s
   143  			Status: %s
   144  			Assignees: %s
   145  			Author: %s
   146  			Milestone: %s
   147  			Due Date: %s
   148  			Time Stats: %s
   149  			Labels: %s
   150  			Related MRs: %s
   151  			MRs that will close this Issue: %s
   152  			Subscribed: %s
   153  			WebURL: %s
   154  		`),
   155  		issue.IID, issue.Title, issue.Description, project, state, strings.Join(assignees, ", "),
   156  		issue.Author.Username, milestone, dueDate, timestats,
   157  		strings.Join(issue.Labels, ", "),
   158  		strings.Trim(strings.Replace(fmt.Sprint(relatedMRs), " ", ",", -1), "[]"),
   159  		strings.Trim(strings.Replace(fmt.Sprint(closingMRs), " ", ",", -1), "[]"),
   160  		subscribed, issue.WebURL,
   161  	)
   162  }
   163  
   164  func init() {
   165  	issueShowCmd.Flags().BoolP("no-markdown", "M", false, "don't use markdown renderer to print the issue description")
   166  	issueShowCmd.Flags().BoolP("comments", "c", false, "show only comments for the issue")
   167  	issueShowCmd.Flags().BoolP("activities", "a", false, "show only activities for the issue")
   168  	issueShowCmd.Flags().BoolP("full", "f", false, "show both activities and comments for the issue")
   169  	issueShowCmd.Flags().StringP("since", "s", "", "show comments since specified date (format: 2020-08-21 14:57:46.808 +0000 UTC)")
   170  	issueCmd.AddCommand(issueShowCmd)
   171  
   172  	carapace.Gen(issueShowCmd).PositionalCompletion(
   173  		action.Remotes(),
   174  		action.Issues(issueList),
   175  	)
   176  }