Skip to content

Commit 319891d

Browse files
authored
Added support for Project Import/Export API - #377 (#379)
1 parent c9fe315 commit 319891d

File tree

9 files changed

+747
-3
lines changed

9 files changed

+747
-3
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757

5858
<changelog-lib.version>1.59</changelog-lib.version>
5959

60-
<gitlab.version>11.10.4-ce.0</gitlab.version>
60+
<gitlab.version>11.11.2-ce.0</gitlab.version>
6161
<gitlab.autoremove-container>true</gitlab.autoremove-container>
6262
<gitlab.skip-docker-start>true</gitlab.skip-docker-start>
6363
<gitlab.port>8090</gitlab.port>

src/main/java/org/gitlab4j/api/GitLabApi.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public String getApiNamespace() {
6363
private EventsApi eventsApi;
6464
private GroupApi groupApi;
6565
private HealthCheckApi healthCheckApi;
66+
private ImportExportApi importExportApi;
6667
private IssuesApi issuesApi;
6768
private JobApi jobApi;
6869
private LabelsApi labelsApi;
@@ -1123,11 +1124,30 @@ public HealthCheckApi getHealthCheckApi() {
11231124
return (healthCheckApi);
11241125
}
11251126

1127+
/**
1128+
* Gets the ImportExportApi instance owned by this GitLabApi instance. The ImportExportApi is used
1129+
* to perform all project import/export related API calls.
1130+
*
1131+
* @return the ImportExportApi instance owned by this GitLabApi instance
1132+
*/
1133+
public ImportExportApi getImportExportApi() {
1134+
1135+
if (importExportApi == null) {
1136+
synchronized (this) {
1137+
if (importExportApi == null) {
1138+
importExportApi = new ImportExportApi(this);
1139+
}
1140+
}
1141+
}
1142+
1143+
return (importExportApi);
1144+
}
1145+
11261146
/**
11271147
* Gets the IssuesApi instance owned by this GitLabApi instance. The IssuesApi is used
1128-
* to perform all iossue related API calls.
1148+
* to perform all issue related API calls.
11291149
*
1130-
* @return the CommitsApi instance owned by this GitLabApi instance
1150+
* @return the IssuesApi instance owned by this GitLabApi instance
11311151
*/
11321152
public IssuesApi getIssuesApi() {
11331153

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
package org.gitlab4j.api;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.net.URL;
7+
import java.nio.file.Files;
8+
import java.nio.file.StandardCopyOption;
9+
import java.util.Map;
10+
11+
import javax.ws.rs.core.Form;
12+
import javax.ws.rs.core.MediaType;
13+
import javax.ws.rs.core.Response;
14+
15+
import org.gitlab4j.api.models.ExportStatus;
16+
import org.gitlab4j.api.models.ImportStatus;
17+
import org.gitlab4j.api.models.Project;
18+
19+
/**
20+
* This class provides an entry point to all the GitLab API project import/export calls.
21+
* @see <a href="https://docs.gitlab.com/ee/api/project_import_export.html">Project import/export API at GitLab</a>
22+
*/
23+
public class ImportExportApi extends AbstractApi {
24+
25+
public ImportExportApi(GitLabApi gitLabApi) {
26+
super(gitLabApi);
27+
}
28+
29+
/**
30+
* Schedule an export.
31+
*
32+
* <pre><code>GitLab Endpoint: POST /projects/:id/export</code></pre>
33+
*
34+
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
35+
* @throws GitLabApiException if any exception occurs
36+
*/
37+
public void scheduleExport(Object projectIdOrPath) throws GitLabApiException {
38+
scheduleExport(projectIdOrPath, null, null, null, null);
39+
}
40+
41+
/**
42+
* Schedule an export.
43+
*
44+
* <pre><code>GitLab Endpoint: POST /projects/:id/export</code></pre>
45+
*
46+
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
47+
* @param description overrides the project description, optional
48+
* @throws GitLabApiException if any exception occurs
49+
*/
50+
public void scheduleExport(Object projectIdOrPath, String description) throws GitLabApiException {
51+
scheduleExport(projectIdOrPath, description, null, null, null);
52+
}
53+
54+
/**
55+
* Schedule an export.
56+
*
57+
* <pre><code>GitLab Endpoint: POST /projects/:id/export</code></pre>
58+
*
59+
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
60+
* @param description overrides the project description, optional
61+
* @param upload Mao that contains the information to upload the exported project to a web server
62+
* @param uploadUrl the URL to upload the project
63+
* @param uploadHttpMethod the HTTP method to upload the exported project.
64+
* Only PUT and POST methods allowed. Default is PUT
65+
* @throws GitLabApiException if any exception occurs
66+
*/
67+
public void scheduleExport(Object projectIdOrPath, String description,
68+
Map<String, String> upload, String uploadUrl, String uploadHttpMethod) throws GitLabApiException {
69+
70+
Form formData = new GitLabApiForm()
71+
.withParam("description", description)
72+
.withParam("upload", upload)
73+
.withParam("upload[url]", uploadUrl)
74+
.withParam("upload[http_method]", uploadHttpMethod);
75+
post(Response.Status.ACCEPTED, formData, "projects", getProjectIdOrPath(projectIdOrPath), "export");
76+
}
77+
78+
/**
79+
* Get the status of export.
80+
*
81+
* <pre><code>GitLab Endpoint: GET /projects/:id/export</code></pre>
82+
*
83+
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
84+
* @return an ExportStatus instance holding information on the export status
85+
* @throws GitLabApiException if any exception occurs
86+
*/
87+
public ExportStatus getExportStatus(Object projectIdOrPath) throws GitLabApiException {
88+
Response response = get(Response.Status.OK, null, "projects", getProjectIdOrPath(projectIdOrPath), "export");
89+
return (response.readEntity(ExportStatus.class));
90+
}
91+
92+
/**
93+
* Download the finished export.
94+
*
95+
* <pre><code>GitLab Endpoint: GET /projects/:id/export/download</code></pre>
96+
*
97+
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
98+
* @param directory the File instance of the directory to save the export file to, if null will use "java.io.tmpdir"
99+
* @return a File instance pointing to the download of the project export file
100+
* @throws GitLabApiException if any exception occurs
101+
*/
102+
public File downloadExport(Object projectIdOrPath, File directory) throws GitLabApiException {
103+
104+
Response response = getWithAccepts(Response.Status.OK, null, MediaType.MEDIA_TYPE_WILDCARD,
105+
"projects", getProjectIdOrPath(projectIdOrPath), "export", "download");
106+
try {
107+
108+
if (directory == null)
109+
directory = new File(System.getProperty("java.io.tmpdir"));
110+
111+
String disposition = response.getHeaderString("Content-Disposition");
112+
String filename = disposition.replaceFirst("(?i)^.*filename=\"?([^\"]+)\"?.*$", "$1");
113+
File file = new File(directory, filename);
114+
115+
InputStream in = response.readEntity(InputStream.class);
116+
Files.copy(in, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
117+
return (file);
118+
119+
} catch (IOException ioe) {
120+
throw new GitLabApiException(ioe);
121+
}
122+
}
123+
124+
/**
125+
* <p>Import an exported project. The following properties on the Project instance
126+
* are utilized in the creation of the new project:</p>
127+
*<ul>
128+
* <li>defaultBranch (optional) - master by default</li>
129+
* <li>description (optional) - short project description</li>
130+
* <li>visibility (optional) - Limit by visibility public, internal, or private</li>
131+
* <li>visibilityLevel (optional)</li>
132+
* <li>issuesEnabled (optional) - Enable issues for this project</li>
133+
* <li>mergeMethod (optional) - Set the merge method used</li>
134+
* <li>mergeRequestsEnabled (optional) - Enable merge requests for this project</li>
135+
* <li>wikiEnabled (optional) - Enable wiki for this project</li>
136+
* <li>snippetsEnabled (optional) - Enable snippets for this project</li>
137+
* <li>jobsEnabled (optional) - Enable jobs for this project</li>
138+
* <li>containerRegistryEnabled (optional) - Enable container registry for this project</li>
139+
* <li>sharedRunnersEnabled (optional) - Enable shared runners for this project</li>
140+
* <li>publicJobs (optional) - If true, jobs can be viewed by non-project-members</li>
141+
* <li>onlyAllowMergeIfPipelineSucceeds (optional) - Set whether merge requests can only be merged with successful jobs</li>
142+
* <li>onlyAllowMergeIfAllDiscussionsAreResolved (optional) - Set whether merge requests can only be merged when all the discussions are resolved</li>
143+
* <li>lLfsEnabled (optional) - Enable LFS</li>
144+
* <li>requestAccessEnabled (optional) - Allow users to request member access</li>
145+
* <li>repositoryStorage (optional) - Which storage shard the repository is on. Available only to admins</li>
146+
* <li>approvalsBeforeMerge (optional) - How many approvers should approve merge request by default</li>
147+
* <li>printingMergeRequestLinkEnabled (optional) - Show link to create/view merge request when pushing from the command line</li>
148+
* <li>resolveOutdatedDiffDiscussions (optional) - Automatically resolve merge request diffs discussions on lines changed with a push</li>
149+
* <li>initialize_with_readme (optional) - Initialize project with README file</li>
150+
* <li>packagesEnabled (optional) - Enable or disable mvn packages repository feature</li>
151+
*</ul>
152+
* <pre><code>GitLab Endpoint: POST /projects/import</code></pre>
153+
*
154+
* @param namespaceIdOrPath the ID or path of the namespace that the project will be imported to. Defaults to the current user’s namespace
155+
* @param exportFile the project export file to be imported
156+
* @param path the name and path for the new project
157+
* @param overwrite if there is a project with the same path the import will overwrite it. Defaults to false
158+
* @param overrideParams overriding project params, supports all fields defined by the ProjectApi, optional
159+
* @return an Importstatus instance with info for the project being imported to
160+
* @throws GitLabApiException if any exception occurs
161+
*/
162+
public ImportStatus startImport(Object namespaceIdOrPath, File exportFile, String path, Boolean overwrite, Project overrideParams) throws GitLabApiException {
163+
164+
URL url;
165+
try {
166+
url = getApiClient().getApiUrl("projects", "import");
167+
} catch (IOException ioe) {
168+
throw new GitLabApiException(ioe);
169+
}
170+
171+
GitLabApiForm formData = new GitLabApiForm()
172+
.withParam("path", path, true)
173+
.withParam("namespace", namespaceIdOrPath)
174+
.withParam("overwrite", overwrite);
175+
176+
if (overrideParams != null) {
177+
formData.withParam("default_branch", overrideParams.getDefaultBranch())
178+
.withParam("description", overrideParams.getDescription())
179+
.withParam("issues_enabled", overrideParams.getIssuesEnabled())
180+
.withParam("merge_method", overrideParams.getMergeMethod())
181+
.withParam("merge_requests_enabled", overrideParams.getMergeRequestsEnabled())
182+
.withParam("jobs_enabled", overrideParams.getJobsEnabled())
183+
.withParam("wiki_enabled", overrideParams.getWikiEnabled())
184+
.withParam("container_registry_enabled", overrideParams.getContainerRegistryEnabled())
185+
.withParam("snippets_enabled", overrideParams.getSnippetsEnabled())
186+
.withParam("shared_runners_enabled", overrideParams.getSharedRunnersEnabled())
187+
.withParam("public_jobs", overrideParams.getPublicJobs())
188+
.withParam("visibility_level", overrideParams.getVisibilityLevel())
189+
.withParam("only_allow_merge_if_pipeline_succeeds", overrideParams.getOnlyAllowMergeIfPipelineSucceeds())
190+
.withParam("only_allow_merge_if_all_discussions_are_resolved", overrideParams.getOnlyAllowMergeIfAllDiscussionsAreResolved())
191+
.withParam("lfs_enabled", overrideParams.getLfsEnabled())
192+
.withParam("request_access_enabled", overrideParams.getRequestAccessEnabled())
193+
.withParam("repository_storage", overrideParams.getRepositoryStorage())
194+
.withParam("approvals_before_merge", overrideParams.getApprovalsBeforeMerge())
195+
.withParam("printing_merge_request_link_enabled", overrideParams.getPrintingMergeRequestLinkEnabled())
196+
.withParam("resolve_outdated_diff_discussions", overrideParams.getResolveOutdatedDiffDiscussions())
197+
.withParam("initialize_with_readme", overrideParams.getInitializeWithReadme())
198+
.withParam("packages_enabled", overrideParams.getPackagesEnabled());
199+
}
200+
201+
Response response = upload(Response.Status.CREATED, "file", exportFile, null, formData, url);
202+
return (response.readEntity(ImportStatus.class));
203+
}
204+
205+
/**
206+
* Get the status of an import.
207+
*
208+
* <pre><code>GitLab Endpoint: GET /projects/:id/import</code></pre>
209+
*
210+
* @param projectIdOrPath the new (imported) project identifier in the form of an Integer(ID), String(path), or Project instance
211+
* @return an ImportStatus instance holding information on the import status
212+
* @throws GitLabApiException if any exception occurs
213+
*/
214+
public ImportStatus getImportStatus(Object projectIdOrPath) throws GitLabApiException {
215+
Response response = get(Response.Status.OK, null, "projects", getProjectIdOrPath(projectIdOrPath), "import");
216+
return (response.readEntity(ImportStatus.class));
217+
}
218+
}

0 commit comments

Comments
 (0)