(this, Participant.class, itemsPerPage, null, "projects", projectId, "merge_requests", mergeRequestIid, "participants");
}
+
+ /**
+ * Get list containing all the issues that would be closed by merging the provided merge requestt.
+ *
+ * GitLab Endpoint: GET /projects/:id/merge_requests/:merge_request_iid/closes_issues
+ *
+ * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path
+ * @param mergeRequestIid the IID of the merge request to get the closes issues for
+ * @return a List containing all the issues that would be closed by merging the provided merge request
+ * @throws GitLabApiException if any exception occurs
+ */
+ public List getClosesIssues(Object projectIdOrPath, Integer mergeRequestIid) throws GitLabApiException {
+ return (getClosesIssues(projectIdOrPath, mergeRequestIid, 1, getDefaultPerPage()));
+ }
+
+ /**
+ * Get list containing all the issues that would be closed by merging the provided merge request.
+ *
+ * GitLab Endpoint: GET /projects/:id/merge_requests/:merge_request_iid/closes_issues
+ *
+ * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path
+ * @param mergeRequestIid the IID of the merge request to get the closes issues for
+ * @param page the page to get
+ * @param perPage the number of issues per page
+ * @return a List containing all the issues that would be closed by merging the provided merge request
+ * @throws GitLabApiException if any exception occurs
+ */
+ public List getClosesIssues(Object projectIdOrPath, Integer mergeRequestIid, int page, int perPage) throws GitLabApiException {
+ Response response = get(Response.Status.OK, getPageQueryParams(page, perPage),
+ "projects", getProjectIdOrPath(projectIdOrPath), "merge_requests", mergeRequestIid, "closes_issues");
+ return (response.readEntity(new GenericType>() { }));
+ }
+
+ /**
+ * Get a Pager containing all the issues that would be closed by merging the provided merge request.
+ *
+ * GitLab Endpoint: GET /projects/:id/merge_requests/:merge_request_iid/closes_issues
+ *
+ * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path
+ * @param mergeRequestIid the IID of the merge request to get the closes issues for
+ * @param itemsPerPage the number of Issue instances that will be fetched per page
+ * @return a Pager containing all the issues that would be closed by merging the provided merge request
+ * @throws GitLabApiException if any exception occurs
+ */
+ public Pager getClosesIssues(Object projectIdOrPath, Integer mergeRequestIid, int itemsPerPage) throws GitLabApiException {
+ return new Pager(this, Issue.class, itemsPerPage, null,
+ "projects", getProjectIdOrPath(projectIdOrPath), "merge_requests", mergeRequestIid, "closes_issues");
+ }
}
diff --git a/src/main/java/org/gitlab4j/api/ProjectApi.java b/src/main/java/org/gitlab4j/api/ProjectApi.java
index 86ff54911..19902edac 100644
--- a/src/main/java/org/gitlab4j/api/ProjectApi.java
+++ b/src/main/java/org/gitlab4j/api/ProjectApi.java
@@ -655,6 +655,8 @@ public Project createProject(Project project) throws GitLabApiException {
* repositoryStorage (optional) - Which storage shard the repository is on. Available only to admins
* approvalsBeforeMerge (optional) - How many approvers should approve merge request by default
* printingMergeRequestLinkEnabled (optional) - Show link to create/view merge request when pushing from the command line
+ * resolveOutdatedDiffDiscussions (optional) - Automatically resolve merge request diffs discussions on lines changed with a push
+ * initialize_with_readme (optional) - Initialize project with README file
*
* @param project the Project instance with the configuration for the new project
* @param importUrl the URL to import the repository from
@@ -696,7 +698,9 @@ public Project createProject(Project project, String importUrl) throws GitLabApi
.withParam("repository_storage", project.getRepositoryStorage())
.withParam("approvals_before_merge", project.getApprovalsBeforeMerge())
.withParam("import_url", importUrl)
- .withParam("printing_merge_request_link_enabled", project.getPrintingMergeRequestLinkEnabled());
+ .withParam("printing_merge_request_link_enabled", project.getPrintingMergeRequestLinkEnabled())
+ .withParam("resolve_outdated_diff_discussions", project.getResolveOutdatedDiffDiscussions())
+ .withParam("initialize_with_readme", project.getInitializeWithReadme());
if (isApiVersion(ApiVersion.V3)) {
boolean isPublic = (project.getPublic() != null ? project.getPublic() : project.getVisibility() == Visibility.PUBLIC);
@@ -889,12 +893,14 @@ public Project createProject(String name, Integer namespaceId, String descriptio
* repositoryStorage (optional) - Which storage shard the repository is on. Available only to admins
* approvalsBeforeMerge (optional) - How many approvers should approve merge request by default
* printingMergeRequestLinkEnabled (optional) - Show link to create/view merge request when pushing from the command line
+ * resolveOutdatedDiffDiscussions (optional) - Automatically resolve merge request diffs discussions on lines changed with a push
*
* NOTE: The following parameters specified by the GitLab API edit project are not supported:
* import_url
* tag_list array
* avatar
* ci_config_path
+ * initialize_with_readme
*
* @param project the Project instance with the configuration for the new project
* @return a Project instance with the newly updated project info
@@ -936,7 +942,8 @@ public Project updateProject(Project project) throws GitLabApiException {
.withParam("request_access_enabled", project.getRequestAccessEnabled())
.withParam("repository_storage", project.getRepositoryStorage())
.withParam("approvals_before_merge", project.getApprovalsBeforeMerge())
- .withParam("printing_merge_request_link_enabled", project.getPrintingMergeRequestLinkEnabled());
+ .withParam("printing_merge_request_link_enabled", project.getPrintingMergeRequestLinkEnabled())
+ .withParam("resolve_outdated_diff_discussions", project.getResolveOutdatedDiffDiscussions());
if (isApiVersion(ApiVersion.V3)) {
formData.withParam("visibility_level", project.getVisibilityLevel());
diff --git a/src/main/java/org/gitlab4j/api/models/ErrorMessage.java b/src/main/java/org/gitlab4j/api/models/ErrorMessage.java
deleted file mode 100644
index 140fc7e20..000000000
--- a/src/main/java/org/gitlab4j/api/models/ErrorMessage.java
+++ /dev/null
@@ -1,21 +0,0 @@
-
-package org.gitlab4j.api.models;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-
-@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
-public class ErrorMessage {
-
- private String message;
-
- public String getMessage() {
- return this.message;
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
-}
diff --git a/src/main/java/org/gitlab4j/api/models/Project.java b/src/main/java/org/gitlab4j/api/models/Project.java
index 1819c9b70..11a643891 100644
--- a/src/main/java/org/gitlab4j/api/models/Project.java
+++ b/src/main/java/org/gitlab4j/api/models/Project.java
@@ -85,7 +85,9 @@ public String toString() {
private String webUrl;
private Boolean wikiEnabled;
private Boolean printingMergeRequestLinkEnabled;
+ private Boolean resolveOutdatedDiffDiscussions;
private ProjectStatistics statistics;
+ private Boolean initializeWithReadme;
public Integer getApprovalsBeforeMerge() {
return approvalsBeforeMerge;
@@ -593,6 +595,32 @@ public Project withPrintingMergeRequestLinkEnabled(Boolean printingMergeRequestL
return (this);
}
+ public Boolean getResolveOutdatedDiffDiscussions() {
+ return resolveOutdatedDiffDiscussions;
+ }
+
+ public void setResolveOutdatedDiffDiscussions(Boolean resolveOutdatedDiffDiscussions) {
+ this.resolveOutdatedDiffDiscussions = resolveOutdatedDiffDiscussions;
+ }
+
+ public Project withResolveOutdatedDiffDiscussions(boolean resolveOutdatedDiffDiscussions) {
+ this.resolveOutdatedDiffDiscussions = resolveOutdatedDiffDiscussions;
+ return (this);
+ }
+
+ public Boolean getInitializeWithReadme() {
+ return initializeWithReadme;
+ }
+
+ public void setInitializeWithReadme(Boolean initializeWithReadme) {
+ this.initializeWithReadme = initializeWithReadme;
+ }
+
+ public Project withInitializeWithReadme(boolean initializeWithReadme) {
+ this.initializeWithReadme = initializeWithReadme;
+ return (this);
+ }
+
public ProjectStatistics getStatistics() {
return statistics;
}
diff --git a/src/main/java/org/gitlab4j/api/utils/JacksonJson.java b/src/main/java/org/gitlab4j/api/utils/JacksonJson.java
index dfd2b54ed..6958978ac 100644
--- a/src/main/java/org/gitlab4j/api/utils/JacksonJson.java
+++ b/src/main/java/org/gitlab4j/api/utils/JacksonJson.java
@@ -243,4 +243,15 @@ private static class JacksonJsonSingletonHelper {
public static String toJsonString(final T object) {
return (JacksonJsonSingletonHelper.JACKSON_JSON.marshal(object));
}
+
+ /**
+ * Parse the provided String into a JsonNode instance.
+ *
+ * @param jsonString a String containing JSON to parse
+ * @return a JsonNode with the String parsed into a JSON tree
+ * @throws IOException if any IO error occurs
+ */
+ public static JsonNode toJsonNode(String jsonString) throws IOException {
+ return (JacksonJsonSingletonHelper.JACKSON_JSON.objectMapper.readTree(jsonString));
+ }
}
diff --git a/src/test/java/org/gitlab4j/api/TestGitLabApiException.java b/src/test/java/org/gitlab4j/api/TestGitLabApiException.java
new file mode 100644
index 000000000..69d2d93a0
--- /dev/null
+++ b/src/test/java/org/gitlab4j/api/TestGitLabApiException.java
@@ -0,0 +1,135 @@
+package org.gitlab4j.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.gitlab4j.api.GitLabApi.ApiVersion;
+import org.gitlab4j.api.models.Project;
+import org.gitlab4j.api.models.Visibility;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * In order for these tests to run you must set the following properties in ~/test-gitlab4j.properties
+ *
+ * TEST_NAMESPACE
+ * TEST_HOST_URL
+ * TEST_PRIVATE_TOKEN
+ *
+ * If any of the above are NULL, all tests in this class will be skipped.
+ */
+public class TestGitLabApiException {
+
+ // The following needs to be set to your test repository
+ private static final String TEST_NAMESPACE;
+ private static final String TEST_HOST_URL;
+ private static final String TEST_PRIVATE_TOKEN;
+
+
+ static {
+ TEST_NAMESPACE = TestUtils.getProperty("TEST_NAMESPACE");
+ TEST_HOST_URL = TestUtils.getProperty("TEST_HOST_URL");
+ TEST_PRIVATE_TOKEN = TestUtils.getProperty("TEST_PRIVATE_TOKEN");
+ }
+
+ private static final String TEST_PROJECT_NAME_DUPLICATE = "test-gitlab4j-create-project-duplicate";
+ private static GitLabApi gitLabApi;
+
+ public TestGitLabApiException() {
+ super();
+ }
+
+ @BeforeClass
+ public static void setup() {
+
+ String problems = "";
+ if (TEST_NAMESPACE == null || TEST_NAMESPACE.trim().isEmpty()) {
+ problems += "TEST_NAMESPACE cannot be empty\n";
+ }
+
+ if (TEST_HOST_URL == null || TEST_HOST_URL.trim().isEmpty()) {
+ problems += "TEST_HOST_URL cannot be empty\n";
+ }
+
+ if (TEST_PRIVATE_TOKEN == null || TEST_PRIVATE_TOKEN.trim().isEmpty()) {
+ problems += "TEST_PRIVATE_TOKEN cannot be empty\n";
+ }
+
+ if (problems.isEmpty()) {
+ gitLabApi = new GitLabApi(ApiVersion.V4, TEST_HOST_URL, TEST_PRIVATE_TOKEN);
+ } else {
+ System.err.print(problems);
+ }
+
+ deleteAllTestProjects();
+ }
+
+ @AfterClass
+ public static void teardown() throws GitLabApiException {
+ deleteAllTestProjects();
+ }
+
+ private static void deleteAllTestProjects() {
+ if (gitLabApi != null) {
+ try {
+ Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME_DUPLICATE);
+ gitLabApi.getProjectApi().deleteProject(project);
+ } catch (GitLabApiException ignore) {}
+ }
+ }
+
+ @Before
+ public void beforeMethod() {
+ assumeTrue(gitLabApi != null);
+ }
+
+ @Test
+ public void testNotFoundError() throws GitLabApiException {
+
+ try {
+ gitLabApi.getProjectApi().getProject(123456789);
+ fail("GitLabApiException not thrown");
+ } catch (GitLabApiException gae) {
+ assertFalse(gae.hasValidationErrors());
+ assertEquals(404, gae.getHttpStatus());
+ assertTrue(gae.getMessage().contains("404"));
+ }
+ }
+
+ @Test
+ public void testValidationErrors() throws GitLabApiException {
+
+ Project project = new Project()
+ .withName(TEST_PROJECT_NAME_DUPLICATE)
+ .withDescription("GitLab4J test project.")
+ .withIssuesEnabled(true)
+ .withMergeRequestsEnabled(true)
+ .withWikiEnabled(true)
+ .withSnippetsEnabled(true)
+ .withVisibility(Visibility.PUBLIC)
+ .withTagList(Arrays.asList("tag1", "tag2"));
+
+ Project newProject = gitLabApi.getProjectApi().createProject(project);
+ assertNotNull(newProject);
+
+ try {
+ newProject = gitLabApi.getProjectApi().createProject(project);
+ fail("GitLabApiException not thrown");
+ } catch (GitLabApiException gae) {
+ assertTrue(gae.hasValidationErrors());
+ Map> validationErrors = gae.getValidationErrors();
+ assertNotNull(validationErrors);
+ assertFalse(validationErrors.isEmpty());
+ }
+ }
+}