/* * The MIT License (MIT) * * Copyright (c) 2017 Greg Messner * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.gitlab4j.api; import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Optional; import javax.ws.rs.core.Form; import javax.ws.rs.core.GenericType; import javax.ws.rs.core.Response; import org.gitlab4j.api.GitLabApi.ApiVersion; import org.gitlab4j.api.models.AccessLevel; import org.gitlab4j.api.models.Event; import org.gitlab4j.api.models.FileUpload; import org.gitlab4j.api.models.Issue; import org.gitlab4j.api.models.Member; import org.gitlab4j.api.models.Project; import org.gitlab4j.api.models.ProjectHook; import org.gitlab4j.api.models.ProjectUser; import org.gitlab4j.api.models.PushRules; import org.gitlab4j.api.models.Snippet; import org.gitlab4j.api.models.Visibility; /** * This class provides an entry point to all the GitLab API project calls. */ public class ProjectApi extends AbstractApi implements Constants { public ProjectApi(GitLabApi gitLabApi) { super(gitLabApi); } /** * Get a list of projects accessible by the authenticated user. * * GET /projects * * @return a list of projects accessible by the authenticated user * @throws GitLabApiException if any exception occurs */ public List getProjects() throws GitLabApiException { Response response = get(Response.Status.OK, getDefaultPerPageParam(), "projects"); return (response.readEntity(new GenericType>() {})); } /** * Get a list of projects accessible by the authenticated user and in the specified page range. * * GET /projects * * @param page the page to get * @param perPage the number of projects per page * @return a list of projects accessible by the authenticated user * @throws GitLabApiException if any exception occurs */ public List getProjects(int page, int perPage) throws GitLabApiException { Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "projects"); return (response.readEntity(new GenericType>() { })); } /** * Get a Pager instance of projects accessible by the authenticated user. * * GET /projects * * @param itemsPerPage the number of Project instances that will be fetched per page * @return a Pager instance of projects accessible by the authenticated user * @throws GitLabApiException if any exception occurs */ public Pager getProjects(int itemsPerPage) throws GitLabApiException { return (new Pager(this, Project.class, itemsPerPage, null, "projects")); } /** * Get a list of projects accessible by the authenticated user and matching the supplied filter parameters. * All filter parameters are optional. * * GET /projects * * @param archived limit by archived status * @param visibility limit by visibility public, internal, or private * @param orderBy return projects ordered by id, name, path, created_at, updated_at, or last_activity_at fields, default is created_at * @param sort return projects sorted in asc or desc order. Default is desc * @param search return list of projects matching the search criteria * @param simple return only the ID, URL, name, and path of each project * @param owned limit by projects owned by the current user * @param membership limit by projects that the current user is a member of * @param starred limit by projects starred by the current user * @param statistics include project statistics * @return a list of projects accessible by the authenticated user and matching the supplied parameters * @throws GitLabApiException if any exception occurs * @deprecated Will be removed in version 5.0, replaced by {@link #getProjects(Boolean, Visibility, * Constants.ProjectOrderBy, Constants.SortOrder, String, Boolean, Boolean, Boolean, Boolean, Boolean)} */ public List getProjects(Boolean archived, Visibility visibility, String orderBy, String sort, String search, Boolean simple, Boolean owned, Boolean membership, Boolean starred, Boolean statistics) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("archived", archived) .withParam("visibility", visibility) .withParam("order_by", orderBy) .withParam("sort", sort) .withParam("search", search) .withParam("simple", simple) .withParam("owned", owned) .withParam("membership", membership) .withParam("starred", starred) .withParam("statistics", statistics) .withParam(PER_PAGE_PARAM, getDefaultPerPage()); Response response = get(Response.Status.OK, formData.asMap(), "projects"); return (response.readEntity(new GenericType>() {})); } /** * Get a list of projects accessible by the authenticated user and matching the supplied filter parameters. * All filter parameters are optional. * * GET /projects * * @param archived limit by archived status * @param visibility limit by visibility public, internal, or private * @param orderBy return projects ordered by ID, NAME, PATH, CREATED_AT, UPDATED_AT, or * LAST_ACTIVITY_AT fields, default is CREATED_AT * @param sort return projects sorted in asc or desc order. Default is desc * @param search return list of projects matching the search criteria * @param simple return only the ID, URL, name, and path of each project * @param owned limit by projects owned by the current user * @param membership limit by projects that the current user is a member of * @param starred limit by projects starred by the current user * @param statistics include project statistics * @return a list of projects accessible by the authenticated user and matching the supplied parameters * @throws GitLabApiException if any exception occurs */ public List getProjects(Boolean archived, Visibility visibility, ProjectOrderBy orderBy, SortOrder sort, String search, Boolean simple, Boolean owned, Boolean membership, Boolean starred, Boolean statistics) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("archived", archived) .withParam("visibility", visibility) .withParam("order_by", orderBy) .withParam("sort", sort) .withParam("search", search) .withParam("simple", simple) .withParam("owned", owned) .withParam("membership", membership) .withParam("starred", starred) .withParam("statistics", statistics) .withParam(PER_PAGE_PARAM, getDefaultPerPage()); Response response = get(Response.Status.OK, formData.asMap(), "projects"); return (response.readEntity(new GenericType>() {})); } /** * Get a list of projects accessible by the authenticated user and matching the supplied filter parameters. * All filter parameters are optional. * * GET /projects * * @param archived limit by archived status * @param visibility limit by visibility public, internal, or private * @param orderBy return projects ordered by ID, NAME, PATH, CREATED_AT, UPDATED_AT, or * LAST_ACTIVITY_AT fields, default is CREATED_AT * @param sort return projects sorted in asc or desc order. Default is desc * @param search return list of projects matching the search criteria * @param simple return only the ID, URL, name, and path of each project * @param owned limit by projects owned by the current user * @param membership limit by projects that the current user is a member of * @param starred limit by projects starred by the current user * @param statistics include project statistics * @param page the page to get * @param perPage the number of projects per page * @return a list of projects accessible by the authenticated user and matching the supplied parameters * @throws GitLabApiException if any exception occurs */ public List getProjects(Boolean archived, Visibility visibility, ProjectOrderBy orderBy, SortOrder sort, String search, Boolean simple, Boolean owned, Boolean membership, Boolean starred, Boolean statistics, int page, int perPage) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("archived", archived) .withParam("visibility", visibility) .withParam("order_by", orderBy) .withParam("sort", sort) .withParam("search", search) .withParam("simple", simple) .withParam("owned", owned) .withParam("membership", membership) .withParam("starred", starred) .withParam("statistics", statistics) .withParam(PAGE_PARAM, page) .withParam(PER_PAGE_PARAM, perPage); Response response = get(Response.Status.OK, formData.asMap(), "projects"); return (response.readEntity(new GenericType>() {})); } /** * Get a Pager of projects accessible by the authenticated user and matching the supplied filter parameters. * All filter parameters are optional. * * GET /projects * * @param archived limit by archived status * @param visibility limit by visibility public, internal, or private * @param orderBy return projects ordered by ID, NAME, PATH, CREATED_AT, UPDATED_AT, or * LAST_ACTIVITY_AT fields, default is CREATED_AT * @param sort return projects sorted in asc or desc order. Default is desc * @param search return list of projects matching the search criteria * @param simple return only the ID, URL, name, and path of each project * @param owned limit by projects owned by the current user * @param membership limit by projects that the current user is a member of * @param starred limit by projects starred by the current user * @param statistics include project statistics * @param itemsPerPage the number of Project instances that will be fetched per page * @return a Pager of projects accessible by the authenticated user and matching the supplied parameters * @throws GitLabApiException if any exception occurs */ public Pager getProjects(Boolean archived, Visibility visibility, ProjectOrderBy orderBy, SortOrder sort, String search, Boolean simple, Boolean owned, Boolean membership, Boolean starred, Boolean statistics, int itemsPerPage) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("archived", archived) .withParam("visibility", visibility) .withParam("order_by", orderBy) .withParam("sort", sort) .withParam("search", search) .withParam("simple", simple) .withParam("owned", owned) .withParam("membership", membership) .withParam("starred", starred) .withParam("statistics", statistics); return (new Pager(this, Project.class, itemsPerPage, formData.asMap(), "projects")); } /** * Get a list of projects accessible by the authenticated user that match the provided search string. * * GET /projects?search=search * * @param search the project name search criteria * @return a list of projects accessible by the authenticated user that match the provided search string * @throws GitLabApiException if any exception occurs */ public List getProjects(String search) throws GitLabApiException { Form formData = new GitLabApiForm().withParam("search", search).withParam(PER_PAGE_PARAM, getDefaultPerPage()); Response response = get(Response.Status.OK, formData.asMap(), "projects"); return (response.readEntity(new GenericType>() {})); } /** * Get a list of projects accessible by the authenticated user that match the provided search string. * * GET /projects?search=search * * @param search the project name search criteria * @param page the page to get * @param perPage the number of projects per page * @return a list of projects accessible by the authenticated user that match the provided search string * @throws GitLabApiException if any exception occurs */ public List getProjects(String search, int page, int perPage) throws GitLabApiException { Form formData = new GitLabApiForm().withParam("search", search).withParam(PAGE_PARAM, page).withParam(PER_PAGE_PARAM, perPage); Response response = get(Response.Status.OK, formData.asMap(), "projects"); return (response.readEntity(new GenericType>() {})); } /** * Get a Pager of projects accessible by the authenticated user that match the provided search string. * * GET /projects?search=search * * @param search the project name search criteria * @param itemsPerPage the number of Project instances that will be fetched per page * @return a Pager of projects accessible by the authenticated user that match the provided search string * @throws GitLabApiException if any exception occurs */ public Pager getProjects(String search, int itemsPerPage) throws GitLabApiException { Form formData = new GitLabApiForm().withParam("search", search); return (new Pager(this, Project.class, itemsPerPage, formData.asMap(), "projects")); } /** * Get a list of projects that the authenticated user is a member of. * * GET /projects * * @return a list of projects that the authenticated user is a member of * @throws GitLabApiException if any exception occurs */ public List getMemberProjects() throws GitLabApiException { Form formData = new GitLabApiForm().withParam("membership", true).withParam(PER_PAGE_PARAM, getDefaultPerPage()); Response response = get(Response.Status.OK, formData.asMap(), "projects"); return (response.readEntity(new GenericType>() {})); } /** * Get a list of projects that the authenticated user is a member of in the specified page range. * * GET /projects * * @param page the page to get * @param perPage the number of projects per page * @return a list of projects that the authenticated user is a member of * @throws GitLabApiException if any exception occurs */ public List getMemberProjects(int page, int perPage) throws GitLabApiException { Form formData = new GitLabApiForm().withParam("membership", true).withParam(PAGE_PARAM, page).withParam(PER_PAGE_PARAM, perPage); Response response = get(Response.Status.OK, formData.asMap(), "projects"); return (response.readEntity(new GenericType>() {})); } /** * Get a Pager of projects that the authenticated user is a member of. * * GET /projects * * @param itemsPerPage the number of Project instances that will be fetched per page * @return a Pager o Project instances that the authenticated user is a member of * @throws GitLabApiException if any exception occurs */ public Pager getMemberProjects(int itemsPerPage) throws GitLabApiException { Form formData = new GitLabApiForm().withParam("membership", true); return (new Pager(this, Project.class, itemsPerPage, formData.asMap(), "projects")); } /** * Get a list of all GitLab projects (admin only). * * GET /projects/all * * @return a list of all GitLab projects * @throws GitLabApiException if any exception occurs * @deprecated Will be removed, no longer supported by the GitLab API */ public List getAllProjects() throws GitLabApiException { if (!isApiVersion(ApiVersion.V3)) { throw new GitLabApiException("Not supported by GitLab API version " + this.getApiVersion()); } Form formData = new GitLabApiForm().withParam(PER_PAGE_PARAM, getDefaultPerPage()); Response response = get(Response.Status.OK, formData.asMap(), "projects", "all"); return (response.readEntity(new GenericType>() {})); } /** * Get a list of projects owned by the authenticated user. * * GET /projects * * @return a list of projects owned by the authenticated user * @throws GitLabApiException if any exception occurs */ public List getOwnedProjects() throws GitLabApiException { Form formData = new GitLabApiForm().withParam("owned", true).withParam(PER_PAGE_PARAM, getDefaultPerPage()); Response response = get(Response.Status.OK, formData.asMap(), "projects"); return (response.readEntity(new GenericType>() { })); } /** * Get a list of projects owned by the authenticated user in the specified page range. * * GET /projects * * @param page the page to get * @param perPage the number of projects per page * @return a list of projects owned by the authenticated user * @throws GitLabApiException if any exception occurs */ public List getOwnedProjects(int page, int perPage) throws GitLabApiException { Form formData = new GitLabApiForm().withParam("owned", true).withParam(PAGE_PARAM, page).withParam(PER_PAGE_PARAM, perPage); Response response = get(Response.Status.OK, formData.asMap(), "projects"); return (response.readEntity(new GenericType>() {})); } /** * Get a Pager of projects owned by the authenticated user. * * GET /projects * * @param itemsPerPage the number of Project instances that will be fetched per page * @return a list of projects owned by the authenticated user * @throws GitLabApiException if any exception occurs */ public Pager getOwnedProjects(int itemsPerPage) throws GitLabApiException { Form formData = new GitLabApiForm().withParam("owned", true); return (new Pager(this, Project.class, itemsPerPage, formData.asMap(), "projects")); } /** * Get a list of projects starred by the authenticated user. * * GET /projects * * @return a list of projects starred by the authenticated user * @throws GitLabApiException if any exception occurs */ public List getStarredProjects() throws GitLabApiException { Form formData = new GitLabApiForm().withParam("starred", true).withParam(PER_PAGE_PARAM, getDefaultPerPage()); Response response = get(Response.Status.OK, formData.asMap(), "projects"); return (response.readEntity(new GenericType>() {})); } /** * Get a list of projects starred by the authenticated user in the specified page range. * * GET /projects * * @param page the page to get * @param perPage the number of projects per page * @return a list of projects starred by the authenticated user * @throws GitLabApiException if any exception occurs */ public List getStarredProjects(int page, int perPage) throws GitLabApiException { Form formData = new GitLabApiForm().withParam("starred", true).withParam(PAGE_PARAM, page).withParam(PER_PAGE_PARAM, perPage); Response response = get(Response.Status.OK, formData.asMap(), "projects"); return (response.readEntity(new GenericType>() {})); } /** * Get a Pager of projects starred by the authenticated user. * * GET /projects * * @param itemsPerPage the number of Project instances that will be fetched per page * @return a Pager of projects starred by the authenticated user * @throws GitLabApiException if any exception occurs */ public Pager getStarredProjects(int itemsPerPage) throws GitLabApiException { Form formData = new GitLabApiForm().withParam("starred", true).withParam(PER_PAGE_PARAM, getDefaultPerPage()); return (new Pager(this, Project.class, itemsPerPage, formData.asMap(), "projects")); } /** * Get a specific project, which is owned by the authentication user. * * GET /projects/:id * * @param projectId the ID of the project to get * @return the specified project * @throws GitLabApiException if any exception occurs */ public Project getProject(Integer projectId) throws GitLabApiException { Response response = get(Response.Status.OK, null, "projects", projectId); return (response.readEntity(Project.class)); } /** * Get a specific project, which is owned by the authentication user. * * GET /projects/:id * * @param projectId the ID of the project to get * @param statistics include project statistics * @return the specified project * @throws GitLabApiException if any exception occurs */ public Project getProject(Integer projectId, Boolean statistics) throws GitLabApiException { Form formData = new GitLabApiForm().withParam("statistics", statistics); Response response = get(Response.Status.OK, formData.asMap(), "projects", projectId); return (response.readEntity(Project.class)); } /** * Get an Optional instance with the value for the specific project, which is owned by the authentication user. * * GET /projects/:id * * @param projectId the ID of the project to get * @return an Optional instance with the specified project as a value */ public Optional getOptionalProject(Integer projectId) { try { return (Optional.ofNullable(getProject(projectId))); } catch (GitLabApiException glae) { return (GitLabApi.createOptionalFromException(glae)); } } /** * Get a specific project, which is owned by the authentication user. * * GET /projects/:id * * @param namespace the name of the project namespace or group * @param project the name of the project to get * @return the specified project * @throws GitLabApiException if any exception occurs */ public Project getProject(String namespace, String project) throws GitLabApiException { if (namespace == null) { throw new RuntimeException("namespace cannot be null"); } if (project == null) { throw new RuntimeException("project cannot be null"); } String projectPath = null; try { projectPath = URLEncoder.encode(namespace + "/" + project, "UTF-8"); } catch (UnsupportedEncodingException uee) { throw (new GitLabApiException(uee)); } Response response = get(Response.Status.OK, null, "projects", projectPath); return (response.readEntity(Project.class)); } /** * Get a specific project, which is owned by the authentication user. * * GET /projects/:id * * @param namespace the name of the project namespace or group * @param project the name of the project to get * @param statistics include project statistics * @return the specified project * @throws GitLabApiException if any exception occurs */ public Project getProject(String namespace, String project, Boolean statistics) throws GitLabApiException { if (namespace == null) { throw new RuntimeException("namespace cannot be null"); } if (project == null) { throw new RuntimeException("project cannot be null"); } String projectPath = null; try { projectPath = URLEncoder.encode(namespace + "/" + project, "UTF-8"); } catch (UnsupportedEncodingException uee) { throw (new GitLabApiException(uee)); } Form formData = new GitLabApiForm().withParam("statistics", statistics); Response response = get(Response.Status.OK, formData.asMap(), "projects", projectPath); return (response.readEntity(Project.class)); } /** * Get an Optional instance with the value for the specific project, which is owned by the authentication user. * * GET /projects/:id * * @param namespace the name of the project namespace or group * @param project the name of the project * @return an Optional instance with the specified project as a value */ public Optional getOptionalProject(String namespace, String project) { try { return (Optional.ofNullable(getProject(namespace, project))); } catch (GitLabApiException glae) { return (GitLabApi.createOptionalFromException(glae)); } } /** * Create a new project in the specified group. * * @param groupId the group ID to create the project under * @param projectName the name of the project top create * @return the created project * @throws GitLabApiException if any exception occurs */ public Project createProject(Integer groupId, String projectName) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm().withParam("namespace_id", groupId).withParam("name", projectName, true); Response response = post(Response.Status.CREATED, formData, "projects"); return (response.readEntity(Project.class)); } /** * Create a new project with the current user's namespace. * * @param projectName the name of the project top create * @return the created project * @throws GitLabApiException if any exception occurs */ public Project createProject(String projectName) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm().withParam("name", projectName, true); Response response = post(Response.Status.CREATED, formData, "projects"); return (response.readEntity(Project.class)); } /** * Creates new project owned by the current user. * * @param project the Project instance with the configuration for the new project * @return a Project instance with the newly created project info * @throws GitLabApiException if any exception occurs */ public Project createProject(Project project) throws GitLabApiException { return (createProject(project, null)); } /** * Creates new project owned by the current user. The following properties on the Project instance * are utilized in the creation of the project: * * name (name or path are required) - new project name * path (name or path are required) - new project path * defaultBranch (optional) - master by default * description (optional) - short project description * visibility (optional) - Limit by visibility public, internal, or private * visibilityLevel (optional) * issuesEnabled (optional) - Enable issues for this project * mergeMethod (optional) - Set the merge method used * mergeRequestsEnabled (optional) - Enable merge requests for this project * wikiEnabled (optional) - Enable wiki for this project * snippetsEnabled (optional) - Enable snippets for this project * jobsEnabled (optional) - Enable jobs for this project * containerRegistryEnabled (optional) - Enable container registry for this project * sharedRunnersEnabled (optional) - Enable shared runners for this project * publicJobs (optional) - If true, jobs can be viewed by non-project-members * onlyAllowMergeIfPipelineSucceeds (optional) - Set whether merge requests can only be merged with successful jobs * onlyAllowMergeIfAllDiscussionsAreResolved (optional) - Set whether merge requests can only be merged when all the discussions are resolved * lLfsEnabled (optional) - Enable LFS * requestAccessEnabled (optional) - Allow users to request member access * 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 * * @param project the Project instance with the configuration for the new project * @param importUrl the URL to import the repository from * @return a Project instance with the newly created project info * @throws GitLabApiException if any exception occurs */ public Project createProject(Project project, String importUrl) throws GitLabApiException { if (project == null) { return (null); } String name = project.getName(); String path = project.getPath(); if ((name == null || name.trim().length() == 0) && (path == null || path.trim().length() == 0)) { return (null); } GitLabApiForm formData = new GitLabApiForm() .withParam("name", name) .withParam("path", path) .withParam("default_branch", project.getDefaultBranch()) .withParam("description", project.getDescription()) .withParam("issues_enabled", project.getIssuesEnabled()) .withParam("merge_method", project.getMergeMethod()) .withParam("merge_requests_enabled", project.getMergeRequestsEnabled()) .withParam("jobs_enabled", project.getJobsEnabled()) .withParam("wiki_enabled", project.getWikiEnabled()) .withParam("container_registry_enabled", project.getContainerRegistryEnabled()) .withParam("snippets_enabled", project.getSnippetsEnabled()) .withParam("shared_runners_enabled", project.getSharedRunnersEnabled()) .withParam("public_jobs", project.getPublicJobs()) .withParam("visibility_level", project.getVisibilityLevel()) .withParam("only_allow_merge_if_pipeline_succeeds", project.getOnlyAllowMergeIfPipelineSucceeds()) .withParam("only_allow_merge_if_all_discussions_are_resolved", project.getOnlyAllowMergeIfAllDiscussionsAreResolved()) .withParam("lfs_enabled", project.getLfsEnabled()) .withParam("request_access_enabled", project.getRequestAccessEnabled()) .withParam("repository_storage", project.getRepositoryStorage()) .withParam("approvals_before_merge", project.getApprovalsBeforeMerge()) .withParam("import_url", importUrl) .withParam("printing_merge_request_link_enabled", project.getPrintingMergeRequestLinkEnabled()); if (isApiVersion(ApiVersion.V3)) { boolean isPublic = (project.getPublic() != null ? project.getPublic() : project.getVisibility() == Visibility.PUBLIC); formData.withParam("public", isPublic); if (project.getTagList() != null && !project.getTagList().isEmpty()) { throw new IllegalArgumentException("GitLab API v3 does not support tag lists when creating projects"); } } else { Visibility visibility = (project.getVisibility() != null ? project.getVisibility() : project.getPublic() == Boolean.TRUE ? Visibility.PUBLIC : null); formData.withParam("visibility", visibility); if (project.getTagList() != null && !project.getTagList().isEmpty()) { formData.withParam("tag_list", String.join(",", project.getTagList())); } } if (project.getNamespace() != null) { formData.withParam("namespace_id", project.getNamespace().getId()); } Response response = post(Response.Status.CREATED, formData, "projects"); return (response.readEntity(Project.class)); } /** * Creates a Project * * @param name The name of the project * @param namespaceId The Namespace for the new project, otherwise null indicates to use the GitLab default (user) * @param description A description for the project, null otherwise * @param issuesEnabled Whether Issues should be enabled, otherwise null indicates to use GitLab default * @param mergeRequestsEnabled Whether Merge Requests should be enabled, otherwise null indicates to use GitLab default * @param wikiEnabled Whether a Wiki should be enabled, otherwise null indicates to use GitLab default * @param snippetsEnabled Whether Snippets should be enabled, otherwise null indicates to use GitLab default * @param visibility The visibility of the project, otherwise null indicates to use GitLab default * @param visibilityLevel The visibility level of the project, otherwise null indicates to use GitLab default * @param importUrl The Import URL for the project, otherwise null * @return the GitLab Project * @throws GitLabApiException if any exception occurs */ public Project createProject(String name, Integer namespaceId, String description, Boolean issuesEnabled, Boolean mergeRequestsEnabled, Boolean wikiEnabled, Boolean snippetsEnabled, Visibility visibility, Integer visibilityLevel, String importUrl) throws GitLabApiException { if (isApiVersion(ApiVersion.V3)) { Boolean isPublic = Visibility.PUBLIC == visibility; return (createProject(name, namespaceId, description, issuesEnabled, mergeRequestsEnabled, wikiEnabled, snippetsEnabled, isPublic, visibilityLevel, importUrl)); } if (name == null || name.trim().length() == 0) { return (null); } GitLabApiForm formData = new GitLabApiForm() .withParam("name", name, true) .withParam("namespace_id", namespaceId) .withParam("description", description) .withParam("issues_enabled", issuesEnabled) .withParam("merge_requests_enabled", mergeRequestsEnabled) .withParam("wiki_enabled", wikiEnabled) .withParam("snippets_enabled", snippetsEnabled) .withParam("visibility_level", visibilityLevel) .withParam("visibility", visibility) .withParam("import_url", importUrl); Response response = post(Response.Status.CREATED, formData, "projects"); return (response.readEntity(Project.class)); } /** * Creates a Project * * @param name The name of the project * @param namespaceId The Namespace for the new project, otherwise null indicates to use the GitLab default (user) * @param description A description for the project, null otherwise * @param issuesEnabled Whether Issues should be enabled, otherwise null indicates to use GitLab default * @param mergeRequestsEnabled Whether Merge Requests should be enabled, otherwise null indicates to use GitLab default * @param wikiEnabled Whether a Wiki should be enabled, otherwise null indicates to use GitLab default * @param snippetsEnabled Whether Snippets should be enabled, otherwise null indicates to use GitLab default * @param visibility The visibility of the project, otherwise null indicates to use GitLab default * @param visibilityLevel The visibility level of the project, otherwise null indicates to use GitLab default * @param printingMergeRequestLinkEnabled Show link to create/view merge request when pushing from the command line * @param importUrl The Import URL for the project, otherwise null * @return the GitLab Project * @throws GitLabApiException if any exception occurs */ public Project createProject(String name, Integer namespaceId, String description, Boolean issuesEnabled, Boolean mergeRequestsEnabled, Boolean wikiEnabled, Boolean snippetsEnabled, Visibility visibility, Integer visibilityLevel, Boolean printingMergeRequestLinkEnabled, String importUrl) throws GitLabApiException { if (isApiVersion(ApiVersion.V3)) { Boolean isPublic = Visibility.PUBLIC == visibility; return (createProject(name, namespaceId, description, issuesEnabled, mergeRequestsEnabled, wikiEnabled, snippetsEnabled, isPublic, visibilityLevel, importUrl)); } if (name == null || name.trim().length() == 0) { return (null); } GitLabApiForm formData = new GitLabApiForm() .withParam("name", name, true) .withParam("namespace_id", namespaceId) .withParam("description", description) .withParam("issues_enabled", issuesEnabled) .withParam("merge_requests_enabled", mergeRequestsEnabled) .withParam("wiki_enabled", wikiEnabled) .withParam("snippets_enabled", snippetsEnabled) .withParam("visibility_level", visibilityLevel) .withParam("visibility", visibility) .withParam("printing_merge_request_link_enabled", printingMergeRequestLinkEnabled) .withParam("import_url", importUrl); Response response = post(Response.Status.CREATED, formData, "projects"); return (response.readEntity(Project.class)); } /** * Creates a Project * * @param name The name of the project * @param namespaceId The Namespace for the new project, otherwise null indicates to use the GitLab default (user) * @param description A description for the project, null otherwise * @param issuesEnabled Whether Issues should be enabled, otherwise null indicates to use GitLab default * @param mergeRequestsEnabled Whether Merge Requests should be enabled, otherwise null indicates to use GitLab default * @param wikiEnabled Whether a Wiki should be enabled, otherwise null indicates to use GitLab default * @param snippetsEnabled Whether Snippets should be enabled, otherwise null indicates to use GitLab default * @param isPublic Whether the project is public or private, if true same as setting visibilityLevel = 20, otherwise null indicates to use GitLab default * @param visibilityLevel The visibility level of the project, otherwise null indicates to use GitLab default * @param importUrl The Import URL for the project, otherwise null * @return the GitLab Project * @throws GitLabApiException if any exception occurs * @deprecated As of release 4.2.0, replaced by {@link #createProject(String, Integer, String, Boolean, Boolean, * Boolean, Boolean, Visibility, Integer, String)} */ @Deprecated public Project createProject(String name, Integer namespaceId, String description, Boolean issuesEnabled, Boolean mergeRequestsEnabled, Boolean wikiEnabled, Boolean snippetsEnabled, Boolean isPublic, Integer visibilityLevel, String importUrl) throws GitLabApiException { if (name == null || name.trim().length() == 0) { return (null); } GitLabApiForm formData = new GitLabApiForm() .withParam("name", name, true) .withParam("namespace_id", namespaceId) .withParam("description", description) .withParam("issues_enabled", issuesEnabled) .withParam("merge_requests_enabled", mergeRequestsEnabled) .withParam("wiki_enabled", wikiEnabled) .withParam("snippets_enabled", snippetsEnabled) .withParam("visibility_level", visibilityLevel) .withParam("import_url", importUrl); if (isApiVersion(ApiVersion.V3)) { formData.withParam("public", isPublic); } else if (isPublic) { formData.withParam("visibility", Visibility.PUBLIC); } Response response = post(Response.Status.CREATED, formData, "projects"); return (response.readEntity(Project.class)); } /** * Updates a project. The following properties on the Project instance * are utilized in the edit of the project, null values are not updated: * * id (required) - existing project id * name (required) - project name * path (optional) - project path * defaultBranch (optional) - master by default * description (optional) - short project description * visibility (optional) - Limit by visibility public, internal, or private * issuesEnabled (optional) - Enable issues for this project * mergeMethod (optional) - Set the merge method used * mergeRequestsEnabled (optional) - Enable merge requests for this project * wikiEnabled (optional) - Enable wiki for this project * snippetsEnabled (optional) - Enable snippets for this project * jobsEnabled (optional) - Enable jobs for this project * containerRegistryEnabled (optional) - Enable container registry for this project * sharedRunnersEnabled (optional) - Enable shared runners for this project * publicJobs (optional) - If true, jobs can be viewed by non-project-members * onlyAllowMergeIfPipelineSucceeds (optional) - Set whether merge requests can only be merged with successful jobs * onlyAllowMergeIfAllDiscussionsAreResolved (optional) - Set whether merge requests can only be merged when all the discussions are resolved * lLfsEnabled (optional) - Enable LFS * requestAccessEnabled (optional) - Allow users to request member access * 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 * * NOTE: The following parameters specified by the GitLab API edit project are not supported: * import_url * tag_list array * avatar * ci_config_path * * @param project the Project instance with the configuration for the new project * @return a Project instance with the newly updated project info * @throws GitLabApiException if any exception occurs */ public Project updateProject(Project project) throws GitLabApiException { if (project == null) { throw new RuntimeException("Project instance cannot be null."); } Integer id = project.getId(); if (id == null) { throw new RuntimeException("Project ID cannot be null."); } String name = project.getName(); if (name == null || name.trim().length() == 0) { throw new RuntimeException("Project name cannot be null or empty."); } GitLabApiForm formData = new GitLabApiForm() .withParam("name", name, true) .withParam("path", project.getPath()) .withParam("default_branch", project.getDefaultBranch()) .withParam("description", project.getDescription()) .withParam("issues_enabled", project.getIssuesEnabled()) .withParam("merge_method", project.getMergeMethod()) .withParam("merge_requests_enabled", project.getMergeRequestsEnabled()) .withParam("jobs_enabled", project.getJobsEnabled()) .withParam("wiki_enabled", project.getWikiEnabled()) .withParam("snippets_enabled", project.getSnippetsEnabled()) .withParam("container_registry_enabled", project.getContainerRegistryEnabled()) .withParam("shared_runners_enabled", project.getSharedRunnersEnabled()) .withParam("public_jobs", project.getPublicJobs()) .withParam("only_allow_merge_if_pipeline_succeeds", project.getOnlyAllowMergeIfPipelineSucceeds()) .withParam("only_allow_merge_if_all_discussions_are_resolved", project.getOnlyAllowMergeIfAllDiscussionsAreResolved()) .withParam("lfs_enabled", project.getLfsEnabled()) .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()); if (isApiVersion(ApiVersion.V3)) { formData.withParam("visibility_level", project.getVisibilityLevel()); boolean isPublic = (project.getPublic() != null ? project.getPublic() : project.getVisibility() == Visibility.PUBLIC); formData.withParam("public", isPublic); if (project.getTagList() != null && !project.getTagList().isEmpty()) { throw new IllegalArgumentException("GitLab API v3 does not support tag lists when updating projects"); } } else { Visibility visibility = (project.getVisibility() != null ? project.getVisibility() : project.getPublic() == Boolean.TRUE ? Visibility.PUBLIC : null); formData.withParam("visibility", visibility); if (project.getTagList() != null && !project.getTagList().isEmpty()) { formData.withParam("tag_list", String.join(",", project.getTagList())); } } Response response = putWithFormData(Response.Status.OK, formData, "projects", id); return (response.readEntity(Project.class)); } /** * Removes project with all resources(issues, merge requests etc). * * DELETE /projects/:id * * @param projectId the project ID to remove * @throws GitLabApiException if any exception occurs */ public void deleteProject(Integer projectId) throws GitLabApiException { if (projectId == null) { throw new RuntimeException("projectId cannot be null"); } Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.ACCEPTED); delete(expectedStatus, null, "projects", projectId); } /** * Removes project with all resources(issues, merge requests etc). * * DELETE /projects/:id * * @param project the Project instance to remove * @throws GitLabApiException if any exception occurs */ public void deleteProject(Project project) throws GitLabApiException { deleteProject(project.getId()); } /** * Forks a project into the user namespace of the authenticated user or the one provided. * The forking operation for a project is asynchronous and is completed in a background job. * The request will return immediately. * * POST /projects/:id/fork * * @param id the ID of the project to fork * @param namespace path of the namespace that the project will be forked to * @return the newly forked Project instance * @throws GitLabApiException if any exception occurs */ public Project forkProject(Integer id, String namespace) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm().withParam("namespace", namespace, true); Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.CREATED); Response response = post(expectedStatus, formData, "projects", id, "fork"); return (response.readEntity(Project.class)); } /** * Forks a project into the user namespace of the authenticated user or the one provided. * The forking operation for a project is asynchronous and is completed in a background job. * The request will return immediately. * * POST /projects/:id/fork * * @param project the project to fork * @param namespace path of the namespace that the project will be forked to * @return the newly forked Project instance * @throws GitLabApiException if any exception occurs */ public Project forkProject(Project project, String namespace) throws GitLabApiException { return (forkProject(project.getId(), namespace)); } /** * Forks a project into the user namespace of the authenticated user or the one provided. * The forking operation for a project is asynchronous and is completed in a background job. * The request will return immediately. * * POST /projects/:id/fork * * @param id the ID of the project to fork * @param namespaceId ID of the namespace that the project will be forked to * @return the newly forked Project instance * @throws GitLabApiException if any exception occurs */ public Project forkProject(Integer id, Integer namespaceId) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm().withParam("namespace", namespaceId, true); Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.CREATED); Response response = post(expectedStatus, formData, "projects", id, "fork"); return (response.readEntity(Project.class)); } /** * Forks a project into the user namespace of the authenticated user or the one provided. * The forking operation for a project is asynchronous and is completed in a background job. * The request will return immediately. * * POST /projects/:id/fork * * @param project the project to fork * @param namespaceId ID of the namespace that the project will be forked to * @return the newly forked Project instance * @throws GitLabApiException if any exception occurs */ public Project forkProject(Project project, Integer namespaceId) throws GitLabApiException { return (forkProject(project.getId(), namespaceId)); } /** * Get a list of project team members. * * GET /projects/:id/members * * @param projectId the project ID to get team members for * @return the members belonging to the specified project * @throws GitLabApiException if any exception occurs */ public List getMembers(Integer projectId) throws GitLabApiException { Response response = get(Response.Status.OK, this.getDefaultPerPageParam(), "projects", projectId, "members"); return (response.readEntity(new GenericType>() {})); } /** * Get a list of project team members in the specified page range. * * GET /projects/:id/members * * @param projectId the project ID to get team members for * @param page the page to get * @param perPage the number of Member instances per page * @return the members belonging to the specified project * @throws GitLabApiException if any exception occurs */ public List getMembers(Integer projectId, int page, int perPage) throws GitLabApiException { Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "projects", projectId, "members"); return (response.readEntity(new GenericType>() {})); } /** * Get a Pager of project team members. * * GET /projects/:id/members * * @param projectId the project ID to get team members for * @param itemsPerPage the number of Project instances that will be fetched per page * @return the members belonging to the specified project * @throws GitLabApiException if any exception occurs */ public Pager getMembers(Integer projectId, int itemsPerPage) throws GitLabApiException { return (new Pager(this, Member.class, itemsPerPage, null, "projects", projectId, "members")); } /** * Gets a project team member. * * GET /projects/:id/members/:user_id * * @param projectId the project ID to get team member for * @param userId the user ID of the member * @return the member specified by the project ID/user ID pair * @throws GitLabApiException if any exception occurs */ public Member getMember(Integer projectId, Integer userId) throws GitLabApiException { Response response = get(Response.Status.OK, null, "projects", projectId, "members", userId); return (response.readEntity(Member.class)); } /** * Gets a project team member. * * GET /projects/:id/members/:user_id * * @param projectId the project ID to get team member for * @param userId the user ID of the member * @return the member specified by the project ID/user ID pair * @throws GitLabApiException if any exception occurs */ public Optional getOptionalMember(Integer projectId, Integer userId) throws GitLabApiException { try { return (Optional.ofNullable(getMember(projectId, userId))); } catch (GitLabApiException glae) { return (GitLabApi.createOptionalFromException(glae)); } } /** * Adds a user to a project team. This is an idempotent method and can be called multiple times * with the same parameters. Adding team membership to a user that is already a member does not * affect the existing membership. * * POST /projects/:id/members * * @param projectId the project ID to add the team member to, required * @param userId the user ID of the member to add, required * @param accessLevel the access level for the new member, required * @return the added member * @throws GitLabApiException if any exception occurs */ public Member addMember(Integer projectId, Integer userId, Integer accessLevel) throws GitLabApiException { return (addMember(projectId, userId, accessLevel, null)); } /** * Adds a user to a project team. This is an idempotent method and can be called multiple times * with the same parameters. Adding team membership to a user that is already a member does not * affect the existing membership. * * POST /projects/:id/members * * @param projectId the project ID to add the team member to, required * @param userId the user ID of the member to add, required * @param accessLevel the access level for the new member, required * @return the added member * @throws GitLabApiException if any exception occurs */ public Member addMember(Integer projectId, Integer userId, AccessLevel accessLevel) throws GitLabApiException { return (addMember(projectId, userId, accessLevel.toValue(), null)); } /** * Adds a user to a project team. This is an idempotent method and can be called multiple times * with the same parameters. Adding team membership to a user that is already a member does not * affect the existing membership. * * POST /projects/:id/members * * @param projectId the project ID to add the team member to * @param userId the user ID of the member to add * @param accessLevel the access level for the new member * @param expiresAt the date the membership in the group will expire * @return the added member * @throws GitLabApiException if any exception occurs */ public Member addMember(Integer projectId, Integer userId, AccessLevel accessLevel, Date expiresAt) throws GitLabApiException { return (addMember(projectId, userId, accessLevel.toValue(), expiresAt)); } /** * Adds a user to a project team. This is an idempotent method and can be called multiple times * with the same parameters. Adding team membership to a user that is already a member does not * affect the existing membership. * * POST /projects/:id/members * * @param projectId the project ID to add the team member to * @param userId the user ID of the member to add * @param accessLevel the access level for the new member * @param expiresAt the date the membership in the group will expire * @return the added member * @throws GitLabApiException if any exception occurs */ public Member addMember(Integer projectId, Integer userId, Integer accessLevel, Date expiresAt) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("user_id", userId, true) .withParam("access_level", accessLevel, true) .withParam("expires_at", expiresAt, false); Response response = post(Response.Status.CREATED, formData, "projects", projectId, "members"); return (response.readEntity(Member.class)); } /** * Updates a member of a project. * * PUT /projects/:projectId/members/:userId * * @param projectId the project ID the member belongs to, required * @param userId the user ID of the member to update, required * @param accessLevel the new access level for the member, required * @return the updated member * @throws GitLabApiException if any exception occurs */ public Member updateMember(Integer projectId, Integer userId, Integer accessLevel) throws GitLabApiException { return (updateMember(projectId, userId, accessLevel, null)); } /** * Updates a member of a project. * * PUT /projects/:projectId/members/:userId * * @param projectId the project ID the member belongs to, required * @param userId the user ID of the member to update, required * @param accessLevel the new access level for the member, required * @return the updated member * @throws GitLabApiException if any exception occurs */ public Member updateMember(Integer projectId, Integer userId, AccessLevel accessLevel) throws GitLabApiException { return (updateMember(projectId, userId, accessLevel.toValue(), null)); } /** * Updates a member of a project. * * PUT /projects/:projectId/members/:userId * * @param projectId the project ID the member belongs to, required * @param userId the user ID of the member to update, required * @param accessLevel the new access level for the member, required * @param expiresAt the date the membership in the group will expire, optional * @return the updated member * @throws GitLabApiException if any exception occurs */ public Member updateMember(Integer projectId, Integer userId, AccessLevel accessLevel, Date expiresAt) throws GitLabApiException { return (updateMember(projectId, userId, accessLevel.toValue(), expiresAt)); } /** * Updates a member of a project. * * PUT /projects/:projectId/members/:userId * * @param projectId the project ID the member belongs to, required * @param userId the user ID of the member to update, required * @param accessLevel the new access level for the member, required * @param expiresAt the date the membership in the group will expire, optional * @return the updated member * @throws GitLabApiException if any exception occurs */ public Member updateMember(Integer projectId, Integer userId, Integer accessLevel, Date expiresAt) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("access_level", accessLevel, true) .withParam("expires_at", expiresAt, false); Response response = put(Response.Status.OK, formData.asMap(), "projects", projectId, "members", userId); return (response.readEntity(Member.class)); } /** * Removes user from project team. * * DELETE /projects/:id/members/:user_id * * @param projectId the project ID to remove the team member from * @param userId the user ID of the member to remove * @throws GitLabApiException if any exception occurs */ public void removeMember(Integer projectId, Integer userId) throws GitLabApiException { Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.NO_CONTENT); delete(expectedStatus, null, "projects", projectId, "members", userId); } /** * Get a list of project users. This list includes all project members and all users assigned to project parent groups. * * GET /projects/:id/users * * @param projectId the project ID to get users for * @return the users belonging to the specified project and its parent groups * @throws GitLabApiException if any exception occurs */ public List getProjectUsers(Integer projectId) throws GitLabApiException { Response response = get(Response.Status.OK, getDefaultPerPageParam(), "projects", projectId, "users"); return (response.readEntity(new GenericType>() {})); } /** * Get a list of project users matching the specified search string. This list includes all project members and all users assigned to project parent groups. * * GET /projects/:id/users * * @param projectId the project ID to get users for * @param search the string to match specific users * @return the users matching the search string and belonging to the specified project and its parent groups * @throws GitLabApiException if any exception occurs */ public List getProjectUsers(Integer projectId, String search) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("search", search) .withParam(PER_PAGE_PARAM, getDefaultPerPage()); Response response = get(Response.Status.OK, formData.asMap(), "projects", projectId, "users"); return (response.readEntity(new GenericType>() {})); } /** * Get the project events for specific project. Sorted from newest to latest. * * GET /projects/:id/events * * @param projectId the project ID to get events for * @return the project events for the specified project * @throws GitLabApiException if any exception occurs */ public List getProjectEvents(Integer projectId) throws GitLabApiException { Response response = get(Response.Status.OK, getDefaultPerPageParam(), "projects", projectId, "events"); return (response.readEntity(new GenericType>() {})); } /** * Get the project events for specific project. Sorted from newest to latest in the specified page range. * * GET /projects/:id/events * * @param projectId the project ID to get events for * @param page the page to get * @param perPage the number of Event instances per page * @return the project events for the specified project * @throws GitLabApiException if any exception occurs */ public List getProjectEvents(Integer projectId, int page, int perPage) throws GitLabApiException { Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "projects", projectId, "events"); return (response.readEntity(new GenericType>() {})); } /** * Get a Pager of project events for specific project. Sorted from newest to latest. * * GET /projects/:id/events * * @param projectId the project ID to get events for * @param itemsPerPage the number of Project instances that will be fetched per page * @return a Pager of project events for the specified project * @throws GitLabApiException if any exception occurs */ public Pager getProjectEvents(Integer projectId, int itemsPerPage) throws GitLabApiException { return (new Pager(this, Event.class, itemsPerPage, null, "projects", projectId, "events")); } /** * Get list of project hooks. * * GET /projects/:id/hooks * * @param projectId the project ID to get project hooks for * @return a list of project hooks for the specified project * @throws GitLabApiException if any exception occurs */ public List getHooks(Integer projectId) throws GitLabApiException { Response response = get(Response.Status.OK, getDefaultPerPageParam(), "projects", projectId, "hooks"); return (response.readEntity(new GenericType>() {})); } /** * Get list of project hooks in the specified page range. * * GET /projects/:id/hooks * * @param projectId the project ID to get project hooks for * @param page the page to get * @param perPage the number of ProjectHook instances per page * @return a list of project hooks for the specified project in the specified page range * @throws GitLabApiException if any exception occurs */ public List getHooks(Integer projectId, int page, int perPage) throws GitLabApiException { Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "projects", projectId, "hooks"); return (response.readEntity(new GenericType>() {})); } /** * Get Pager of project hooks. * * GET /projects/:id/hooks * * @param projectId the project ID to get project hooks for * @param itemsPerPage the number of Project instances that will be fetched per page * @return a Pager of project hooks for the specified project * @throws GitLabApiException if any exception occurs */ public Pager getHooks(Integer projectId, int itemsPerPage) throws GitLabApiException { return (new Pager(this, ProjectHook.class, itemsPerPage, null, "projects", projectId, "hooks")); } /** * Get a specific hook for project. * * GET /projects/:id/hooks/:hook_id * * @param projectId the project ID to get the hook for * @param hookId the ID of the hook to get * @return the project hook for the specified project ID/hook ID pair * @throws GitLabApiException if any exception occurs */ public ProjectHook getHook(Integer projectId, Integer hookId) throws GitLabApiException { Response response = get(Response.Status.OK, null, "projects", projectId, "hooks", hookId); return (response.readEntity(ProjectHook.class)); } /** * Get a specific hook for project as an Optional instance. * * GET /projects/:id/hooks/:hook_id * * @param projectId the project ID to get the hook for * @param hookId the ID of the hook to get * @return the project hook for the specified project ID/hook ID pair as an Optional instance */ public Optional getOptionalHook(Integer projectId, Integer hookId) { try { return (Optional.ofNullable(getHook(projectId, hookId))); } catch (GitLabApiException glae) { return (GitLabApi.createOptionalFromException(glae)); } } /** * Adds a hook to project. * * POST /projects/:id/hooks * * @param projectName the name of the project * @param url the callback URL for the hook * @param enabledHooks a ProjectHook instance specifying which hooks to enable * @param enableSslVerification enable SSL verification * @param secretToken the secret token to pass back to the hook * @return the added ProjectHook instance * @throws GitLabApiException if any exception occurs */ public ProjectHook addHook(String projectName, String url, ProjectHook enabledHooks, boolean enableSslVerification, String secretToken) throws GitLabApiException { if (projectName == null) { return (null); } GitLabApiForm formData = new GitLabApiForm() .withParam("url", url, true) .withParam("push_events", enabledHooks.getPushEvents(), false) .withParam("issues_events", enabledHooks.getIssuesEvents(), false) .withParam("merge_requests_events", enabledHooks.getMergeRequestsEvents(), false) .withParam("tag_push_events", enabledHooks.getTagPushEvents(), false) .withParam("note_events", enabledHooks.getNoteEvents(), false) .withParam("job_events", enabledHooks.getJobEvents(), false) .withParam("pipeline_events", enabledHooks.getPipelineEvents(), false) .withParam("wiki_events", enabledHooks.getWikiPageEvents(), false) .withParam("enable_ssl_verification", enabledHooks.getEnableSslVerification()) .withParam("token", secretToken, false); Response response = post(Response.Status.CREATED, formData, "projects", projectName, "hooks"); return (response.readEntity(ProjectHook.class)); } /** * Adds a hook to project. * * POST /projects/:id/hooks * * @param projectId the project ID to add the project hook to * @param url the callback URL for the hook * @param enabledHooks a ProjectHook instance specifying which hooks to enable * @param enableSslVerification enable SSL verification * @param secretToken the secret token to pass back to the hook * @return the added ProjectHook instance * @throws GitLabApiException if any exception occurs */ public ProjectHook addHook(Integer projectId, String url, ProjectHook enabledHooks, boolean enableSslVerification, String secretToken) throws GitLabApiException { if (projectId == null) { return (null); } GitLabApiForm formData = new GitLabApiForm() .withParam("url", url, true) .withParam("push_events", enabledHooks.getPushEvents(), false) .withParam("issues_events", enabledHooks.getIssuesEvents(), false) .withParam("merge_requests_events", enabledHooks.getMergeRequestsEvents(), false) .withParam("tag_push_events", enabledHooks.getTagPushEvents(), false) .withParam("note_events", enabledHooks.getNoteEvents(), false) .withParam("job_events", enabledHooks.getJobEvents(), false) .withParam("pipeline_events", enabledHooks.getPipelineEvents(), false) .withParam("wiki_events", enabledHooks.getWikiPageEvents(), false) .withParam("enable_ssl_verification", enabledHooks.getEnableSslVerification()) .withParam("token", secretToken, false); Response response = post(Response.Status.CREATED, formData, "projects", projectId, "hooks"); return (response.readEntity(ProjectHook.class)); } /** * Adds a hook to project. * * POST /projects/:id/hooks * * @param project the Project instance to add the project hook to * @param url the callback URL for the hook * @param enabledHooks a ProjectHook instance specifying which hooks to enable * @param enableSslVerification enable SSL verification * @param secretToken the secret token to pass back to the hook * @return the added ProjectHook instance * @throws GitLabApiException if any exception occurs */ public ProjectHook addHook(Project project, String url, ProjectHook enabledHooks, boolean enableSslVerification, String secretToken) throws GitLabApiException { if (project == null) { return (null); } return (addHook(project.getId(), url, enabledHooks, enableSslVerification, secretToken)); } /** * Adds a hook to project. * * POST /projects/:id/hooks * * @param project the Project instance to add the project hook to * @param url the callback URL for the hook * @param doPushEvents flag specifying whether to do push events * @param doIssuesEvents flag specifying whether to do issues events * @param doMergeRequestsEvents flag specifying whether to do merge requests events * @return the added ProjectHook instance * @throws GitLabApiException if any exception occurs */ public ProjectHook addHook(Project project, String url, boolean doPushEvents, boolean doIssuesEvents, boolean doMergeRequestsEvents) throws GitLabApiException { if (project == null) { return (null); } return (addHook(project.getId(), url, doPushEvents, doIssuesEvents, doMergeRequestsEvents)); } /** * Adds a hook to project. * * POST /projects/:id/hooks * * @param projectId the project ID to add the project hook to * @param url the callback URL for the hook * @param doPushEvents flag specifying whether to do push events * @param doIssuesEvents flag specifying whether to do issues events * @param doMergeRequestsEvents flag specifying whether to do merge requests events * @return the added ProjectHook instance * @throws GitLabApiException if any exception occurs */ public ProjectHook addHook(Integer projectId, String url, boolean doPushEvents, boolean doIssuesEvents, boolean doMergeRequestsEvents) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("url", url) .withParam("push_events", doPushEvents) .withParam("issues_enabled", doIssuesEvents) .withParam("merge_requests_events", doMergeRequestsEvents); Response response = post(Response.Status.CREATED, formData, "projects", projectId, "hooks"); return (response.readEntity(ProjectHook.class)); } /** * Deletes a hook from the project. * * DELETE /projects/:id/hooks/:hook_id * * @param projectId the project ID to delete the project hook from * @param hookId the project hook ID to delete * @throws GitLabApiException if any exception occurs */ public void deleteHook(Integer projectId, Integer hookId) throws GitLabApiException { Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.NO_CONTENT); delete(expectedStatus, null, "projects", projectId, "hooks", hookId); } /** * Deletes a hook from the project. * * DELETE /projects/:id/hooks/:hook_id * * @param hook the ProjectHook instance to remove * @throws GitLabApiException if any exception occurs */ public void deleteHook(ProjectHook hook) throws GitLabApiException { deleteHook(hook.getProjectId(), hook.getId()); } /** * Modifies a hook for project. * * PUT /projects/:id/hooks/:hook_id * * @param hook the ProjectHook instance that contains the project hook info to modify * @return the modified project hook * @throws GitLabApiException if any exception occurs */ public ProjectHook modifyHook(ProjectHook hook) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("url", hook.getUrl(), true) .withParam("push_events", hook.getPushEvents(), false) .withParam("issues_events", hook.getIssuesEvents(), false) .withParam("merge_requests_events", hook.getMergeRequestsEvents(), false) .withParam("tag_push_events", hook.getTagPushEvents(), false) .withParam("note_events", hook.getNoteEvents(), false) .withParam("job_events", hook.getJobEvents(), false) .withParam("pipeline_events", hook.getPipelineEvents(), false) .withParam("wiki_events", hook.getWikiPageEvents(), false) .withParam("enable_ssl_verification", hook.getEnableSslVerification(), false) .withParam("token", hook.getToken(), false); Response response = put(Response.Status.OK, formData.asMap(), "projects", hook.getProjectId(), "hooks", hook.getId()); return (response.readEntity(ProjectHook.class)); } /** * Get a list of project's issues. Only returns the first page * * GET /projects/:id/issues * * @param projectId the project ID to get the issues for * @return a list of project's issues * @throws GitLabApiException if any exception occurs * @deprecated Will be removed in version 5.0, replaced by {@link IssuesApi#getIssues(Integer)} */ public List getIssues(Integer projectId) throws GitLabApiException { Response response = get(Response.Status.OK, getDefaultPerPageParam(), "projects", projectId, "issues"); return (response.readEntity(new GenericType>() {})); } /** * Get a list of project's issues using the specified page and per page settings. * * GET /projects/:id/issues * * @param projectId the project ID to get the issues for * @param page the page to get * @param perPage the number of issues per page * @return the list of issues in the specified range * @throws GitLabApiException if any exception occurs * @deprecated Will be removed in version 5.0, replaced by {@link IssuesApi#getIssues(Integer, int, int)} */ public List getIssues(Integer projectId, int page, int perPage) throws GitLabApiException { Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "projects", projectId, "issues"); return (response.readEntity(new GenericType>() {})); } /** * Get a Pager of project's issues. * * GET /projects/:id/issues * * @param projectId the project ID to get the issues for * @param itemsPerPage the number of issues per page * @return the list of issues in the specified range * @throws GitLabApiException if any exception occurs * @deprecated Will be removed in version 5.0, replaced by {@link IssuesApi#getIssues(Integer, int)} */ public Pager getIssues(Integer projectId, int itemsPerPage) throws GitLabApiException { return (new Pager(this, Issue.class, itemsPerPage, null, "projects", projectId, "issues")); } /** * Get a single project issues. * * GET /projects/:id/issues/:issue_iid * * @param projectId the project ID to get the issue for * @param issueId the internal ID of a project's issue * @return the specified Issue instance * @throws GitLabApiException if any exception occurs * @deprecated Will be removed in version 5.0, replaced by {@link IssuesApi#getIssue(Integer, Integer)} */ public Issue getIssue(Integer projectId, Integer issueId) throws GitLabApiException { Response response = get(Response.Status.OK, getDefaultPerPageParam(), "projects", projectId, "issues", issueId); return (response.readEntity(Issue.class)); } /** * Delete a project issue. * * DELETE /projects/:id/issues/:issue_iid * * @param projectId the project ID to delete the issue from * @param issueId the internal ID of a project's issue * @throws GitLabApiException if any exception occurs * @deprecated Will be removed in version 5.0, replaced by {@link IssuesApi#deleteIssue(Integer, Integer)} */ public void deleteIssue(Integer projectId, Integer issueId) throws GitLabApiException { Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.NO_CONTENT); delete(expectedStatus, getDefaultPerPageParam(), "projects", projectId, "issues", issueId); } /** * Get a list of project snippets. This only returns the first page of snippets. * * GET /projects/:id/snippets * * @param projectId the project ID to get the snippets for * @return a list of project's snippets * @throws GitLabApiException if any exception occurs */ public List getSnippets(Integer projectId) throws GitLabApiException { return (getSnippets(projectId, 1, this.getDefaultPerPage())); } /** * Get a list of project snippets. This only returns the first page of snippets. * * GET /projects/:id/snippets * * @param projectId the project ID to get the snippets for * @param page the page to get * @param perPage the number of snippets per page * @return a list of project's snippets for the specified range * @throws GitLabApiException if any exception occurs */ public List getSnippets(Integer projectId, int page, int perPage) throws GitLabApiException { Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "projects", projectId, "snippets"); return (response.readEntity(new GenericType>() {})); } /** * Get a Pager of project's snippets. * * GET /projects/:id/snippets * * @param projectId the project ID to get the issues for * @param itemsPerPage the number of snippets per page * @return the Pager of snippets * @throws GitLabApiException if any exception occurs */ public Pager getSnippets(Integer projectId, int itemsPerPage) throws GitLabApiException { return (new Pager(this, Snippet.class, itemsPerPage, null, "projects", projectId, "snippets")); } /** * Get a single of project snippet. * * GET /projects/:id/snippets/:snippet_id * * @param projectId the project ID to get the snippet for * @param snippetId the ID of the project's snippet * @return the specified project Snippet * @throws GitLabApiException if any exception occurs */ public Snippet getSnippet(Integer projectId, Integer snippetId) throws GitLabApiException { Response response = get(Response.Status.OK, null, "projects", projectId, "snippets", snippetId); return (response.readEntity(Snippet.class)); } /** * Get a single of project snippet as an Optional instance. * * GET /projects/:id/snippets/:snippet_id * * @param projectId the project ID to get the snippet for * @param snippetId the ID of the project's snippet * @return the specified project Snippet as an Optional instance */ public Optional getOptionalSnippet(Integer projectId, Integer snippetId) { try { return (Optional.ofNullable(getSnippet(projectId, snippetId))); } catch (GitLabApiException glae) { return (GitLabApi.createOptionalFromException(glae)); } } /** * Creates a new project snippet. The user must have permission to create new snippets. * * POST /projects/:id/snippets * * @param projectId the ID of the project owned by the authenticated user, required * @param title the title of a snippet, required * @param filename the name of a snippet file, required * @param description the description of a snippet, optional * @param code the content of a snippet, required * @param visibility the snippet's visibility, required * @return a Snippet instance with info on the created snippet * @throws GitLabApiException if any exception occurs */ public Snippet createSnippet(Integer projectId, String title, String filename, String description, String code, Visibility visibility) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("title", title, true) .withParam("file_name", filename, true) .withParam("description", description) .withParam("code", code, true) .withParam("visibility", visibility, true); Response response = post(Response.Status.CREATED, formData, "projects", projectId, "snippets"); return (response.readEntity(Snippet.class)); } /** * Updates an existing project snippet. The user must have permission to change an existing snippet. * * PUT /projects/:id/snippets/:snippet_id * * @param projectId the ID of the project owned by the authenticated user, required * @param snippetId the ID of a project's snippet, required * @param title the title of a snippet, optional * @param filename the name of a snippet file, optional * @param description the description of a snippet, optioptionalonal * @param code the content of a snippet, optional * @param visibility the snippet's visibility, reqoptionaluired * @return a Snippet instance with info on the updated snippet * @throws GitLabApiException if any exception occurs */ public Snippet updateSnippet(Integer projectId, Integer snippetId, String title, String filename, String description, String code, Visibility visibility) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("title", title) .withParam("file_name", filename) .withParam("description", description) .withParam("code", code) .withParam("visibility", visibility); Response response = put(Response.Status.OK, formData.asMap(), "projects", projectId, "snippets", snippetId); return (response.readEntity(Snippet.class)); } /* * Deletes an existing project snippet. This is an idempotent function and deleting a * non-existent snippet does not cause an error. * * DELETE /projects/:id/snippets/:snippet_id * * @param projectId the project ID of the snippet * @param snippetId the ID of the project's snippet * @throws GitLabApiException if any exception occurs */ public void deleteSnippet(Integer projectId, Integer snippetId) throws GitLabApiException { delete(Response.Status.NO_CONTENT, null, "projects", projectId, "snippets", snippetId); } /** * Get the raw project snippet as plain text. * * GET /projects/:id/snippets/:snippet_id/raw * * @param projectId the project ID of the snippet * @param snippetId the ID of the project's snippet * @return the raw project snippet plain text as an Optional instance * @throws GitLabApiException if any exception occurs */ public String getRawSnippetContent(Integer projectId, Integer snippetId) throws GitLabApiException { Response response = get(Response.Status.OK, null, "projects", projectId, "snippets", snippetId, "raw"); return (response.readEntity(String.class)); } /** * Get the raw project snippet plain text as an Optional instance. * * GET /projects/:id/snippets/:snippet_id/raw * * @param projectId the project ID of the snippet * @param snippetId the ID of the project's snippet * @return the raw project snippet plain text as an Optional instance */ public Optional getOptionalRawSnippetContent(Integer projectId, Integer snippetId) { try { return (Optional.ofNullable(getRawSnippetContent(projectId, snippetId))); } catch (GitLabApiException glae) { return (GitLabApi.createOptionalFromException(glae)); } } /** * Share a project with the specified group. * * POST /projects/:id/share * * @param projectId the ID of the project to share, required * @param groupId the ID of the group to share with, required * @param accessLevel the permissions level to grant the group, required * @param expiresAt the share expiration date, optional * @throws GitLabApiException if any exception occurs */ public void shareProject(Integer projectId, Integer groupId, AccessLevel accessLevel, Date expiresAt) throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("group_id", groupId, true) .withParam("group_access", accessLevel, true) .withParam("expires_at", expiresAt); post(Response.Status.CREATED, formData, "projects", projectId, "share"); } /** * Unshare the project from the group. * * DELETE /projects/:id/share/:group_id * * @param projectId the ID of the project to unshare, required * @param groupId the ID of the group to unshare, required * @throws GitLabApiException if any exception occurs */ public void unshareProject(Integer projectId, Integer groupId) throws GitLabApiException { Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.NO_CONTENT); delete(expectedStatus, null, "projects", projectId, "share", groupId); } /** * Archive a project * * POST /projects/:id/archive * * @param projectId the ID of the project to archive, required * @return the archived GitLab Project * @throws GitLabApiException if any exception occurs */ public Project archiveProject(Integer projectId) throws GitLabApiException { Response response = post(Response.Status.CREATED, (new GitLabApiForm()), "projects", projectId, "archive"); return (response.readEntity(Project.class)); } /** * Unarchive a project * * POST /projects/:id/unarchive * * @param projectId the ID of the project to unarchive, required * @return the unarchived GitLab Project * @throws GitLabApiException if any exception occurs */ public Project unarchiveProject(Integer projectId) throws GitLabApiException { Response response = post(Response.Status.CREATED, (new GitLabApiForm()), "projects", projectId, "unarchive"); return (response.readEntity(Project.class)); } /** * Uploads a file to the specified project to be used in an issue or merge request description, or a comment. * * POST /projects/:id/uploads * * @param projectId the ID of the project to upload the file to, required * @param fileToUpload the File instance of the file to upload, required * @return a FileUpload instance with information on the just uploaded file * @throws GitLabApiException if any exception occurs */ public FileUpload uploadFile(Integer projectId, File fileToUpload) throws GitLabApiException { return (uploadFile(projectId, fileToUpload, null)); } /** * Uploads a file to the specified project to be used in an issue or merge request description, or a comment. * * POST /projects/:id/uploads * * @param projectId the ID of the project to upload the file to, required * @param fileToUpload the File instance of the file to upload, required * @param mediaType the media type of the file to upload, optional * @return a FileUpload instance with information on the just uploaded file * @throws GitLabApiException if any exception occurs */ public FileUpload uploadFile(Integer projectId, File fileToUpload, String mediaType) throws GitLabApiException { Response response = upload(Response.Status.CREATED, "file", fileToUpload, mediaType, "projects", projectId, "uploads"); return (response.readEntity(FileUpload.class)); } /** * Get the project's push rules. * * GET /projects/:id/push_rule * * @param projectId the project ID to get the push rules for * @return the push rules for the specified project * @throws GitLabApiException if any exception occurs */ public PushRules getPushRules(Integer projectId) throws GitLabApiException { Response response = get(Response.Status.OK, null, "projects", projectId, "push_rule"); return (response.readEntity(PushRules.class)); } /** * Adds a push rule to a specified project. * * POST /projects/:id/push_rule * * The following properties on the PushRules instance are utilized in the creation of the push rule: * * * denyDeleteTag (optional) - Deny deleting a tag * memberCheck (optional) - Restrict commits by author (email) to existing GitLab users * preventSecrets (optional) - GitLab will reject any files that are likely to contain secrets * commitMessageRegex (optional) - All commit messages must match this, e.g. Fixed \d+\..* * branchNameRegex (optional) - All branch names must match this, e.g. `(feature * authorEmailRegex (optional) - All commit author emails must match this, e.g. @my-company.com$ * fileNameRegex (optional) - All committed filenames must not match this, e.g. `(jar * maxFileSize (optional) - Maximum file size (MB * * * @param projectId the project ID to add the push rule to * @param pushRule the PushRule instance containing the push rule configuration to add * @return a PushRules instance with the newly created push rule info * @throws GitLabApiException if any exception occurs */ public PushRules createPushRules(Integer projectId, PushRules pushRule) throws GitLabApiException { if (projectId == null) { throw new RuntimeException("projectId cannot be null"); } GitLabApiForm formData = new GitLabApiForm() .withParam("deny_delete_tag", pushRule.getDenyDeleteTag()) .withParam("member_check", pushRule.getMemberCheck()) .withParam("prevent_secrets", pushRule.getPreventSecrets()) .withParam("commit_message_regex", pushRule.getCommitMessageRegex()) .withParam("branch_name_regex", pushRule.getBranchNameRegex()) .withParam("author_email_regex", pushRule.getAuthorEmailRegex()) .withParam("file_name_regex", pushRule.getFileNameRegex()) .withParam("max_file_size", pushRule.getMaxFileSize()); Response response = post(Response.Status.CREATED, formData, "projects", projectId, "push_rule"); return (response.readEntity(PushRules.class)); } /** * Updates a push rule for the specified project. * * PUT /projects/:id/push_rule/:push_rule_id * * The following properties on the PushRules instance are utilized when updating the push rule: * * * denyDeleteTag (optional) - Deny deleting a tag * memberCheck (optional) - Restrict commits by author (email) to existing GitLab users * preventSecrets (optional) - GitLab will reject any files that are likely to contain secrets * commitMessageRegex (optional) - All commit messages must match this, e.g. Fixed \d+\..* * branchNameRegex (optional) - All branch names must match this, e.g. `(feature * authorEmailRegex (optional) - All commit author emails must match this, e.g. @my-company.com$ * fileNameRegex (optional) - All committed filenames must not match this, e.g. `(jar * maxFileSize (optional) - Maximum file size (MB * * * @param projectId the project ID to update the push rule for * @param pushRule the PushRules instance containing the push rule configuration to update * @return a PushRules instance with the newly created push rule info * @throws GitLabApiException if any exception occurs */ public PushRules updatePushRules(Integer projectId, PushRules pushRule) throws GitLabApiException { if (projectId == null) { throw new RuntimeException("projectId cannot be null"); } GitLabApiForm formData = new GitLabApiForm() .withParam("deny_delete_tag", pushRule.getDenyDeleteTag()) .withParam("member_check", pushRule.getMemberCheck()) .withParam("prevent_secrets", pushRule.getPreventSecrets()) .withParam("commit_message_regex", pushRule.getCommitMessageRegex()) .withParam("branch_name_regex", pushRule.getBranchNameRegex()) .withParam("author_email_regex", pushRule.getAuthorEmailRegex()) .withParam("file_name_regex", pushRule.getFileNameRegex()) .withParam("max_file_size", pushRule.getMaxFileSize()); final Response response = putWithFormData(Response.Status.OK, formData, "projects", projectId, "push_rule"); return (response.readEntity(PushRules.class)); } /** * Removes a push rule from a project. This is an idempotent method and can be * called multiple times. Either the push rule is available or not. * * DELETE /projects/:id/push_rule * * @param projectId the project ID to delete the push rule from * @throws GitLabApiException if any exception occurs */ public void deletePushRules(Integer projectId) throws GitLabApiException { if (projectId == null) { throw new RuntimeException("projectId cannot be null"); } delete(Response.Status.OK, null, "projects", projectId, "push_rule"); } /** * Get a list of projects that were forked from the specified project. * * GET /projects/:id/forks * * @param projectId the ID of the project * @return a List of forked projects * @throws GitLabApiException if any exception occurs */ public List getForks(Integer projectId) throws GitLabApiException { return (getForks(projectId, 1, getDefaultPerPage())); } /** * Get a list of projects that were forked from the specified project and in the specified page range. * * GET /projects/:id/forks * * @param projectId the ID of the project * @param page the page to get * @param perPage the number of projects per page * @return a List of forked projects * @throws GitLabApiException if any exception occurs */ public List getForks(Integer projectId, int page, int perPage) throws GitLabApiException { Response response = get(Response.Status.OK, getPageQueryParams(page, perPage),"projects", projectId, "forks"); return (response.readEntity(new GenericType>() { })); } /** * Get a Pager of projects that were forked from the specified project. * * GET /projects/:id/forks * * @param projectId the ID of the project * @param itemsPerPage the number of Project instances that will be fetched per page * @return a Pager of projects * @throws GitLabApiException if any exception occurs */ public Pager getForks(Integer projectId, int itemsPerPage) throws GitLabApiException { return new Pager(this, Project.class, itemsPerPage, null, "projects", projectId, "forks"); } /** * Star a project. * * POST /projects/:id/star * * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path * @return a Project instance with the new project info * @throws GitLabApiException if any exception occurs */ public Project starProject(Object projectIdOrPath) throws GitLabApiException { Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.CREATED); Response response = post(expectedStatus, (Form) null, "projects", getProjectIdOrPath(projectIdOrPath), "star"); return (response.readEntity(Project.class)); } /** * Unstar a project. * * POST /projects/:id/unstar * * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path * @return a Project instance with the new project info * @throws GitLabApiException if any exception occurs */ public Project unstarProject(Object projectIdOrPath) throws GitLabApiException { Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.CREATED); Response response = post(expectedStatus, (Form) null, "projects", getProjectIdOrPath(projectIdOrPath), "unstar"); return (response.readEntity(Project.class)); } /** * Get languages used in a project with percentage value. * * Get /projects/:id/languages * * @param projectId the ID of the project * @return a Map instance with the language as the key and the percentage as the value * @throws GitLabApiException if any exception occurs * @since GitLab 10.8 */ public Map getProjectLanguages(Integer projectId) throws GitLabApiException { if (projectId == null) { throw new RuntimeException("projectId cannot be null"); } Response response = get(Response.Status.OK, null, "projects", projectId, "languages"); return (response.readEntity(new GenericType>() {})); } }