Add the command `hub issue view <NUMBER>`

This commit adds the subcommand hub issue view, which displays an issue as well as
lists its comments underneath.
This commit is contained in:
royels 2018-10-29 02:02:32 -07:00 коммит произвёл Mislav Marohnić
Родитель b15d8de5e4
Коммит 6b5997f974
3 изменённых файлов: 193 добавлений и 0 удалений

Просмотреть файл

@ -20,6 +20,7 @@ var (
issue [-a <ASSIGNEE>] [-c <CREATOR>] [-@ <USER>] [-s <STATE>] [-f <FORMAT>] [-M <MILESTONE>] [-l <LABELS>] [-d <DATE>] [-o <SORT_KEY> [-^]] [-L <LIMIT>]
issue create [-oc] [-m <MESSAGE>|-F <FILE>] [--edit] [-a <USERS>] [-M <MILESTONE>] [-l <LABELS>]
issue labels [--color]
issue show <NUMBER>
`,
Long: `Manage GitHub issues for the current project.
@ -153,6 +154,13 @@ With no arguments, show a list of open issues.
Long: "Open an issue in the current project.",
}
cmdShowIssue = &Command{
Key: "show",
Run: showIssue,
Usage: "issue show <NUMBER>",
Long: "Show an issue in the current project.",
}
cmdLabel = &Command{
Key: "labels",
Run: listLabels,
@ -213,6 +221,7 @@ func init() {
cmdLabel.Flag.BoolVarP(&flagLabelsColorize, "color", "", false, "COLORIZE")
cmdIssue.Use(cmdShowIssue)
cmdIssue.Use(cmdCreateIssue)
cmdIssue.Use(cmdLabel)
CmdRunner.Use(cmdIssue)
@ -371,6 +380,68 @@ func formatIssue(issue github.Issue, format string, colorize bool) string {
return ui.Expand(format, placeholders, colorize)
}
func showIssue(cmd *Command, args *Args) {
issueNumber := cmd.Arg(0)
if issueNumber == "" {
utils.Check(fmt.Errorf(cmd.Synopsis()))
}
localRepo, err := github.LocalRepo()
utils.Check(err)
project, err := localRepo.MainProject()
utils.Check(err)
gh := github.NewClient(project.Host)
var issue = &github.Issue{}
issue, err = gh.FetchIssue(project, issueNumber)
utils.Check(err)
var closed = ""
if issue.State != "open" {
closed = "[CLOSED] "
}
commentsList, err := gh.FetchComments(project, issueNumber)
utils.Check(err)
var assignees []string
var assigneesString = ""
if len(issue.Assignees) > 0 {
for _, user := range issue.Assignees {
assignees = append(assignees, user.Login)
}
assigneesString = fmt.Sprintf("* assignees: %s\n\n", strings.Join(assignees, ", "))
}
var comments []string
var commentsString = ""
if issue.Comments > 0 {
for _, comment := range commentsList {
comments = append(comments, fmt.Sprintf(
"### comment by @%s on %s\n\n"+
"%s\n", comment.User.Login, comment.CreatedAt.String(), comment.Body))
}
commentsString = fmt.Sprintf("\n## Comments:\n\n%s", strings.Join(comments, ""))
}
ui.Printf("# %s\n\n"+
"* created by @%s on %s\n"+
"%s"+
"%s\n"+
"%s",
closed+issue.Title,
issue.User.Login,
issue.CreatedAt.String(),
assigneesString,
issue.Body,
commentsString)
args.NoForward()
return
}
func createIssue(cmd *Command, args *Args) {
localRepo, err := github.LocalRepo()
utils.Check(err)

Просмотреть файл

@ -530,3 +530,84 @@ Feature: hub issue
bug
feature\n
"""
Scenario: Fetch single issue
Given the GitHub API server:
"""
get('/repos/github/hub/issues/102') { json \
:number => 102,
:state => "open",
:body => "I want this feature",
:title => "Feature request for hub issue show",
:created_at => "2017-04-14T16:00:49Z",
:user => { :login => "royels" },
:assignees => [{:login => "royels"}],
:comments => 1
}
get('/repos/github/hub/issues/102/comments') {
json [{
:id => 1,
:body => "I am from the future",
:created_at => "2011-04-14T16:00:49Z",
:user => { :login => "octocat" }}
]
}
"""
When I successfully run `hub issue show 102`
Then the output should contain exactly:
"""
# Feature request for hub issue show
* created by @royels on 2017-04-14 16:00:49 +0000 UTC
* assignees: royels
I want this feature
## Comments:
### comment by @octocat on 2011-04-14 16:00:49 +0000 UTC
I am from the future
"""
Scenario: Did not supply an issue number
When I run `hub issue show`
Then the exit status should be 1
Then the output should contain exactly "Usage: hub issue show <NUMBER>\n"
Scenario: Show error message if http code is not 200 for issues endpoint
Given the GitHub API server:
"""
get('/repos/github/hub/issues/102') {
status 500
}
"""
When I run `hub issue show 102`
Then the output should contain exactly:
"""
Error fetching issue: Internal Server Error (HTTP 500)\n
"""
Scenario: Show error message if http code is not 200 for comments endpoint
Given the GitHub API server:
"""
get('/repos/github/hub/issues/102') { json \
:number => 102,
:body => "I want this feature",
:title => "Feature request for hub issue show",
:created_at => "2017-04-14T16:00:49Z",
:user => { :login => "royels" }
}
get('/repos/github/hub/issues/102/comments') {
status 404
}
"""
When I run `hub issue show 102`
Then the output should contain exactly:
"""
Error fetching comments for issue: Not Found (HTTP 404)\n
"""

Просмотреть файл

@ -525,6 +525,13 @@ func (client *Client) ForkRepository(project *Project, params map[string]interfa
return
}
type Comment struct {
Id int `json:"id"`
Body string `json:"body"`
User *User `json:"user"`
CreatedAt time.Time `json:"created_at"`
}
type Issue struct {
Number int `json:"number"`
State string `json:"state"`
@ -550,6 +557,8 @@ type Issue struct {
ApiUrl string `json:"url"`
HtmlUrl string `json:"html_url"`
ClosedBy *User `json:"closed_by"`
}
type PullRequest Issue
@ -649,6 +658,38 @@ func (client *Client) FetchIssues(project *Project, filterParams map[string]inte
return
}
func (client *Client) FetchIssue(project *Project, number string) (issue *Issue, err error) {
api, err := client.simpleApi()
if err != nil {
return
}
res, err := api.Get(fmt.Sprintf("repos/%s/%s/issues/%s", project.Owner, project.Name, number))
if err = checkStatus(200, "fetching issue", res, err); err != nil {
return nil, err
}
issue = &Issue{}
err = res.Unmarshal(issue)
return
}
func (client *Client) FetchComments(project *Project, number string) (comments []Comment, err error) {
api, err := client.simpleApi()
if err != nil {
return
}
res, err := api.Get(fmt.Sprintf("repos/%s/%s/issues/%s/comments", project.Owner, project.Name, number))
if err = checkStatus(200, "fetching comments for issue", res, err); err != nil {
return nil, err
}
comments = []Comment{}
err = res.Unmarshal(&comments)
return
}
func (client *Client) CreateIssue(project *Project, params interface{}) (issue *Issue, err error) {
api, err := client.simpleApi()
if err != nil {