diff options
author | a1012112796 <1012112796@qq.com> | 2021-07-05 23:29:08 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-05 17:29:08 +0200 |
commit | 5bb97a12d79309e799e9826badf3527f03815dd2 (patch) | |
tree | 35e6a708ca49a01684ea97512055c0611552e7f4 /routers/api/v1/repo | |
parent | 64122fe105686502d4d5606425875a6b16fa6203 (diff) | |
download | gitea-5bb97a12d79309e799e9826badf3527f03815dd2.tar.gz gitea-5bb97a12d79309e799e9826badf3527f03815dd2.zip |
Creating a repo from a template repo via API (#15958)
* Creating a repo from a template repo via API
fix #15934
ref:
https://docs.github.com/en/rest/reference/repos#create-a-repository-using-a-template
Signed-off-by: a1012112796 <1012112796@qq.com>
Diffstat (limited to 'routers/api/v1/repo')
-rw-r--r-- | routers/api/v1/repo/repo.go | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 35d3490510..5d397191a6 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -307,6 +307,115 @@ func Create(ctx *context.APIContext) { CreateUserRepo(ctx, ctx.User, *opt) } +// Generate Create a repository using a template +func Generate(ctx *context.APIContext) { + // swagger:operation POST /repos/{template_owner}/{template_repo}/generate repository generateRepo + // --- + // summary: Create a repository using a template + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: template_owner + // in: path + // description: name of the template repository owner + // type: string + // required: true + // - name: template_repo + // in: path + // description: name of the template repository + // type: string + // required: true + // - name: body + // in: body + // schema: + // "$ref": "#/definitions/GenerateRepoOption" + // responses: + // "201": + // "$ref": "#/responses/Repository" + // "403": + // "$ref": "#/responses/forbidden" + // "404": + // "$ref": "#/responses/notFound" + // "409": + // description: The repository with the same name already exists. + // "422": + // "$ref": "#/responses/validationError" + form := web.GetForm(ctx).(*api.GenerateRepoOption) + + if !ctx.Repo.Repository.IsTemplate { + ctx.Error(http.StatusUnprocessableEntity, "", "this is not a template repo") + return + } + + if ctx.User.IsOrganization() { + ctx.Error(http.StatusUnprocessableEntity, "", "not allowed creating repository for organization") + return + } + + opts := models.GenerateRepoOptions{ + Name: form.Name, + Description: form.Description, + Private: form.Private, + GitContent: form.GitContent, + Topics: form.Topics, + GitHooks: form.GitHooks, + Webhooks: form.Webhooks, + Avatar: form.Avatar, + IssueLabels: form.Labels, + } + + if !opts.IsValid() { + ctx.Error(http.StatusUnprocessableEntity, "", "must select at least one template item") + return + } + + ctxUser := ctx.User + var err error + if form.Owner != ctxUser.Name { + ctxUser, err = models.GetOrgByName(form.Owner) + if err != nil { + if models.IsErrOrgNotExist(err) { + ctx.JSON(http.StatusNotFound, map[string]interface{}{ + "error": "request owner `" + form.Name + "` is not exist", + }) + return + } + + ctx.Error(http.StatusInternalServerError, "GetOrgByName", err) + return + } + + if !ctx.User.IsAdmin { + canCreate, err := ctxUser.CanCreateOrgRepo(ctx.User.ID) + if err != nil { + ctx.ServerError("CanCreateOrgRepo", err) + return + } else if !canCreate { + ctx.Error(http.StatusForbidden, "", "Given user is not allowed to create repository in organization.") + return + } + } + } + + repo, err := repo_service.GenerateRepository(ctx.User, ctxUser, ctx.Repo.Repository, opts) + if err != nil { + if models.IsErrRepoAlreadyExist(err) { + ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.") + } else if models.IsErrNameReserved(err) || + models.IsErrNamePatternNotAllowed(err) { + ctx.Error(http.StatusUnprocessableEntity, "", err) + } else { + ctx.Error(http.StatusInternalServerError, "CreateRepository", err) + } + return + } + log.Trace("Repository generated [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name) + + ctx.JSON(http.StatusCreated, convert.ToRepo(repo, models.AccessModeOwner)) +} + // CreateOrgRepoDeprecated create one repository of the organization func CreateOrgRepoDeprecated(ctx *context.APIContext) { // swagger:operation POST /org/{org}/repos organization createOrgRepoDeprecated |