Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 113 additions & 23 deletions gitlab4j-api/src/main/java/org/gitlab4j/api/RepositoryFileApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@

import org.gitlab4j.api.models.Blame;
import org.gitlab4j.api.models.RepositoryFile;
import org.gitlab4j.api.models.RepositoryFileCreate;
import org.gitlab4j.api.models.RepositoryFileResponse;
import org.gitlab4j.api.models.RepositoryFileUpdate;
import org.gitlab4j.models.Constants;

/**
Expand Down Expand Up @@ -183,7 +185,7 @@ public RepositoryFile getFile(Object projectIdOrPath, String filePath, String re
}

/**
* Create new file in repository
* Create new file in repository.
*
* <pre><code>GitLab Endpoint: POST /projects/:id/repository/files</code></pre>
*
Expand All @@ -194,15 +196,44 @@ public RepositoryFile getFile(Object projectIdOrPath, String filePath, String re
* commit_message (required) - Commit message
*
* @param projectIdOrPath the id, path of the project, or a Project instance holding the project ID or path
* @param file a ReposityoryFile instance with info for the file to create
* @param file a RepositoryFile instance with info for the file to create
* @param branchName the name of branch
* @param commitMessage the commit message
* @return a RepositoryFile instance with the created file info
* @return a RepositoryFileResponse instance with the created file info
* @throws GitLabApiException if any exception occurs
* @deprecated Use {@link #createFile(Object, RepositoryFileCreate, String, String)} instead.
* {@link RepositoryFile} mixes read-only response fields with write input fields;
* {@link RepositoryFileCreate} exposes only the parameters accepted by the endpoint and adds support
* for {@code start_branch}, {@code execute_filemode}, {@code author_email} and {@code author_name}.
*/
@Deprecated
public RepositoryFileResponse createFile(
Object projectIdOrPath, RepositoryFile file, String branchName, String commitMessage)
throws GitLabApiException {
return createFile(projectIdOrPath, toCreate(file), branchName, commitMessage);
}

/**
* Create new file in repository.
*
* <pre><code>GitLab Endpoint: POST /projects/:id/repository/files/:file_path</code></pre>
*
* file_path (required) - Full path to new file. Ex. lib/class.rb
* branch_name (required) - The name of branch
* encoding (optional) - 'text' or 'base64'. Text is default.
* content (required) - File content
* commit_message (required) - Commit message
*
* @param projectIdOrPath the id, path of the project, or a Project instance holding the project ID or path
* @param file a RepositoryFileCreate instance with the input parameters for the file to create
* @param branchName the name of branch
* @param commitMessage the commit message
* @return a RepositoryFileResponse instance with the created file info (path and branch)
* @throws GitLabApiException if any exception occurs
*/
public RepositoryFileResponse createFile(
Object projectIdOrPath, RepositoryFileCreate file, String branchName, String commitMessage)
throws GitLabApiException {

Form formData = createForm(file, branchName, commitMessage);
Response response = post(
Expand All @@ -217,7 +248,7 @@ public RepositoryFileResponse createFile(
}

/**
* Create new file in repository
* Create new file in repository.
*
* <pre><code>GitLab Endpoint: POST /projects/:id/repository/files</code></pre>
*
Expand All @@ -227,13 +258,13 @@ public RepositoryFileResponse createFile(
* content (required) - File content
* commit_message (required) - Commit message
*
* @param file a ReposityoryFile instance with info for the file to create
* @param file a RepositoryFile instance with info for the file to create
* @param projectId the project ID
* @param branchName the name of branch
* @param commitMessage the commit message
* @return a RepositoryFile instance with the created file info
* @return a RepositoryFileResponse instance with the created file info
* @throws GitLabApiException if any exception occurs
* @deprecated Will be removed in version 6.0, replaced by {@link #createFile(Object, RepositoryFile, String, String)}
* @deprecated Use {@link #createFile(Object, RepositoryFileCreate, String, String)} instead.
*/
@Deprecated
public RepositoryFileResponse createFile(
Expand All @@ -242,7 +273,7 @@ public RepositoryFileResponse createFile(
}

/**
* Update existing file in repository
* Update existing file in repository.
*
* <pre><code>GitLab Endpoint: PUT /projects/:id/repository/files</code></pre>
*
Expand All @@ -253,15 +284,45 @@ public RepositoryFileResponse createFile(
* commit_message (required) - Commit message
*
* @param projectIdOrPath the id, path of the project, or a Project instance holding the project ID or path
* @param file a ReposityoryFile instance with info for the file to update
* @param file a RepositoryFile instance with info for the file to update
* @param branchName the name of branch
* @param commitMessage the commit message
* @return a RepositoryFile instance with the updated file info
* @return a RepositoryFileResponse instance with the updated file info
* @throws GitLabApiException if any exception occurs
* @deprecated Use {@link #updateFile(Object, RepositoryFileUpdate, String, String)} instead.
* {@link RepositoryFile} mixes read-only response fields with write input fields;
* {@link RepositoryFileUpdate} exposes only the parameters accepted by the endpoint and adds support
* for {@code start_branch}, {@code execute_filemode}, {@code last_commit_id}, {@code author_email}
* and {@code author_name}.
*/
@Deprecated
public RepositoryFileResponse updateFile(
Object projectIdOrPath, RepositoryFile file, String branchName, String commitMessage)
throws GitLabApiException {
return updateFile(projectIdOrPath, toUpdate(file), branchName, commitMessage);
}

/**
* Update existing file in repository.
*
* <pre><code>GitLab Endpoint: PUT /projects/:id/repository/files/:file_path</code></pre>
*
* file_path (required) - Full path to new file. Ex. lib/class.rb
* branch_name (required) - The name of branch
* encoding (optional) - 'text' or 'base64'. Text is default.
* content (required) - File content
* commit_message (required) - Commit message
*
* @param projectIdOrPath the id, path of the project, or a Project instance holding the project ID or path
* @param file a RepositoryFileUpdate instance with the input parameters for the file to update
* @param branchName the name of branch
* @param commitMessage the commit message
* @return a RepositoryFileResponse instance with the updated file info (path and branch)
* @throws GitLabApiException if any exception occurs
*/
public RepositoryFileResponse updateFile(
Object projectIdOrPath, RepositoryFileUpdate file, String branchName, String commitMessage)
throws GitLabApiException {

Form formData = createForm(file, branchName, commitMessage);
Response response = put(
Expand All @@ -276,23 +337,17 @@ public RepositoryFileResponse updateFile(
}

/**
* Update existing file in repository
* Update existing file in repository.
*
* <pre><code>GitLab Endpoint: PUT /projects/:id/repository/files</code></pre>
*
* file_path (required) - Full path to new file. Ex. lib/class.rb
* branch_name (required) - The name of branch
* encoding (optional) - 'text' or 'base64'. Text is default.
* content (required) - File content
* commit_message (required) - Commit message
*
* @param file a ReposityoryFile instance with info for the file to update
* @param file a RepositoryFile instance with info for the file to update
* @param projectId the project ID
* @param branchName the name of branch
* @param commitMessage the commit message
* @return a RepositoryFile instance with the updated file info
* @return a RepositoryFileResponse instance with the updated file info
* @throws GitLabApiException if any exception occurs
* @deprecated Will be removed in version 6.0, replaced by {@link #updateFile(Object, RepositoryFile, String, String)}
* @deprecated Use {@link #updateFile(Object, RepositoryFileUpdate, String, String)} instead.
*/
@Deprecated
public RepositoryFileResponse updateFile(
Expand Down Expand Up @@ -433,18 +488,21 @@ public InputStream getRawFile(Object projectIdOrPath, String ref, String filepat
}

/**
* Gets the query params based on the API version.
* Builds the form payload sent on create/update requests.
*
* @param file the RepositoryFile instance with the info for the query params
* @param file the RepositoryFileCreate (or RepositoryFileUpdate) instance with the input parameters
* @param branchName the branch name
* @param commitMessage the commit message
* @return a Form instance with the correct query params.
*/
protected Form createForm(RepositoryFile file, String branchName, String commitMessage) {
private Form createForm(RepositoryFileCreate file, String branchName, String commitMessage) {

Form form = new Form();
addFormParam(form, "branch", branchName, true);
addFormParam(form, "start_branch", file.getStartBranch(), false);
addFormParam(form, "encoding", file.getEncoding(), false);
addFormParam(form, "author_email", file.getAuthorEmail(), false);
addFormParam(form, "author_name", file.getAuthorName(), false);

// Cannot use addFormParam() as it does not accept an empty or whitespace only string
String content = file.getContent();
Expand All @@ -454,9 +512,41 @@ protected Form createForm(RepositoryFile file, String branchName, String commitM
form.param("content", content);

addFormParam(form, "commit_message", commitMessage, true);
addFormParam(form, "execute_filemode", file.getExecuteFilemode(), false);

if (file instanceof RepositoryFileUpdate) {
addFormParam(form, "last_commit_id", ((RepositoryFileUpdate) file).getLastCommitId(), false);
}

return (form);
}

/**
* Copies the input fields of a {@link RepositoryFile} into a new {@link RepositoryFileCreate}.
* Used by the deprecated {@code createFile(Object, RepositoryFile, ...)} overload.
*/
private RepositoryFileCreate toCreate(RepositoryFile file) {
RepositoryFileCreate create = new RepositoryFileCreate();
create.setFilePath(file.getFilePath());
create.setContent(file.getContent());
create.setEncoding(file.getEncoding());
return create;
}

/**
* Copies the input fields of a {@link RepositoryFile} into a new {@link RepositoryFileUpdate},
* preserving {@code lastCommitId} as the optimistic-locking hint.
* Used by the deprecated {@code updateFile(Object, RepositoryFile, ...)} overload.
*/
private RepositoryFileUpdate toUpdate(RepositoryFile file) {
RepositoryFileUpdate update = new RepositoryFileUpdate();
update.setFilePath(file.getFilePath());
update.setContent(file.getContent());
update.setEncoding(file.getEncoding());
update.setLastCommitId(file.getLastCommitId());
return update;
}

/**
* Get a List of file blame from repository. Allows you to receive blame information.
* Each blame range contains lines and corresponding commit information.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package org.gitlab4j.api.models;

import java.io.Serializable;
import java.util.Base64;

import org.gitlab4j.models.Constants.Encoding;
import org.gitlab4j.models.utils.JacksonJson;

import com.fasterxml.jackson.annotation.JsonIgnore;

/**
* This class is used as input when creating a file in a repository.
*
* @see <a href="https://docs.gitlab.com/api/repository_files/#create-a-file-in-a-repository">Create a file in a repository</a>
*/
public class RepositoryFileCreate implements Serializable {
private static final long serialVersionUID = 1L;

private String filePath;
private String startBranch;
private Encoding encoding;
private String authorEmail;
private String authorName;
private String content;
private Boolean executeFilemode;

public String getFilePath() {
return filePath;
}

public void setFilePath(String filePath) {
this.filePath = filePath;
}

public RepositoryFileCreate withFilePath(String filePath) {
this.filePath = filePath;
return this;
}

public String getStartBranch() {
return startBranch;
}

public void setStartBranch(String startBranch) {
this.startBranch = startBranch;
}

public RepositoryFileCreate withStartBranch(String startBranch) {
this.startBranch = startBranch;
return this;
}

public Encoding getEncoding() {
return encoding;
}

public void setEncoding(Encoding encoding) {
this.encoding = encoding;
}

public RepositoryFileCreate withEncoding(Encoding encoding) {
this.encoding = encoding;
return this;
}

public String getAuthorEmail() {
return authorEmail;
}

public void setAuthorEmail(String authorEmail) {
this.authorEmail = authorEmail;
}

public RepositoryFileCreate withAuthorEmail(String authorEmail) {
this.authorEmail = authorEmail;
return this;
}

public String getAuthorName() {
return authorName;
}

public void setAuthorName(String authorName) {
this.authorName = authorName;
}

public RepositoryFileCreate withAuthorName(String authorName) {
this.authorName = authorName;
return this;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}

public RepositoryFileCreate withContent(String content) {
this.content = content;
return this;
}

public Boolean getExecuteFilemode() {
return executeFilemode;
}

public void setExecuteFilemode(Boolean executeFilemode) {
this.executeFilemode = executeFilemode;
}

public RepositoryFileCreate withExecuteFilemode(Boolean executeFilemode) {
this.executeFilemode = executeFilemode;
return this;
}

/**
* Encodes the provided String using Base64 and sets it as the content.
* The encoding property of this instance will be set to base64.
*
* @param content the String content to encode and set as the base64 encoded String content
*/
@JsonIgnore
public void encodeAndSetContent(String content) {
encodeAndSetContent(content != null ? content.getBytes() : null);
}

/**
* Encodes the provided byte array using Base64 and sets it as the content.
* The encoding property of this instance will be set to base64.
*
* @param byteContent the byte[] content to encode and set as the base64 encoded String content
*/
@JsonIgnore
public void encodeAndSetContent(byte[] byteContent) {
if (byteContent == null) {
this.content = null;
return;
}
this.content = Base64.getEncoder().encodeToString(byteContent);
this.encoding = Encoding.BASE64;
}

@Override
public String toString() {
return (JacksonJson.toJsonString(this));
}
}
Loading
Loading