Merge branch 'master' into add-check-suite-warp-up

This commit is contained in:
Kezhi Xiong
2020-03-27 17:05:14 +08:00
committed by GitHub
4160 changed files with 74377 additions and 63460 deletions

View File

@@ -0,0 +1,165 @@
package org.kohsuke.github;
import java.io.IOException;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
/**
* An abstract data object builder/updater.
*
* This class can be use to make a Builder that supports both batch and single property changes.
* <p>
* Batching looks like this:
* </p>
*
* <pre>
* update().someName(value).otherName(value).done()
* </pre>
* <p>
* Single changes look like this:
* </p>
*
* <pre>
* set().someName(value);
* set().otherName(value);
* </pre>
* <p>
* If {@link S} is the same as {@link R}, {@link #with(String, Object)} will commit changes after the first value change
* and return a {@link R} from {@link #done()}.
* </p>
* <p>
* If {@link S} is not the same as {@link R}, {@link #with(String, Object)} will batch together multiple changes and let
* the user call {@link #done()} when they are ready.
*
* @param <R>
* Final return type built by this builder returned when {@link #done()}} is called.
* @param <S>
* Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If {@link S}
* the same as {@link R}, this builder will commit changes after each call to {@link #with(String, Object)}.
*/
abstract class AbstractBuilder<R, S> {
@Nonnull
private final Class<R> returnType;
private final boolean commitChangesImmediately;
@CheckForNull
private final R baseInstance;
@Nonnull
protected final Requester requester;
// TODO: Not sure how update-in-place behavior should be controlled
// However, it certainly can be controlled dynamically down to the instance level or inherited for all children of
// some
// connection.
protected boolean updateInPlace;
/**
* Creates a builder.
*
* @param root
* the GitHub instance to connect to.
* @param intermediateReturnType
* the intermediate return type of type {@link S} returned by calls to {@link #with(String, Object)}.
* Must either be equal to {@code builtReturnType} or this instance must be castable to this class. If
* not, the constructor will throw {@link IllegalArgumentException}.
* @param finalReturnType
* the final return type for built by this builder returned when {@link #done()}} is called.
* @param baseInstance
* optional instance on which to base this builder.
*/
protected AbstractBuilder(@Nonnull Class<R> finalReturnType,
@Nonnull Class<S> intermediateReturnType,
@Nonnull GitHub root,
@CheckForNull R baseInstance) {
this.requester = root.createRequest();
this.returnType = finalReturnType;
this.commitChangesImmediately = returnType.equals(intermediateReturnType);
if (!commitChangesImmediately && !intermediateReturnType.isInstance(this)) {
throw new IllegalArgumentException(
"Argument \"intermediateReturnType\": This instance must be castable to intermediateReturnType or finalReturnType must be equal to intermediateReturnType.");
}
this.baseInstance = baseInstance;
this.updateInPlace = false;
}
/**
* Finishes an update, committing changes.
*
* This method may update-in-place or not. Either way it returns the resulting instance.
*
* @return an instance with updated current data
* @throws IOException
* if there is an I/O Exception
*/
@Nonnull
@Preview
@Deprecated
public R done() throws IOException {
R result;
if (updateInPlace && baseInstance != null) {
result = requester.fetchInto(baseInstance);
} else {
result = requester.fetch(returnType);
}
return result;
}
/**
* Applies a value to a name for this builder.
*
* If {@link S} is the same as {@link R}, this method will commit changes after the first value change and return a
* {@link R} from {@link #done()}.
*
* If {@link S} is not the same as {@link R}, this method will return an {@link S} and letting the caller batch
* together multiple changes and call {@link #done()} when they are ready.
*
* @param name
* the name of the field
* @param value
* the value of the field
* @return either a continuing builder or an updated data record
* @throws IOException
* if an I/O error occurs
*/
@Nonnull
@Preview
@Deprecated
protected S with(@Nonnull String name, Object value) throws IOException {
requester.with(name, value);
return continueOrDone();
}
/**
* Chooses whether to return a continuing builder or an updated data record
*
* If {@link S} is the same as {@link R}, this method will commit changes after the first value change and return a
* {@link R} from {@link #done()}.
*
* If {@link S} is not the same as {@link R}, this method will return an {@link S} and letting the caller batch
* together multiple changes and call {@link #done()} when they are ready.
*
* @return either a continuing builder or an updated data record
* @throws IOException
* if an I/O error occurs
*/
@Nonnull
@Preview
@Deprecated
protected S continueOrDone() throws IOException {
// This little bit of roughness in this base class means all inheriting builders get to create Updater and
// Setter classes from almost identical code. Creator can often be implemented with significant code reuse as
// well.
if (commitChangesImmediately) {
// These casts look strange and risky, but they they're actually guaranteed safe due to the return path
// being based on the previous comparison of class instances passed to the constructor.
return (S) done();
} else {
return (S) this;
}
}
}

View File

@@ -39,6 +39,8 @@ public class GHCommit {
private int comment_count;
private GHVerification verification;
static class Tree {
String sha;
}
@@ -100,6 +102,15 @@ public class GHCommit {
public int getCommentCount() {
return comment_count;
}
/**
* Gets Verification Status.
*
* @return the Verification status
*/
public GHVerification getVerification() {
return verification;
}
}
/**

View File

@@ -1,27 +1,56 @@
package org.kohsuke.github;
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonCreator;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
/**
* The type GHLabel.
*
* @author Kohsuke Kawaguchi
* @see <a href="https://developer.github.com/v3/issues/labels/">Labels</a>
* @see GHIssue#getLabels() GHIssue#getLabels()
* @see GHRepository#listLabels() GHRepository#listLabels()
*/
public class GHLabel {
private String url, name, color, description;
private GHRepository repo;
@Nonnull
private String url, name, color;
@CheckForNull
private String description;
@Nonnull
private final GitHub root;
@JsonCreator
private GHLabel(@JacksonInject @Nonnull GitHub root) {
this.root = root;
url = "";
name = "";
color = "";
description = null;
}
@Nonnull
GitHub getApiRoot() {
return Objects.requireNonNull(root);
}
/**
* Gets url.
*
* @return the url
*/
@Nonnull
public String getUrl() {
return url;
}
@@ -31,6 +60,7 @@ public class GHLabel {
*
* @return the name
*/
@Nonnull
public String getName() {
return name;
}
@@ -40,6 +70,7 @@ public class GHLabel {
*
* @return the color
*/
@Nonnull
public String getColor() {
return color;
}
@@ -49,25 +80,11 @@ public class GHLabel {
*
* @return the description
*/
@CheckForNull
public String getDescription() {
return description;
}
GHLabel wrapUp(GHRepository repo) {
this.repo = repo;
return this;
}
/**
* Delete.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
repo.root.createRequest().method("DELETE").setRawUrlPath(url).send();
}
/**
* Sets color.
*
@@ -75,15 +92,11 @@ public class GHLabel {
* 6-letter hex color code, like "f29513"
* @throws IOException
* the io exception
* @deprecated use {@link #set()} or {@link #update()} instead
*/
@Deprecated
public void setColor(String newColor) throws IOException {
repo.root.createRequest()
.method("PATCH")
.with("name", name)
.with("color", newColor)
.with("description", description)
.setRawUrlPath(url)
.send();
set().color(newColor);
}
/**
@@ -93,25 +106,106 @@ public class GHLabel {
* Description of label
* @throws IOException
* the io exception
* @deprecated use {@link #set()} or {@link #update()} instead
*/
@Deprecated
public void setDescription(String newDescription) throws IOException {
repo.root.createRequest()
.method("PATCH")
.with("name", name)
.with("color", color)
.with("description", newDescription)
.setRawUrlPath(url)
.send();
set().description(newDescription);
}
static Collection<String> toNames(Collection<GHLabel> labels) {
List<String> r = new ArrayList<String>();
List<String> r = new ArrayList<>();
for (GHLabel l : labels) {
r.add(l.getName());
}
return r;
}
/**
* Begins the creation of a new instance.
*
* Consumer must call {@link Creator#done()} to commit changes.
*
* @param repository
* the repository in which the label will be created.
* @return a {@link Creator}
* @throws IOException
* the io exception
*/
@Preview
@Deprecated
static Creator create(GHRepository repository) throws IOException {
return new Creator(repository);
}
/**
* Reads a label from a repository.
*
* @param repository
* the repository to read from
* @param name
* the name of the label
* @return a label
* @throws IOException
* the io exception
*/
static GHLabel read(@Nonnull GHRepository repository, @Nonnull String name) throws IOException {
return repository.root.createRequest()
.withUrlPath(repository.getApiTailUrl("labels"), name)
.fetch(GHLabel.class);
}
/**
* Reads all labels from a repository.
*
* @param repository
* the repository to read from
* @return iterable of all labels
* @throws IOException
* the io exception
*/
static PagedIterable<GHLabel> readAll(@Nonnull final GHRepository repository) throws IOException {
return repository.root.createRequest()
.withUrlPath(repository.getApiTailUrl("labels"))
.toIterable(GHLabel[].class, null);
}
/**
* Begins a batch update
*
* Consumer must call {@link Updater#done()} to commit changes.
*
* @return a {@link Updater}
*/
@Preview
@Deprecated
public Updater update() {
return new Updater(this);
}
/**
* Begins a single property update.
*
* @return a {@link Setter}
*/
@Preview
@Deprecated
public Setter set() {
return new Setter(this);
}
/**
* Delete this label from the repository.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
root.createRequest().method("DELETE").setRawUrlPath(getUrl()).send();
}
@Override
public boolean equals(final Object o) {
if (this == o)
@@ -120,11 +214,54 @@ public class GHLabel {
return false;
final GHLabel ghLabel = (GHLabel) o;
return Objects.equals(url, ghLabel.url) && Objects.equals(name, ghLabel.name)
&& Objects.equals(color, ghLabel.color) && Objects.equals(repo, ghLabel.repo);
&& Objects.equals(color, ghLabel.color) && Objects.equals(description, ghLabel.description);
}
@Override
public int hashCode() {
return Objects.hash(url, name, color, repo);
return Objects.hash(url, name, color, description);
}
/**
* A {@link GHLabelBuilder} that updates a single property per request
*
* {@link #done()} is called automatically after the property is set.
*/
@Preview
@Deprecated
public static class Setter extends GHLabelBuilder<GHLabel> {
private Setter(@Nonnull GHLabel base) {
super(GHLabel.class, base.getApiRoot(), base);
requester.method("PATCH").setRawUrlPath(base.getUrl());
}
}
/**
* A {@link GHLabelBuilder} that allows multiple properties to be updated per request.
*
* Consumer must call {@link #done()} to commit changes.
*/
@Preview
@Deprecated
public static class Updater extends GHLabelBuilder<Updater> {
private Updater(@Nonnull GHLabel base) {
super(Updater.class, base.getApiRoot(), base);
requester.method("PATCH").setRawUrlPath(base.getUrl());
}
}
/**
* A {@link GHLabelBuilder} that creates a new {@link GHLabel}
*
* Consumer must call {@link #done()} to create the new instance.
*/
@Preview
@Deprecated
public static class Creator extends GHLabelBuilder<Creator> {
private Creator(@Nonnull GHRepository repository) {
super(Creator.class, repository.root, null);
requester.method("POST").withUrlPath(repository.getApiTailUrl("labels"));
}
}
}

View File

@@ -0,0 +1,60 @@
package org.kohsuke.github;
import java.io.IOException;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
/**
*
* @param <S>
* Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If {@link S}
* the same as {@link GHLabel}, this builder will commit changes after each call to
* {@link #with(String, Object)}.
*/
class GHLabelBuilder<S> extends AbstractBuilder<GHLabel, S> {
/**
*
* @param intermediateReturnType
* Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If
* {@link S} the same as {@link GHLabel}, this builder will commit changes after each call to
* {@link #with(String, Object)}.
* @param root
* the GitHub instance to which updates will be sent
* @param baseInstance
* instance on which to base this builder. If {@code null} a new instance will be created.
*/
protected GHLabelBuilder(@Nonnull Class<S> intermediateReturnType,
@Nonnull GitHub root,
@CheckForNull GHLabel baseInstance) {
super(GHLabel.class, intermediateReturnType, root, baseInstance);
if (baseInstance != null) {
requester.with("name", baseInstance.getName());
requester.with("color", baseInstance.getColor());
requester.with("description", baseInstance.getDescription());
}
}
@Nonnull
@Preview
@Deprecated
public S name(String value) throws IOException {
return with("name", value);
}
@Nonnull
@Preview
@Deprecated
public S color(String value) throws IOException {
return with("color", value);
}
@Nonnull
@Preview
@Deprecated
public S description(String value) throws IOException {
return with("description", value);
}
}

View File

@@ -1872,9 +1872,7 @@ public class GHRepository extends GHObject {
* the io exception
*/
public PagedIterable<GHLabel> listLabels() throws IOException {
return root.createRequest()
.withUrlPath(getApiTailUrl("labels"))
.toIterable(GHLabel[].class, item -> item.wrapUp(this));
return GHLabel.readAll(this);
}
/**
@@ -1887,7 +1885,7 @@ public class GHRepository extends GHObject {
* the io exception
*/
public GHLabel getLabel(String name) throws IOException {
return root.createRequest().withUrlPath(getApiTailUrl("labels/" + name)).fetch(GHLabel.class).wrapUp(this);
return GHLabel.read(this, name);
}
/**
@@ -1902,7 +1900,7 @@ public class GHRepository extends GHObject {
* the io exception
*/
public GHLabel createLabel(String name, String color) throws IOException {
return createLabel(name, color, "");
return GHLabel.create(this).name(name).color(color).description("").done();
}
/**
@@ -1919,14 +1917,7 @@ public class GHRepository extends GHObject {
* the io exception
*/
public GHLabel createLabel(String name, String color, String description) throws IOException {
return root.createRequest()
.method("POST")
.with("name", name)
.with("color", color)
.with("description", description)
.withUrlPath(getApiTailUrl("labels"))
.fetch(GHLabel.class)
.wrapUp(this);
return GHLabel.create(this).name(name).color(color).description(description).done();
}
/**

View File

@@ -19,6 +19,7 @@ public class GHTagObject {
private String message;
private GitUser tagger;
private GHRef.GHObject object;
private GHVerification verification;
GHTagObject wrap(GHRepository owner) {
this.owner = owner;
@@ -97,4 +98,13 @@ public class GHTagObject {
public GHRef.GHObject getObject() {
return object;
}
/**
* Gets Verification Status.
*
* @return the Verification status
*/
public GHVerification getVerification() {
return verification;
}
}

View File

@@ -0,0 +1,82 @@
package org.kohsuke.github;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
/**
* The commit/tag can be signed by user. This object holds the verification status. Whether the Commit/Tag is signed or
* not.
*
* @see <a href="https://developer.github.com/v3/git/tags/#signature-verification-object">tags signature
* verificatiion</a>
* @see <a href="https://developer.github.com/v3/git/commits/#signature-verification-object">commits signature
* verificatiion</a>
*
* @author Sourabh Sarvotham Parkala
*/
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
justification = "JSON API")
public class GHVerification {
private String signature, payload;
private boolean verified;
private Reason reason;
/**
* Indicates whether GitHub considers the signature in this commit to be verified.
*
* @return true if the signature is valid else returns false.
*/
public boolean isVerified() {
return verified;
}
/**
* Gets reason for verification value.
*
* @return return reason of type {@link Reason}, such as "valid" or "unsigned". The possible values can be found in
* {@link Reason}}
*/
public Reason getReason() {
return reason;
}
/**
* Gets signature used for the verification.
*
* @return null if not signed else encoded signature.
*/
public String getSignature() {
return signature;
}
/**
* Gets the payload that was signed.
*
* @return null if not signed else encoded signature.
*/
public String getPayload() {
return payload;
}
/**
* The possible values for reason in verification object from github.
*
* @see <a href="https://developer.github.com/v3/repos/commits/#signature-verification-object">List of possible
* reason values</a>
* @author Sourabh Sarvotham Parkala
*/
public enum Reason {
EXPIRED_KEY,
NOT_SIGNING_KEY,
GPGVERIFY_ERROR,
GPGVERIFY_UNAVAILABLE,
UNSIGNED,
UNKNOWN_SIGNATURE_TYPE,
NO_USER,
UNVERIFIED_EMAIL,
BAD_EMAIL,
UNKNOWN_KEY,
MALFORMED_SIGNATURE,
INVALID,
VALID
}
}