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 }