Files
github-api/jacoco/org.kohsuke.github/GHIssue.java.html
2021-01-05 18:12:07 -08:00

725 lines
26 KiB
HTML

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>GHIssue.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">GitHub API for Java</a> &gt; <a href="index.source.html" class="el_package">org.kohsuke.github</a> &gt; <span class="el_source">GHIssue.java</span></div><h1>GHIssue.java</h1><pre class="source lang-java linenums">/*
* The MIT License
*
* Copyright (c) 2011, Eric Maupin, Kohsuke Kawaguchi
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the &quot;Software&quot;), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.kohsuke.github;
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import static org.kohsuke.github.internal.Previews.SQUIRREL_GIRL;
/**
* Represents an issue on GitHub.
*
* @author Eric Maupin
* @author Kohsuke Kawaguchi
* @see GHRepository#getIssue(int) GHRepository#getIssue(int)
* @see GitHub#searchIssues() GitHub#searchIssues()
* @see GHIssueSearchBuilder
*/
<span class="fc" id="L53">public class GHIssue extends GHObject implements Reactable {</span>
private static final String ASSIGNEES = &quot;assignees&quot;;
GHRepository owner;
// API v3
protected GHUser assignee; // not sure what this field is now that 'assignees' exist
protected GHUser[] assignees;
protected String state;
protected int number;
protected String closed_at;
protected int comments;
@SkipFromToString
protected String body;
protected List&lt;GHLabel&gt; labels;
protected GHUser user;
protected String title, html_url;
protected GHIssue.PullRequest pull_request;
protected GHMilestone milestone;
protected GHUser closed_by;
protected boolean locked;
GHIssue wrap(GHRepository owner) {
<span class="fc" id="L76"> this.owner = owner;</span>
<span class="fc bfc" id="L77" title="All 2 branches covered."> if (milestone != null)</span>
<span class="fc" id="L78"> milestone.wrap(owner);</span>
<span class="fc" id="L79"> return wrap(owner.root);</span>
}
GHIssue wrap(GitHub root) {
<span class="fc" id="L83"> this.root = root;</span>
<span class="fc bfc" id="L84" title="All 2 branches covered."> if (assignee != null)</span>
<span class="fc" id="L85"> assignee.wrapUp(root);</span>
<span class="fc bfc" id="L86" title="All 2 branches covered."> if (assignees != null)</span>
<span class="fc" id="L87"> GHUser.wrap(assignees, root);</span>
<span class="fc bfc" id="L88" title="All 2 branches covered."> if (user != null)</span>
<span class="fc" id="L89"> user.wrapUp(root);</span>
<span class="fc bfc" id="L90" title="All 2 branches covered."> if (closed_by != null)</span>
<span class="fc" id="L91"> closed_by.wrapUp(root);</span>
<span class="fc" id="L92"> return this;</span>
}
/**
* Repository to which the issue belongs.
*
* @return the repository
*/
public GHRepository getRepository() {
<span class="fc" id="L101"> return owner;</span>
}
/**
* The description of this pull request.
*
* @return the body
*/
public String getBody() {
<span class="fc" id="L110"> return body;</span>
}
/**
* ID.
*
* @return the number
*/
public int getNumber() {
<span class="fc" id="L119"> return number;</span>
}
/**
* The HTML page of this issue, like https://github.com/jenkinsci/jenkins/issues/100
*/
public URL getHtmlUrl() {
<span class="nc" id="L126"> return GitHubClient.parseURL(html_url);</span>
}
/**
* Gets title.
*
* @return the title
*/
public String getTitle() {
<span class="fc" id="L135"> return title;</span>
}
/**
* Is locked boolean.
*
* @return the boolean
*/
public boolean isLocked() {
<span class="nc" id="L144"> return locked;</span>
}
/**
* Gets state.
*
* @return the state
*/
public GHIssueState getState() {
<span class="fc" id="L153"> return Enum.valueOf(GHIssueState.class, state.toUpperCase(Locale.ENGLISH));</span>
}
/**
* Gets labels.
*
* @return the labels
*/
public Collection&lt;GHLabel&gt; getLabels() {
<span class="pc bpc" id="L162" title="1 of 2 branches missed."> if (labels == null) {</span>
<span class="nc" id="L163"> return Collections.emptyList();</span>
}
<span class="fc" id="L165"> return Collections.unmodifiableList(labels);</span>
}
/**
* Gets closed at.
*
* @return the closed at
*/
public Date getClosedAt() {
<span class="nc" id="L174"> return GitHubClient.parseDate(closed_at);</span>
}
/**
* Gets api url.
*
* @return API URL of this object.
* @deprecated use {@link #getUrl()}
*/
@Deprecated
public URL getApiURL() {
<span class="nc" id="L185"> return getUrl();</span>
}
/**
* Lock.
*
* @throws IOException
* the io exception
*/
public void lock() throws IOException {
<span class="nc" id="L195"> root.createRequest().method(&quot;PUT&quot;).withUrlPath(getApiRoute() + &quot;/lock&quot;).send();</span>
<span class="nc" id="L196"> }</span>
/**
* Unlock.
*
* @throws IOException
* the io exception
*/
public void unlock() throws IOException {
<span class="nc" id="L205"> root.createRequest().method(&quot;PUT&quot;).withUrlPath(getApiRoute() + &quot;/lock&quot;).send();</span>
<span class="nc" id="L206"> }</span>
/**
* Updates the issue by adding a comment.
*
* @param message
* the message
* @return Newly posted comment.
* @throws IOException
* the io exception
*/
@WithBridgeMethods(void.class)
public GHIssueComment comment(String message) throws IOException {
<span class="fc" id="L219"> GHIssueComment r = root.createRequest()</span>
<span class="fc" id="L220"> .method(&quot;POST&quot;)</span>
<span class="fc" id="L221"> .with(&quot;body&quot;, message)</span>
<span class="fc" id="L222"> .withUrlPath(getIssuesApiRoute() + &quot;/comments&quot;)</span>
<span class="fc" id="L223"> .fetch(GHIssueComment.class);</span>
<span class="fc" id="L224"> return r.wrapUp(this);</span>
}
private void edit(String key, Object value) throws IOException {
<span class="fc" id="L228"> root.createRequest().with(key, value).method(&quot;PATCH&quot;).withUrlPath(getApiRoute()).send();</span>
<span class="fc" id="L229"> }</span>
/**
* Identical to edit(), but allows null for the value.
*/
private void editNullable(String key, Object value) throws IOException {
<span class="nc" id="L235"> root.createRequest().withNullable(key, value).method(&quot;PATCH&quot;).withUrlPath(getApiRoute()).send();</span>
<span class="nc" id="L236"> }</span>
private void editIssue(String key, Object value) throws IOException {
<span class="fc" id="L239"> root.createRequest().withNullable(key, value).method(&quot;PATCH&quot;).withUrlPath(getIssuesApiRoute()).send();</span>
<span class="fc" id="L240"> }</span>
/**
* Closes this issue.
*
* @throws IOException
* the io exception
*/
public void close() throws IOException {
<span class="fc" id="L249"> edit(&quot;state&quot;, &quot;closed&quot;);</span>
<span class="fc" id="L250"> }</span>
/**
* Reopens this issue.
*
* @throws IOException
* the io exception
*/
public void reopen() throws IOException {
<span class="nc" id="L259"> edit(&quot;state&quot;, &quot;open&quot;);</span>
<span class="nc" id="L260"> }</span>
/**
* Sets title.
*
* @param title
* the title
* @throws IOException
* the io exception
*/
public void setTitle(String title) throws IOException {
<span class="nc" id="L271"> edit(&quot;title&quot;, title);</span>
<span class="nc" id="L272"> }</span>
/**
* Sets body.
*
* @param body
* the body
* @throws IOException
* the io exception
*/
public void setBody(String body) throws IOException {
<span class="nc" id="L283"> edit(&quot;body&quot;, body);</span>
<span class="nc" id="L284"> }</span>
/**
* Sets the milestone for this issue.
*
* @param milestone
* The milestone to assign this issue to. Use null to remove the milestone for this issue.
* @throws IOException
* The io exception
*/
public void setMilestone(GHMilestone milestone) throws IOException {
<span class="fc bfc" id="L295" title="All 2 branches covered."> if (milestone == null) {</span>
<span class="fc" id="L296"> editIssue(&quot;milestone&quot;, null);</span>
} else {
<span class="fc" id="L298"> editIssue(&quot;milestone&quot;, milestone.getNumber());</span>
}
<span class="fc" id="L300"> }</span>
/**
* Assign to.
*
* @param user
* the user
* @throws IOException
* the io exception
*/
public void assignTo(GHUser user) throws IOException {
<span class="fc" id="L311"> setAssignees(user);</span>
<span class="fc" id="L312"> }</span>
/**
* Sets labels.
*
* @param labels
* the labels
* @throws IOException
* the io exception
*/
public void setLabels(String... labels) throws IOException {
<span class="fc" id="L323"> editIssue(&quot;labels&quot;, labels);</span>
<span class="fc" id="L324"> }</span>
/**
* Adds labels to the issue.
*
* @param names
* Names of the label
* @throws IOException
* the io exception
*/
public void addLabels(String... names) throws IOException {
<span class="fc" id="L335"> _addLabels(Arrays.asList(names));</span>
<span class="fc" id="L336"> }</span>
/**
* Add labels.
*
* @param labels
* the labels
* @throws IOException
* the io exception
*/
public void addLabels(GHLabel... labels) throws IOException {
<span class="nc" id="L347"> addLabels(Arrays.asList(labels));</span>
<span class="nc" id="L348"> }</span>
/**
* Add labels.
*
* @param labels
* the labels
* @throws IOException
* the io exception
*/
public void addLabels(Collection&lt;GHLabel&gt; labels) throws IOException {
<span class="nc" id="L359"> _addLabels(GHLabel.toNames(labels));</span>
<span class="nc" id="L360"> }</span>
private void _addLabels(Collection&lt;String&gt; names) throws IOException {
<span class="fc" id="L363"> List&lt;String&gt; newLabels = new ArrayList&lt;String&gt;();</span>
<span class="pc bpc" id="L365" title="1 of 2 branches missed."> for (GHLabel label : getLabels()) {</span>
<span class="nc" id="L366"> newLabels.add(label.getName());</span>
<span class="nc" id="L367"> }</span>
<span class="fc bfc" id="L368" title="All 2 branches covered."> for (String name : names) {</span>
<span class="pc bpc" id="L369" title="1 of 2 branches missed."> if (!newLabels.contains(name)) {</span>
<span class="fc" id="L370"> newLabels.add(name);</span>
}
<span class="fc" id="L372"> }</span>
<span class="fc" id="L373"> setLabels(newLabels.toArray(new String[0]));</span>
<span class="fc" id="L374"> }</span>
/**
* Remove a given label by name from this issue.
*
* @param names
* the names
* @throws IOException
* the io exception
*/
public void removeLabels(String... names) throws IOException {
<span class="nc" id="L385"> _removeLabels(Arrays.asList(names));</span>
<span class="nc" id="L386"> }</span>
/**
* Remove labels.
*
* @param labels
* the labels
* @throws IOException
* the io exception
* @see #removeLabels(String...) #removeLabels(String...)
*/
public void removeLabels(GHLabel... labels) throws IOException {
<span class="nc" id="L398"> removeLabels(Arrays.asList(labels));</span>
<span class="nc" id="L399"> }</span>
/**
* Remove labels.
*
* @param labels
* the labels
* @throws IOException
* the io exception
*/
public void removeLabels(Collection&lt;GHLabel&gt; labels) throws IOException {
<span class="nc" id="L410"> _removeLabels(GHLabel.toNames(labels));</span>
<span class="nc" id="L411"> }</span>
private void _removeLabels(Collection&lt;String&gt; names) throws IOException {
<span class="nc" id="L414"> List&lt;String&gt; newLabels = new ArrayList&lt;String&gt;();</span>
<span class="nc bnc" id="L416" title="All 2 branches missed."> for (GHLabel l : getLabels()) {</span>
<span class="nc bnc" id="L417" title="All 2 branches missed."> if (!names.contains(l.getName())) {</span>
<span class="nc" id="L418"> newLabels.add(l.getName());</span>
}
<span class="nc" id="L420"> }</span>
<span class="nc" id="L422"> setLabels(newLabels.toArray(new String[0]));</span>
<span class="nc" id="L423"> }</span>
/**
* Obtains all the comments associated with this issue.
*
* @return the comments
* @throws IOException
* the io exception
* @see #listComments() #listComments()
*/
public List&lt;GHIssueComment&gt; getComments() throws IOException {
<span class="fc" id="L434"> return listComments().toList();</span>
}
/**
* Obtains all the comments associated with this issue.
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable&lt;GHIssueComment&gt; listComments() throws IOException {
<span class="fc" id="L445"> return root.createRequest()</span>
<span class="fc" id="L446"> .withUrlPath(getIssuesApiRoute() + &quot;/comments&quot;)</span>
<span class="fc" id="L447"> .toIterable(GHIssueComment[].class, item -&gt; item.wrapUp(this));</span>
}
@Preview(SQUIRREL_GIRL)
@Deprecated
public GHReaction createReaction(ReactionContent content) throws IOException {
<span class="fc" id="L453"> return root.createRequest()</span>
<span class="fc" id="L454"> .method(&quot;POST&quot;)</span>
<span class="fc" id="L455"> .withPreview(SQUIRREL_GIRL)</span>
<span class="fc" id="L456"> .with(&quot;content&quot;, content.getContent())</span>
<span class="fc" id="L457"> .withUrlPath(getApiRoute() + &quot;/reactions&quot;)</span>
<span class="fc" id="L458"> .fetch(GHReaction.class)</span>
<span class="fc" id="L459"> .wrap(root);</span>
}
@Preview(SQUIRREL_GIRL)
@Deprecated
public PagedIterable&lt;GHReaction&gt; listReactions() {
<span class="fc" id="L465"> return root.createRequest()</span>
<span class="fc" id="L466"> .withPreview(SQUIRREL_GIRL)</span>
<span class="fc" id="L467"> .withUrlPath(getApiRoute() + &quot;/reactions&quot;)</span>
<span class="fc" id="L468"> .toIterable(GHReaction[].class, item -&gt; item.wrap(root));</span>
}
/**
* Add assignees.
*
* @param assignees
* the assignees
* @throws IOException
* the io exception
*/
public void addAssignees(GHUser... assignees) throws IOException {
<span class="nc" id="L480"> addAssignees(Arrays.asList(assignees));</span>
<span class="nc" id="L481"> }</span>
/**
* Add assignees.
*
* @param assignees
* the assignees
* @throws IOException
* the io exception
*/
public void addAssignees(Collection&lt;GHUser&gt; assignees) throws IOException {
<span class="nc" id="L492"> root.createRequest()</span>
<span class="nc" id="L493"> .method(&quot;POST&quot;)</span>
<span class="nc" id="L494"> .with(ASSIGNEES, getLogins(assignees))</span>
<span class="nc" id="L495"> .withUrlPath(getIssuesApiRoute() + &quot;/assignees&quot;)</span>
<span class="nc" id="L496"> .fetchInto(this);</span>
<span class="nc" id="L497"> }</span>
/**
* Sets assignees.
*
* @param assignees
* the assignees
* @throws IOException
* the io exception
*/
public void setAssignees(GHUser... assignees) throws IOException {
<span class="fc" id="L508"> setAssignees(Arrays.asList(assignees));</span>
<span class="fc" id="L509"> }</span>
/**
* Sets assignees.
*
* @param assignees
* the assignees
* @throws IOException
* the io exception
*/
public void setAssignees(Collection&lt;GHUser&gt; assignees) throws IOException {
<span class="fc" id="L520"> root.createRequest()</span>
<span class="fc" id="L521"> .method(&quot;PATCH&quot;)</span>
<span class="fc" id="L522"> .with(ASSIGNEES, getLogins(assignees))</span>
<span class="fc" id="L523"> .withUrlPath(getIssuesApiRoute())</span>
<span class="fc" id="L524"> .send();</span>
<span class="fc" id="L525"> }</span>
/**
* Remove assignees.
*
* @param assignees
* the assignees
* @throws IOException
* the io exception
*/
public void removeAssignees(GHUser... assignees) throws IOException {
<span class="nc" id="L536"> removeAssignees(Arrays.asList(assignees));</span>
<span class="nc" id="L537"> }</span>
/**
* Remove assignees.
*
* @param assignees
* the assignees
* @throws IOException
* the io exception
*/
public void removeAssignees(Collection&lt;GHUser&gt; assignees) throws IOException {
<span class="nc" id="L548"> root.createRequest()</span>
<span class="nc" id="L549"> .method(&quot;DELETE&quot;)</span>
<span class="nc" id="L550"> .with(ASSIGNEES, getLogins(assignees))</span>
<span class="nc" id="L551"> .inBody()</span>
<span class="nc" id="L552"> .withUrlPath(getIssuesApiRoute() + &quot;/assignees&quot;)</span>
<span class="nc" id="L553"> .fetchInto(this);</span>
<span class="nc" id="L554"> }</span>
/**
* Gets api route.
*
* @return the api route
*/
protected String getApiRoute() {
<span class="fc" id="L562"> return getIssuesApiRoute();</span>
}
/**
* Gets issues api route.
*
* @return the issues api route
*/
protected String getIssuesApiRoute() {
<span class="fc bfc" id="L571" title="All 2 branches covered."> if (owner == null) {</span>
// Issues returned from search to do not have an owner. Attempt to use url.
<span class="fc" id="L573"> final URL url = Objects.requireNonNull(getUrl(), &quot;Missing instance URL!&quot;);</span>
<span class="fc" id="L574"> return StringUtils.prependIfMissing(url.toString().replace(root.getApiUrl(), &quot;&quot;), &quot;/&quot;);</span>
}
<span class="fc" id="L576"> return &quot;/repos/&quot; + owner.getOwnerName() + &quot;/&quot; + owner.getName() + &quot;/issues/&quot; + number;</span>
}
/**
* Gets assignee.
*
* @return the assignee
* @throws IOException
* the io exception
*/
public GHUser getAssignee() throws IOException {
<span class="fc" id="L587"> return root.intern(assignee);</span>
}
/**
* Gets assignees.
*
* @return the assignees
*/
public List&lt;GHUser&gt; getAssignees() {
<span class="nc" id="L596"> return Collections.unmodifiableList(Arrays.asList(assignees));</span>
}
/**
* User who submitted the issue.
*
* @return the user
* @throws IOException
* the io exception
*/
public GHUser getUser() throws IOException {
<span class="fc" id="L607"> return root.intern(user);</span>
}
/**
* Reports who has closed the issue.
*
* &lt;p&gt;
* Note that GitHub doesn't always seem to report this information even for an issue that's already closed. See
* https://github.com/kohsuke/github-api/issues/60.
*
* @return the closed by
* @throws IOException
* the io exception
*/
public GHUser getClosedBy() throws IOException {
<span class="nc bnc" id="L622" title="All 2 branches missed."> if (!&quot;closed&quot;.equals(state))</span>
<span class="nc" id="L623"> return null;</span>
// TODO
/*
* if (closed_by==null) { closed_by = owner.getIssue(number).getClosed_by(); }
*/
<span class="nc" id="L629"> return root.intern(closed_by);</span>
}
/**
* Gets comments count.
*
* @return the comments count
*/
public int getCommentsCount() {
<span class="fc" id="L638"> return comments;</span>
}
/**
* Returns non-null if this issue is a shadow of a pull request.
*
* @return the pull request
*/
public PullRequest getPullRequest() {
<span class="nc" id="L647"> return pull_request;</span>
}
/**
* Is pull request boolean.
*
* @return the boolean
*/
public boolean isPullRequest() {
<span class="nc bnc" id="L656" title="All 2 branches missed."> return pull_request != null;</span>
}
/**
* Gets milestone.
*
* @return the milestone
*/
public GHMilestone getMilestone() {
<span class="fc" id="L665"> return milestone;</span>
}
/**
* The type PullRequest.
*/
@SuppressFBWarnings(value = { &quot;UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD&quot;, &quot;UWF_UNWRITTEN_FIELD&quot; },
justification = &quot;JSON API&quot;)
<span class="fc" id="L673"> public static class PullRequest {</span>
private String diff_url, patch_url, html_url;
/**
* Gets diff url.
*
* @return the diff url
*/
public URL getDiffUrl() {
<span class="nc" id="L682"> return GitHubClient.parseURL(diff_url);</span>
}
/**
* Gets patch url.
*
* @return the patch url
*/
public URL getPatchUrl() {
<span class="nc" id="L691"> return GitHubClient.parseURL(patch_url);</span>
}
/**
* Gets url.
*
* @return the url
*/
public URL getUrl() {
<span class="nc" id="L700"> return GitHubClient.parseURL(html_url);</span>
}
}
protected static List&lt;String&gt; getLogins(Collection&lt;GHUser&gt; users) {
<span class="fc" id="L705"> List&lt;String&gt; names = new ArrayList&lt;String&gt;(users.size());</span>
<span class="fc bfc" id="L706" title="All 2 branches covered."> for (GHUser a : users) {</span>
<span class="fc" id="L707"> names.add(a.getLogin());</span>
<span class="fc" id="L708"> }</span>
<span class="fc" id="L709"> return names;</span>
}
/**
* Lists events for this issue. See https://developer.github.com/v3/issues/events/
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable&lt;GHIssueEvent&gt; listEvents() throws IOException {
<span class="fc" id="L720"> return root.createRequest()</span>
<span class="fc" id="L721"> .withUrlPath(owner.getApiTailUrl(String.format(&quot;/issues/%s/events&quot;, number)))</span>
<span class="fc" id="L722"> .toIterable(GHIssueEvent[].class, item -&gt; item.wrapUp(this));</span>
}
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.6.202009150832</span></div></body></html>