GHTreeBuilder.java
package org.kohsuke.github;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
// TODO: Auto-generated Javadoc
/**
* Builder pattern for creating a new tree. Based on https://developer.github.com/v3/git/trees/#create-a-tree
*/
public class GHTreeBuilder {
private final GHRepository repo;
private final Requester req;
private final List<TreeEntry> treeEntries = new ArrayList<TreeEntry>();
// Issue #636: Create Tree no longer accepts null value in sha field
@JsonInclude(Include.NON_NULL)
@SuppressFBWarnings("URF_UNREAD_FIELD")
private static class TreeEntry {
private final String path;
private final String mode;
private final String type;
private String sha;
private String content;
private TreeEntry(String path, String mode, String type) {
this.path = path;
this.mode = mode;
this.type = type;
}
}
private static class DeleteTreeEntry extends TreeEntry {
/**
* According to reference doc https://docs.github.com/en/rest/git/trees?apiVersion=2022-11-28#create-a-tree: if
* sha value is null then the file will be deleted. That's why in this DTO sha is always {@literal null} and is
* included to json.
*/
@JsonInclude
private final String sha = null;
private DeleteTreeEntry(String path) {
// The `mode` and `type` parameters are required by the API, but their values are ignored during delete.
// Supply reasonable placeholders.
super(path, "100644", "blob");
}
}
/**
* Instantiates a new GH tree builder.
*
* @param repo
* the repo
*/
GHTreeBuilder(GHRepository repo) {
this.repo = repo;
req = repo.root().createRequest();
}
/**
* Base tree gh tree builder.
*
* @param baseTree
* the SHA of tree you want to update with new data
* @return the gh tree builder
*/
public GHTreeBuilder baseTree(String baseTree) {
req.with("base_tree", baseTree);
return this;
}
/**
* Specialized version of entry() for adding an existing blob referred by its SHA.
*
* @param path
* the path
* @param sha
* the sha
* @param executable
* the executable
* @return the gh tree builder
* @deprecated use {@link #add(String, String, boolean)} or {@link #add(String, byte[], boolean)} instead.
*/
@Deprecated
public GHTreeBuilder shaEntry(String path, String sha, boolean executable) {
TreeEntry entry = new TreeEntry(path, executable ? "100755" : "100644", "blob");
entry.sha = sha;
treeEntries.add(entry);
return this;
}
/**
* Specialized version of entry() for adding an existing blob specified {@code content}.
*
* @param path
* the path
* @param content
* the content
* @param executable
* the executable
* @return the gh tree builder
* @deprecated use {@link #add(String, String, boolean)} or {@link #add(String, byte[], boolean)} instead.
*/
@Deprecated
public GHTreeBuilder textEntry(String path, String content, boolean executable) {
TreeEntry entry = new TreeEntry(path, executable ? "100755" : "100644", "blob");
entry.content = content;
treeEntries.add(entry);
return this;
}
/**
* Adds a new entry with the given binary content to the tree.
*
* @param path
* the file path in the tree
* @param content
* the file content as byte array
* @param executable
* true, if the file should be executable
* @return this GHTreeBuilder
*/
public GHTreeBuilder add(String path, byte[] content, boolean executable) {
try {
String dataSha = repo.createBlob().binaryContent(content).create().getSha();
return shaEntry(path, dataSha, executable);
} catch (IOException e) {
throw new GHException("Cannot create binary content of '" + path + "'", e);
}
}
/**
* Adds a new entry with the given text content to the tree.
*
* @param path
* the file path in the tree
* @param content
* the file content as UTF-8 encoded string
* @param executable
* true, if the file should be executable
* @return this GHTreeBuilder
*/
public GHTreeBuilder add(String path, String content, boolean executable) {
return add(path, content.getBytes(StandardCharsets.UTF_8), executable);
}
/**
* Removes an entry with the given path from base tree.
*
* @param path
* the file path in the tree
* @return this GHTreeBuilder
*/
public GHTreeBuilder delete(String path) {
TreeEntry entry = new DeleteTreeEntry(path);
treeEntries.add(entry);
return this;
}
private String getApiTail() {
return String.format("/repos/%s/%s/git/trees", repo.getOwnerName(), repo.getName());
}
/**
* Creates a tree based on the parameters specified thus far.
*
* @return the gh tree
* @throws IOException
* the io exception
*/
public GHTree create() throws IOException {
req.with("tree", treeEntries);
return req.method("POST").withUrlPath(getApiTail()).fetch(GHTree.class).wrap(repo);
}
}