mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	* Feature - #5960 - API Endpoint for Repo Editing * Revert from merge * Adds integration testing * Updates to integration tests * Revert changes * Update year in file header * Misspell fix * XORM = test * XORM = test * revert XORM = file * Makes RepoUnit.ID be pk and autoincr * Fix to units * revert header * Remove print statement * Adds other responses * Improves swagger for creating repo * Fixes import order * Better Unit Type does not exist error * Adds editable repo properties to the response repo structure * Fix to api_repo_edit_test.go * Fixes repo test * Changes per review * Fixes typo and standardizes comments in the EditRepoOption struct for swagger * Fixes typo and standardizes comments in the EditRepoOption struct for swagger * Actually can unarchive through the API * Unlike delete, user doesn't have to be the owner of the org, just admin to the repo * Fix to swagger comments for field name change * Update to swagger docs * Update swagger * Changes allow_pull_requests to has_pull_requests
This commit is contained in:
		
				
					committed by
					
						
						techknowlogick
					
				
			
			
				
	
			
			
			
						parent
						
							cdd10f145b
						
					
				
				
					commit
					1831b3b571
				
			
							
								
								
									
										225
									
								
								integrations/api_repo_edit_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								integrations/api_repo_edit_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,225 @@
 | 
				
			|||||||
 | 
					// Copyright 2019 The Gitea Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package integrations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
 | 
						api "code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getRepoEditOptionFromRepo gets the options for an existing repo exactly as is
 | 
				
			||||||
 | 
					func getRepoEditOptionFromRepo(repo *models.Repository) *api.EditRepoOption {
 | 
				
			||||||
 | 
						name := repo.Name
 | 
				
			||||||
 | 
						description := repo.Description
 | 
				
			||||||
 | 
						website := repo.Website
 | 
				
			||||||
 | 
						private := repo.IsPrivate
 | 
				
			||||||
 | 
						hasIssues := false
 | 
				
			||||||
 | 
						if _, err := repo.GetUnit(models.UnitTypeIssues); err == nil {
 | 
				
			||||||
 | 
							hasIssues = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hasWiki := false
 | 
				
			||||||
 | 
						if _, err := repo.GetUnit(models.UnitTypeWiki); err == nil {
 | 
				
			||||||
 | 
							hasWiki = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defaultBranch := repo.DefaultBranch
 | 
				
			||||||
 | 
						hasPullRequests := false
 | 
				
			||||||
 | 
						ignoreWhitespaceConflicts := false
 | 
				
			||||||
 | 
						allowMerge := false
 | 
				
			||||||
 | 
						allowRebase := false
 | 
				
			||||||
 | 
						allowRebaseMerge := false
 | 
				
			||||||
 | 
						allowSquash := false
 | 
				
			||||||
 | 
						if unit, err := repo.GetUnit(models.UnitTypePullRequests); err == nil {
 | 
				
			||||||
 | 
							config := unit.PullRequestsConfig()
 | 
				
			||||||
 | 
							hasPullRequests = true
 | 
				
			||||||
 | 
							ignoreWhitespaceConflicts = config.IgnoreWhitespaceConflicts
 | 
				
			||||||
 | 
							allowMerge = config.AllowMerge
 | 
				
			||||||
 | 
							allowRebase = config.AllowRebase
 | 
				
			||||||
 | 
							allowRebaseMerge = config.AllowRebaseMerge
 | 
				
			||||||
 | 
							allowSquash = config.AllowSquash
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						archived := repo.IsArchived
 | 
				
			||||||
 | 
						return &api.EditRepoOption{
 | 
				
			||||||
 | 
							Name:                      &name,
 | 
				
			||||||
 | 
							Description:               &description,
 | 
				
			||||||
 | 
							Website:                   &website,
 | 
				
			||||||
 | 
							Private:                   &private,
 | 
				
			||||||
 | 
							HasIssues:                 &hasIssues,
 | 
				
			||||||
 | 
							HasWiki:                   &hasWiki,
 | 
				
			||||||
 | 
							DefaultBranch:             &defaultBranch,
 | 
				
			||||||
 | 
							HasPullRequests:           &hasPullRequests,
 | 
				
			||||||
 | 
							IgnoreWhitespaceConflicts: &ignoreWhitespaceConflicts,
 | 
				
			||||||
 | 
							AllowMerge:                &allowMerge,
 | 
				
			||||||
 | 
							AllowRebase:               &allowRebase,
 | 
				
			||||||
 | 
							AllowRebaseMerge:          &allowRebaseMerge,
 | 
				
			||||||
 | 
							AllowSquash:               &allowSquash,
 | 
				
			||||||
 | 
							Archived:                  &archived,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getNewRepoEditOption Gets the options to change everything about an existing repo by adding to strings or changing
 | 
				
			||||||
 | 
					// the boolean
 | 
				
			||||||
 | 
					func getNewRepoEditOption(opts *api.EditRepoOption) *api.EditRepoOption {
 | 
				
			||||||
 | 
						// Gives a new property to everything
 | 
				
			||||||
 | 
						name := *opts.Name + "renamed"
 | 
				
			||||||
 | 
						description := "new description"
 | 
				
			||||||
 | 
						website := "http://wwww.newwebsite.com"
 | 
				
			||||||
 | 
						private := !*opts.Private
 | 
				
			||||||
 | 
						hasIssues := !*opts.HasIssues
 | 
				
			||||||
 | 
						hasWiki := !*opts.HasWiki
 | 
				
			||||||
 | 
						defaultBranch := "master"
 | 
				
			||||||
 | 
						hasPullRequests := !*opts.HasPullRequests
 | 
				
			||||||
 | 
						ignoreWhitespaceConflicts := !*opts.IgnoreWhitespaceConflicts
 | 
				
			||||||
 | 
						allowMerge := !*opts.AllowMerge
 | 
				
			||||||
 | 
						allowRebase := !*opts.AllowRebase
 | 
				
			||||||
 | 
						allowRebaseMerge := !*opts.AllowRebaseMerge
 | 
				
			||||||
 | 
						allowSquash := !*opts.AllowSquash
 | 
				
			||||||
 | 
						archived := !*opts.Archived
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &api.EditRepoOption{
 | 
				
			||||||
 | 
							Name:                      &name,
 | 
				
			||||||
 | 
							Description:               &description,
 | 
				
			||||||
 | 
							Website:                   &website,
 | 
				
			||||||
 | 
							Private:                   &private,
 | 
				
			||||||
 | 
							DefaultBranch:             &defaultBranch,
 | 
				
			||||||
 | 
							HasIssues:                 &hasIssues,
 | 
				
			||||||
 | 
							HasWiki:                   &hasWiki,
 | 
				
			||||||
 | 
							HasPullRequests:           &hasPullRequests,
 | 
				
			||||||
 | 
							IgnoreWhitespaceConflicts: &ignoreWhitespaceConflicts,
 | 
				
			||||||
 | 
							AllowMerge:                &allowMerge,
 | 
				
			||||||
 | 
							AllowRebase:               &allowRebase,
 | 
				
			||||||
 | 
							AllowRebaseMerge:          &allowRebaseMerge,
 | 
				
			||||||
 | 
							AllowSquash:               &allowSquash,
 | 
				
			||||||
 | 
							Archived:                  &archived,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestAPIRepoEdit(t *testing.T) {
 | 
				
			||||||
 | 
						onGiteaRun(t, func(t *testing.T, u *url.URL) {
 | 
				
			||||||
 | 
							user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)               // owner of the repo1 & repo16
 | 
				
			||||||
 | 
							user3 := models.AssertExistsAndLoadBean(t, &models.User{ID: 3}).(*models.User)               // owner of the repo3, is an org
 | 
				
			||||||
 | 
							user4 := models.AssertExistsAndLoadBean(t, &models.User{ID: 4}).(*models.User)               // owner of neither repos
 | 
				
			||||||
 | 
							repo1 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)   // public repo
 | 
				
			||||||
 | 
							repo3 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 3}).(*models.Repository)   // public repo
 | 
				
			||||||
 | 
							repo16 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 16}).(*models.Repository) // private repo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Get user2's token
 | 
				
			||||||
 | 
							session := loginUser(t, user2.Name)
 | 
				
			||||||
 | 
							token2 := getTokenForLoggedInUser(t, session)
 | 
				
			||||||
 | 
							session = emptyTestSession(t)
 | 
				
			||||||
 | 
							// Get user4's token
 | 
				
			||||||
 | 
							session = loginUser(t, user4.Name)
 | 
				
			||||||
 | 
							token4 := getTokenForLoggedInUser(t, session)
 | 
				
			||||||
 | 
							session = emptyTestSession(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Test editing a repo1 which user2 owns, changing name and many properties
 | 
				
			||||||
 | 
							origRepoEditOption := getRepoEditOptionFromRepo(repo1)
 | 
				
			||||||
 | 
							repoEditOption := getNewRepoEditOption(origRepoEditOption)
 | 
				
			||||||
 | 
							url := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo1.Name, token2)
 | 
				
			||||||
 | 
							req := NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
 | 
				
			||||||
 | 
							resp := session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
 | 
							var repo api.Repository
 | 
				
			||||||
 | 
							DecodeJSON(t, resp, &repo)
 | 
				
			||||||
 | 
							assert.NotNil(t, repo)
 | 
				
			||||||
 | 
							// check response
 | 
				
			||||||
 | 
							assert.Equal(t, *repoEditOption.Name, repo.Name)
 | 
				
			||||||
 | 
							assert.Equal(t, *repoEditOption.Description, repo.Description)
 | 
				
			||||||
 | 
							assert.Equal(t, *repoEditOption.Website, repo.Website)
 | 
				
			||||||
 | 
							assert.Equal(t, *repoEditOption.Archived, repo.Archived)
 | 
				
			||||||
 | 
							// check repo1 from database
 | 
				
			||||||
 | 
							repo1edited := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
 | 
				
			||||||
 | 
							repo1editedOption := getRepoEditOptionFromRepo(repo1edited)
 | 
				
			||||||
 | 
							assert.Equal(t, *repoEditOption.Name, *repo1editedOption.Name)
 | 
				
			||||||
 | 
							assert.Equal(t, *repoEditOption.Description, *repo1editedOption.Description)
 | 
				
			||||||
 | 
							assert.Equal(t, *repoEditOption.Website, *repo1editedOption.Website)
 | 
				
			||||||
 | 
							assert.Equal(t, *repoEditOption.Archived, *repo1editedOption.Archived)
 | 
				
			||||||
 | 
							assert.Equal(t, *repoEditOption.Private, *repo1editedOption.Private)
 | 
				
			||||||
 | 
							assert.Equal(t, *repoEditOption.HasWiki, *repo1editedOption.HasWiki)
 | 
				
			||||||
 | 
							// reset repo in db
 | 
				
			||||||
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, *repoEditOption.Name, token2)
 | 
				
			||||||
 | 
							req = NewRequestWithJSON(t, "PATCH", url, &origRepoEditOption)
 | 
				
			||||||
 | 
							resp = session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Test editing a non-existing repo
 | 
				
			||||||
 | 
							name := "repodoesnotexist"
 | 
				
			||||||
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, name, token2)
 | 
				
			||||||
 | 
							req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{Name: &name})
 | 
				
			||||||
 | 
							resp = session.MakeRequest(t, req, http.StatusNotFound)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Test editing repo16 by user4 who does not have write access
 | 
				
			||||||
 | 
							origRepoEditOption = getRepoEditOptionFromRepo(repo16)
 | 
				
			||||||
 | 
							repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
				
			||||||
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo16.Name, token4)
 | 
				
			||||||
 | 
							req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
 | 
				
			||||||
 | 
							session.MakeRequest(t, req, http.StatusNotFound)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Tests a repo with no token given so will fail
 | 
				
			||||||
 | 
							origRepoEditOption = getRepoEditOptionFromRepo(repo16)
 | 
				
			||||||
 | 
							repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
				
			||||||
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name)
 | 
				
			||||||
 | 
							req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
 | 
				
			||||||
 | 
							resp = session.MakeRequest(t, req, http.StatusNotFound)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Test using access token for a private repo that the user of the token owns
 | 
				
			||||||
 | 
							origRepoEditOption = getRepoEditOptionFromRepo(repo16)
 | 
				
			||||||
 | 
							repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
				
			||||||
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo16.Name, token2)
 | 
				
			||||||
 | 
							req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
 | 
				
			||||||
 | 
							resp = session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
 | 
							// reset repo in db
 | 
				
			||||||
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, *repoEditOption.Name, token2)
 | 
				
			||||||
 | 
							req = NewRequestWithJSON(t, "PATCH", url, &origRepoEditOption)
 | 
				
			||||||
 | 
							resp = session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Test making a repo public that is private
 | 
				
			||||||
 | 
							repo16 = models.AssertExistsAndLoadBean(t, &models.Repository{ID: 16}).(*models.Repository)
 | 
				
			||||||
 | 
							assert.True(t, repo16.IsPrivate)
 | 
				
			||||||
 | 
							private := false
 | 
				
			||||||
 | 
							repoEditOption = &api.EditRepoOption{
 | 
				
			||||||
 | 
								Private: &private,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo16.Name, token2)
 | 
				
			||||||
 | 
							req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
 | 
				
			||||||
 | 
							resp = session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
 | 
							repo16 = models.AssertExistsAndLoadBean(t, &models.Repository{ID: 16}).(*models.Repository)
 | 
				
			||||||
 | 
							assert.False(t, repo16.IsPrivate)
 | 
				
			||||||
 | 
							// Make it private again
 | 
				
			||||||
 | 
							private = true
 | 
				
			||||||
 | 
							repoEditOption.Private = &private
 | 
				
			||||||
 | 
							req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
 | 
				
			||||||
 | 
							resp = session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Test using org repo "user3/repo3" where user2 is a collaborator
 | 
				
			||||||
 | 
							origRepoEditOption = getRepoEditOptionFromRepo(repo3)
 | 
				
			||||||
 | 
							repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
				
			||||||
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user3.Name, repo3.Name, token2)
 | 
				
			||||||
 | 
							req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
 | 
				
			||||||
 | 
							session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
 | 
							// reset repo in db
 | 
				
			||||||
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user3.Name, *repoEditOption.Name, token2)
 | 
				
			||||||
 | 
							req = NewRequestWithJSON(t, "PATCH", url, &origRepoEditOption)
 | 
				
			||||||
 | 
							resp = session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Test using org repo "user3/repo3" with no user token
 | 
				
			||||||
 | 
							origRepoEditOption = getRepoEditOptionFromRepo(repo3)
 | 
				
			||||||
 | 
							repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
				
			||||||
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s", user3.Name, repo3.Name)
 | 
				
			||||||
 | 
							req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
 | 
				
			||||||
 | 
							session.MakeRequest(t, req, http.StatusNotFound)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Test using repo "user2/repo1" where user4 is a NOT collaborator
 | 
				
			||||||
 | 
							origRepoEditOption = getRepoEditOptionFromRepo(repo1)
 | 
				
			||||||
 | 
							repoEditOption = getNewRepoEditOption(origRepoEditOption)
 | 
				
			||||||
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo1.Name, token4)
 | 
				
			||||||
 | 
							req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
 | 
				
			||||||
 | 
							session.MakeRequest(t, req, http.StatusForbidden)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -108,7 +108,7 @@ func TestAPIDeleteFile(t *testing.T) {
 | 
				
			|||||||
		DecodeJSON(t, resp, &apiError)
 | 
							DecodeJSON(t, resp, &apiError)
 | 
				
			||||||
		assert.Equal(t, expectedAPIError, apiError)
 | 
							assert.Equal(t, expectedAPIError, apiError)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Test creating a file in repo1 by user4 who does not have write access
 | 
							// Test creating a file in repo16 by user4 who does not have write access
 | 
				
			||||||
		fileID++
 | 
							fileID++
 | 
				
			||||||
		treePath = fmt.Sprintf("delete/file%d.txt", fileID)
 | 
							treePath = fmt.Sprintf("delete/file%d.txt", fileID)
 | 
				
			||||||
		createFile(user2, repo16, treePath)
 | 
							createFile(user2, repo16, treePath)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -162,8 +162,8 @@ func CreateOrganization(org, owner *User) (err error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// insert units for team
 | 
						// insert units for team
 | 
				
			||||||
	var units = make([]TeamUnit, 0, len(allRepUnitTypes))
 | 
						var units = make([]TeamUnit, 0, len(AllRepoUnitTypes))
 | 
				
			||||||
	for _, tp := range allRepUnitTypes {
 | 
						for _, tp := range AllRepoUnitTypes {
 | 
				
			||||||
		units = append(units, TeamUnit{
 | 
							units = append(units, TeamUnit{
 | 
				
			||||||
			OrgID:  org.ID,
 | 
								OrgID:  org.ID,
 | 
				
			||||||
			TeamID: t.ID,
 | 
								TeamID: t.ID,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										111
									
								
								models/repo.go
									
									
									
									
									
								
							
							
						
						
									
										111
									
								
								models/repo.go
									
									
									
									
									
								
							@@ -274,32 +274,64 @@ func (repo *Repository) innerAPIFormat(e Engine, mode AccessMode, isParent bool)
 | 
				
			|||||||
			parent = repo.BaseRepo.innerAPIFormat(e, mode, true)
 | 
								parent = repo.BaseRepo.innerAPIFormat(e, mode, true)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						hasIssues := false
 | 
				
			||||||
 | 
						if _, err := repo.getUnit(e, UnitTypeIssues); err == nil {
 | 
				
			||||||
 | 
							hasIssues = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hasWiki := false
 | 
				
			||||||
 | 
						if _, err := repo.getUnit(e, UnitTypeWiki); err == nil {
 | 
				
			||||||
 | 
							hasWiki = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						hasPullRequests := false
 | 
				
			||||||
 | 
						ignoreWhitespaceConflicts := false
 | 
				
			||||||
 | 
						allowMerge := false
 | 
				
			||||||
 | 
						allowRebase := false
 | 
				
			||||||
 | 
						allowRebaseMerge := false
 | 
				
			||||||
 | 
						allowSquash := false
 | 
				
			||||||
 | 
						if unit, err := repo.getUnit(e, UnitTypePullRequests); err == nil {
 | 
				
			||||||
 | 
							config := unit.PullRequestsConfig()
 | 
				
			||||||
 | 
							hasPullRequests = true
 | 
				
			||||||
 | 
							ignoreWhitespaceConflicts = config.IgnoreWhitespaceConflicts
 | 
				
			||||||
 | 
							allowMerge = config.AllowMerge
 | 
				
			||||||
 | 
							allowRebase = config.AllowRebase
 | 
				
			||||||
 | 
							allowRebaseMerge = config.AllowRebaseMerge
 | 
				
			||||||
 | 
							allowSquash = config.AllowSquash
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &api.Repository{
 | 
						return &api.Repository{
 | 
				
			||||||
		ID:            repo.ID,
 | 
							ID:                        repo.ID,
 | 
				
			||||||
		Owner:         repo.Owner.APIFormat(),
 | 
							Owner:                     repo.Owner.APIFormat(),
 | 
				
			||||||
		Name:          repo.Name,
 | 
							Name:                      repo.Name,
 | 
				
			||||||
		FullName:      repo.FullName(),
 | 
							FullName:                  repo.FullName(),
 | 
				
			||||||
		Description:   repo.Description,
 | 
							Description:               repo.Description,
 | 
				
			||||||
		Private:       repo.IsPrivate,
 | 
							Private:                   repo.IsPrivate,
 | 
				
			||||||
		Empty:         repo.IsEmpty,
 | 
							Empty:                     repo.IsEmpty,
 | 
				
			||||||
		Archived:      repo.IsArchived,
 | 
							Archived:                  repo.IsArchived,
 | 
				
			||||||
		Size:          int(repo.Size / 1024),
 | 
							Size:                      int(repo.Size / 1024),
 | 
				
			||||||
		Fork:          repo.IsFork,
 | 
							Fork:                      repo.IsFork,
 | 
				
			||||||
		Parent:        parent,
 | 
							Parent:                    parent,
 | 
				
			||||||
		Mirror:        repo.IsMirror,
 | 
							Mirror:                    repo.IsMirror,
 | 
				
			||||||
		HTMLURL:       repo.HTMLURL(),
 | 
							HTMLURL:                   repo.HTMLURL(),
 | 
				
			||||||
		SSHURL:        cloneLink.SSH,
 | 
							SSHURL:                    cloneLink.SSH,
 | 
				
			||||||
		CloneURL:      cloneLink.HTTPS,
 | 
							CloneURL:                  cloneLink.HTTPS,
 | 
				
			||||||
		Website:       repo.Website,
 | 
							Website:                   repo.Website,
 | 
				
			||||||
		Stars:         repo.NumStars,
 | 
							Stars:                     repo.NumStars,
 | 
				
			||||||
		Forks:         repo.NumForks,
 | 
							Forks:                     repo.NumForks,
 | 
				
			||||||
		Watchers:      repo.NumWatches,
 | 
							Watchers:                  repo.NumWatches,
 | 
				
			||||||
		OpenIssues:    repo.NumOpenIssues,
 | 
							OpenIssues:                repo.NumOpenIssues,
 | 
				
			||||||
		DefaultBranch: repo.DefaultBranch,
 | 
							DefaultBranch:             repo.DefaultBranch,
 | 
				
			||||||
		Created:       repo.CreatedUnix.AsTime(),
 | 
							Created:                   repo.CreatedUnix.AsTime(),
 | 
				
			||||||
		Updated:       repo.UpdatedUnix.AsTime(),
 | 
							Updated:                   repo.UpdatedUnix.AsTime(),
 | 
				
			||||||
		Permissions:   permission,
 | 
							Permissions:               permission,
 | 
				
			||||||
		AvatarURL:     repo.AvatarLink(),
 | 
							HasIssues:                 hasIssues,
 | 
				
			||||||
 | 
							HasWiki:                   hasWiki,
 | 
				
			||||||
 | 
							HasPullRequests:           hasPullRequests,
 | 
				
			||||||
 | 
							IgnoreWhitespaceConflicts: ignoreWhitespaceConflicts,
 | 
				
			||||||
 | 
							AllowMerge:                allowMerge,
 | 
				
			||||||
 | 
							AllowRebase:               allowRebase,
 | 
				
			||||||
 | 
							AllowRebaseMerge:          allowRebaseMerge,
 | 
				
			||||||
 | 
							AllowSquash:               allowSquash,
 | 
				
			||||||
 | 
							AvatarURL:                 repo.AvatarLink(),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -346,10 +378,20 @@ func (repo *Repository) UnitEnabled(tp UnitType) bool {
 | 
				
			|||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					// ErrUnitTypeNotExist represents a "UnitTypeNotExist" kind of error.
 | 
				
			||||||
	// ErrUnitNotExist organization does not exist
 | 
					type ErrUnitTypeNotExist struct {
 | 
				
			||||||
	ErrUnitNotExist = errors.New("Unit does not exist")
 | 
						UT UnitType
 | 
				
			||||||
)
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsErrUnitTypeNotExist checks if an error is a ErrUnitNotExist.
 | 
				
			||||||
 | 
					func IsErrUnitTypeNotExist(err error) bool {
 | 
				
			||||||
 | 
						_, ok := err.(ErrUnitTypeNotExist)
 | 
				
			||||||
 | 
						return ok
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err ErrUnitTypeNotExist) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("Unit type does not exist: %s", err.UT.String())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MustGetUnit always returns a RepoUnit object
 | 
					// MustGetUnit always returns a RepoUnit object
 | 
				
			||||||
func (repo *Repository) MustGetUnit(tp UnitType) *RepoUnit {
 | 
					func (repo *Repository) MustGetUnit(tp UnitType) *RepoUnit {
 | 
				
			||||||
@@ -373,6 +415,11 @@ func (repo *Repository) MustGetUnit(tp UnitType) *RepoUnit {
 | 
				
			|||||||
			Type:   tp,
 | 
								Type:   tp,
 | 
				
			||||||
			Config: new(PullRequestsConfig),
 | 
								Config: new(PullRequestsConfig),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						} else if tp == UnitTypeIssues {
 | 
				
			||||||
 | 
							return &RepoUnit{
 | 
				
			||||||
 | 
								Type:   tp,
 | 
				
			||||||
 | 
								Config: new(IssuesConfig),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return &RepoUnit{
 | 
						return &RepoUnit{
 | 
				
			||||||
		Type:   tp,
 | 
							Type:   tp,
 | 
				
			||||||
@@ -394,7 +441,7 @@ func (repo *Repository) getUnit(e Engine, tp UnitType) (*RepoUnit, error) {
 | 
				
			|||||||
			return unit, nil
 | 
								return unit, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil, ErrUnitNotExist
 | 
						return nil, ErrUnitTypeNotExist{tp}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (repo *Repository) getOwner(e Engine) (err error) {
 | 
					func (repo *Repository) getOwner(e Engine) (err error) {
 | 
				
			||||||
@@ -1232,8 +1279,8 @@ func createRepository(e *xorm.Session, doer, u *User, repo *Repository) (err err
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// insert units for repo
 | 
						// insert units for repo
 | 
				
			||||||
	var units = make([]RepoUnit, 0, len(defaultRepoUnits))
 | 
						var units = make([]RepoUnit, 0, len(DefaultRepoUnits))
 | 
				
			||||||
	for _, tp := range defaultRepoUnits {
 | 
						for _, tp := range DefaultRepoUnits {
 | 
				
			||||||
		if tp == UnitTypeIssues {
 | 
							if tp == UnitTypeIssues {
 | 
				
			||||||
			units = append(units, RepoUnit{
 | 
								units = append(units, RepoUnit{
 | 
				
			||||||
				RepoID: repo.ID,
 | 
									RepoID: repo.ID,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,8 +58,8 @@ func (u UnitType) ColorFormat(s fmt.State) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	// allRepUnitTypes contains all the unit types
 | 
						// AllRepoUnitTypes contains all the unit types
 | 
				
			||||||
	allRepUnitTypes = []UnitType{
 | 
						AllRepoUnitTypes = []UnitType{
 | 
				
			||||||
		UnitTypeCode,
 | 
							UnitTypeCode,
 | 
				
			||||||
		UnitTypeIssues,
 | 
							UnitTypeIssues,
 | 
				
			||||||
		UnitTypePullRequests,
 | 
							UnitTypePullRequests,
 | 
				
			||||||
@@ -69,8 +69,8 @@ var (
 | 
				
			|||||||
		UnitTypeExternalTracker,
 | 
							UnitTypeExternalTracker,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// defaultRepoUnits contains the default unit types
 | 
						// DefaultRepoUnits contains the default unit types
 | 
				
			||||||
	defaultRepoUnits = []UnitType{
 | 
						DefaultRepoUnits = []UnitType{
 | 
				
			||||||
		UnitTypeCode,
 | 
							UnitTypeCode,
 | 
				
			||||||
		UnitTypeIssues,
 | 
							UnitTypeIssues,
 | 
				
			||||||
		UnitTypePullRequests,
 | 
							UnitTypePullRequests,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,9 +41,17 @@ type Repository struct {
 | 
				
			|||||||
	// swagger:strfmt date-time
 | 
						// swagger:strfmt date-time
 | 
				
			||||||
	Created time.Time `json:"created_at"`
 | 
						Created time.Time `json:"created_at"`
 | 
				
			||||||
	// swagger:strfmt date-time
 | 
						// swagger:strfmt date-time
 | 
				
			||||||
	Updated     time.Time   `json:"updated_at"`
 | 
						Updated                   time.Time   `json:"updated_at"`
 | 
				
			||||||
	Permissions *Permission `json:"permissions,omitempty"`
 | 
						Permissions               *Permission `json:"permissions,omitempty"`
 | 
				
			||||||
	AvatarURL   string      `json:"avatar_url"`
 | 
						HasIssues                 bool        `json:"has_issues"`
 | 
				
			||||||
 | 
						HasWiki                   bool        `json:"has_wiki"`
 | 
				
			||||||
 | 
						HasPullRequests           bool        `json:"has_pull_requests"`
 | 
				
			||||||
 | 
						IgnoreWhitespaceConflicts bool        `json:"ignore_whitespace_conflicts"`
 | 
				
			||||||
 | 
						AllowMerge                bool        `json:"allow_merge_commits"`
 | 
				
			||||||
 | 
						AllowRebase               bool        `json:"allow_rebase"`
 | 
				
			||||||
 | 
						AllowRebaseMerge          bool        `json:"allow_rebase_explicit"`
 | 
				
			||||||
 | 
						AllowSquash               bool        `json:"allow_squash_merge"`
 | 
				
			||||||
 | 
						AvatarURL                 string      `json:"avatar_url"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateRepoOption options when creating repository
 | 
					// CreateRepoOption options when creating repository
 | 
				
			||||||
@@ -71,38 +79,36 @@ type CreateRepoOption struct {
 | 
				
			|||||||
// EditRepoOption options when editing a repository's properties
 | 
					// EditRepoOption options when editing a repository's properties
 | 
				
			||||||
// swagger:model
 | 
					// swagger:model
 | 
				
			||||||
type EditRepoOption struct {
 | 
					type EditRepoOption struct {
 | 
				
			||||||
	// Name of the repository
 | 
						// name of the repository
 | 
				
			||||||
	//
 | 
					 | 
				
			||||||
	// required: true
 | 
					 | 
				
			||||||
	// unique: true
 | 
						// unique: true
 | 
				
			||||||
	Name *string `json:"name" binding:"Required;AlphaDashDot;MaxSize(100)"`
 | 
						Name *string `json:"name,omitempty" binding:"OmitEmpty;AlphaDashDot;MaxSize(100);"`
 | 
				
			||||||
	// A short description of the repository.
 | 
						// a short description of the repository.
 | 
				
			||||||
	Description *string `json:"description,omitempty" binding:"MaxSize(255)"`
 | 
						Description *string `json:"description,omitempty" binding:"MaxSize(255)"`
 | 
				
			||||||
	// A URL with more information about the repository.
 | 
						// a URL with more information about the repository.
 | 
				
			||||||
	Website *string `json:"website,omitempty" binding:"MaxSize(255)"`
 | 
						Website *string `json:"website,omitempty" binding:"MaxSize(255)"`
 | 
				
			||||||
	// Either `true` to make the repository private or `false` to make it public.
 | 
						// either `true` to make the repository private or `false` to make it public.
 | 
				
			||||||
	// Note: You will get a 422 error if the organization restricts changing repository visibility to organization
 | 
						// Note: you will get a 422 error if the organization restricts changing repository visibility to organization
 | 
				
			||||||
	// owners and a non-owner tries to change the value of private.
 | 
						// owners and a non-owner tries to change the value of private.
 | 
				
			||||||
	Private *bool `json:"private,omitempty"`
 | 
						Private *bool `json:"private,omitempty"`
 | 
				
			||||||
	// Either `true` to enable issues for this repository or `false` to disable them.
 | 
						// either `true` to enable issues for this repository or `false` to disable them.
 | 
				
			||||||
	EnableIssues *bool `json:"enable_issues,omitempty"`
 | 
						HasIssues *bool `json:"has_issues,omitempty"`
 | 
				
			||||||
	// Either `true` to enable the wiki for this repository or `false` to disable it.
 | 
						// either `true` to enable the wiki for this repository or `false` to disable it.
 | 
				
			||||||
	EnableWiki *bool `json:"enable_wiki,omitempty"`
 | 
						HasWiki *bool `json:"has_wiki,omitempty"`
 | 
				
			||||||
	// Updates the default branch for this repository.
 | 
						// sets the default branch for this repository.
 | 
				
			||||||
	DefaultBranch *string `json:"default_branch,omitempty"`
 | 
						DefaultBranch *string `json:"default_branch,omitempty"`
 | 
				
			||||||
	// Either `true` to allow pull requests, or `false` to prevent pull request.
 | 
						// either `true` to allow pull requests, or `false` to prevent pull request.
 | 
				
			||||||
	EnablePullRequests *bool `json:"enable_pull_requests,omitempty"`
 | 
						HasPullRequests *bool `json:"has_pull_requests,omitempty"`
 | 
				
			||||||
	// Either `true` to ignore whitepace for conflicts, or `false` to not ignore whitespace. `enabled_pull_requests` must be `true`.
 | 
						// either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. `has_pull_requests` must be `true`.
 | 
				
			||||||
	IgnoreWhitespaceConflicts *bool `json:"ignore_whitespace,omitempty"`
 | 
						IgnoreWhitespaceConflicts *bool `json:"ignore_whitespace_conflicts,omitempty"`
 | 
				
			||||||
	// Either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. `enabled_pull_requests` must be `true`.
 | 
						// either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. `has_pull_requests` must be `true`.
 | 
				
			||||||
	AllowMerge *bool `json:"allow_merge_commits,omitempty"`
 | 
						AllowMerge *bool `json:"allow_merge_commits,omitempty"`
 | 
				
			||||||
	// Either `true` to allow rebase-merging pull requests, or `false` to prevent rebase-merging. `enabled_pull_requests` must be `true`.
 | 
						// either `true` to allow rebase-merging pull requests, or `false` to prevent rebase-merging. `has_pull_requests` must be `true`.
 | 
				
			||||||
	AllowRebase *bool `json:"allow_rebase,omitempty"`
 | 
						AllowRebase *bool `json:"allow_rebase,omitempty"`
 | 
				
			||||||
	// Either `true` to allow rebase with explicit merge commits (--no-ff), or `false` to prevent rebase with explicit merge commits. `enabled_pull_requests` must be `true`.
 | 
						// either `true` to allow rebase with explicit merge commits (--no-ff), or `false` to prevent rebase with explicit merge commits. `has_pull_requests` must be `true`.
 | 
				
			||||||
	AllowRebaseMerge *bool `json:"allow_rebase_explicit,omitempty"`
 | 
						AllowRebaseMerge *bool `json:"allow_rebase_explicit,omitempty"`
 | 
				
			||||||
	// Either `true` to allow squash-merging pull requests, or `false` to prevent squash-merging. `enabled_pull_requests` must be `true`.
 | 
						// either `true` to allow squash-merging pull requests, or `false` to prevent squash-merging. `has_pull_requests` must be `true`.
 | 
				
			||||||
	AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"`
 | 
						AllowSquash *bool `json:"allow_squash_merge,omitempty"`
 | 
				
			||||||
	// `true` to archive this repository. Note: You cannot unarchive repositories through the API.
 | 
						// set to `true` to archive this repository.
 | 
				
			||||||
	Archived *bool `json:"archived,omitempty"`
 | 
						Archived *bool `json:"archived,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -608,7 +608,8 @@ func RegisterRoutes(m *macaron.Macaron) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			m.Group("/:username/:reponame", func() {
 | 
								m.Group("/:username/:reponame", func() {
 | 
				
			||||||
				m.Combo("").Get(reqAnyRepoReader(), repo.Get).
 | 
									m.Combo("").Get(reqAnyRepoReader(), repo.Get).
 | 
				
			||||||
					Delete(reqToken(), reqOwner(), repo.Delete)
 | 
										Delete(reqToken(), reqOwner(), repo.Delete).
 | 
				
			||||||
 | 
										Patch(reqToken(), reqAdmin(), bind(api.EditRepoOption{}), repo.Edit)
 | 
				
			||||||
				m.Group("/hooks", func() {
 | 
									m.Group("/hooks", func() {
 | 
				
			||||||
					m.Combo("").Get(repo.ListHooks).
 | 
										m.Combo("").Get(repo.ListHooks).
 | 
				
			||||||
						Post(bind(api.CreateHookOption{}), repo.CreateHook)
 | 
											Post(bind(api.CreateHookOption{}), repo.CreateHook)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -240,6 +240,10 @@ func Create(ctx *context.APIContext, opt api.CreateRepoOption) {
 | 
				
			|||||||
	// responses:
 | 
						// responses:
 | 
				
			||||||
	//   "201":
 | 
						//   "201":
 | 
				
			||||||
	//     "$ref": "#/responses/Repository"
 | 
						//     "$ref": "#/responses/Repository"
 | 
				
			||||||
 | 
						//   "409":
 | 
				
			||||||
 | 
						//     description: The repository with the same name already exists.
 | 
				
			||||||
 | 
						//   "422":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/validationError"
 | 
				
			||||||
	if ctx.User.IsOrganization() {
 | 
						if ctx.User.IsOrganization() {
 | 
				
			||||||
		// Shouldn't reach this condition, but just in case.
 | 
							// Shouldn't reach this condition, but just in case.
 | 
				
			||||||
		ctx.Error(422, "", "not allowed creating repository for organization")
 | 
							ctx.Error(422, "", "not allowed creating repository for organization")
 | 
				
			||||||
@@ -500,6 +504,280 @@ func GetByID(ctx *context.APIContext) {
 | 
				
			|||||||
	ctx.JSON(200, repo.APIFormat(perm.AccessMode))
 | 
						ctx.JSON(200, repo.APIFormat(perm.AccessMode))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Edit edit repository properties
 | 
				
			||||||
 | 
					func Edit(ctx *context.APIContext, opts api.EditRepoOption) {
 | 
				
			||||||
 | 
						// swagger:operation PATCH /repos/{owner}/{repo} repository repoEdit
 | 
				
			||||||
 | 
						// ---
 | 
				
			||||||
 | 
						// summary: Edit a repository's properties. Only fields that are set will be changed.
 | 
				
			||||||
 | 
						// produces:
 | 
				
			||||||
 | 
						// - application/json
 | 
				
			||||||
 | 
						// parameters:
 | 
				
			||||||
 | 
						// - name: owner
 | 
				
			||||||
 | 
						//   in: path
 | 
				
			||||||
 | 
						//   description: owner of the repo to edit
 | 
				
			||||||
 | 
						//   type: string
 | 
				
			||||||
 | 
						//   required: true
 | 
				
			||||||
 | 
						// - name: repo
 | 
				
			||||||
 | 
						//   in: path
 | 
				
			||||||
 | 
						//   description: name of the repo to edit
 | 
				
			||||||
 | 
						//   type: string
 | 
				
			||||||
 | 
						//   required: true
 | 
				
			||||||
 | 
						//   required: true
 | 
				
			||||||
 | 
						// - name: body
 | 
				
			||||||
 | 
						//   in: body
 | 
				
			||||||
 | 
						//   description: "Properties of a repo that you can edit"
 | 
				
			||||||
 | 
						//   schema:
 | 
				
			||||||
 | 
						//     "$ref": "#/definitions/EditRepoOption"
 | 
				
			||||||
 | 
						// responses:
 | 
				
			||||||
 | 
						//   "200":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/Repository"
 | 
				
			||||||
 | 
						//   "403":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/forbidden"
 | 
				
			||||||
 | 
						//   "422":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/validationError"
 | 
				
			||||||
 | 
						if err := updateBasicProperties(ctx, opts); err != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := updateRepoUnits(ctx, opts); err != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if opts.Archived != nil {
 | 
				
			||||||
 | 
							if err := updateRepoArchivedState(ctx, opts); err != nil {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.JSON(http.StatusOK, ctx.Repo.Repository.APIFormat(ctx.Repo.AccessMode))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// updateBasicProperties updates the basic properties of a repo: Name, Description, Website and Visibility
 | 
				
			||||||
 | 
					func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) error {
 | 
				
			||||||
 | 
						owner := ctx.Repo.Owner
 | 
				
			||||||
 | 
						repo := ctx.Repo.Repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						oldRepoName := repo.Name
 | 
				
			||||||
 | 
						newRepoName := repo.Name
 | 
				
			||||||
 | 
						if opts.Name != nil {
 | 
				
			||||||
 | 
							newRepoName = *opts.Name
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Check if repository name has been changed and not just a case change
 | 
				
			||||||
 | 
						if repo.LowerName != strings.ToLower(newRepoName) {
 | 
				
			||||||
 | 
							if err := models.ChangeRepositoryName(ctx.Repo.Owner, repo.Name, newRepoName); err != nil {
 | 
				
			||||||
 | 
								switch {
 | 
				
			||||||
 | 
								case models.IsErrRepoAlreadyExist(err):
 | 
				
			||||||
 | 
									ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is already taken [name: %s]", newRepoName), err)
 | 
				
			||||||
 | 
								case models.IsErrNameReserved(err):
 | 
				
			||||||
 | 
									ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is reserved [name: %s]", newRepoName), err)
 | 
				
			||||||
 | 
								case models.IsErrNamePatternNotAllowed(err):
 | 
				
			||||||
 | 
									ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name's pattern is not allowed [name: %s, pattern: %s]", newRepoName, err.(models.ErrNamePatternNotAllowed).Pattern), err)
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									ctx.Error(http.StatusUnprocessableEntity, "ChangeRepositoryName", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err := models.NewRepoRedirect(ctx.Repo.Owner.ID, repo.ID, repo.Name, newRepoName)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								ctx.Error(http.StatusUnprocessableEntity, "NewRepoRedirect", err)
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := models.RenameRepoAction(ctx.User, oldRepoName, repo); err != nil {
 | 
				
			||||||
 | 
								log.Error("RenameRepoAction: %v", err)
 | 
				
			||||||
 | 
								ctx.Error(http.StatusInternalServerError, "RenameRepoActions", err)
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							log.Trace("Repository name changed: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newRepoName)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Update the name in the repo object for the response
 | 
				
			||||||
 | 
						repo.Name = newRepoName
 | 
				
			||||||
 | 
						repo.LowerName = strings.ToLower(newRepoName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if opts.Description != nil {
 | 
				
			||||||
 | 
							repo.Description = *opts.Description
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if opts.Website != nil {
 | 
				
			||||||
 | 
							repo.Website = *opts.Website
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						visibilityChanged := false
 | 
				
			||||||
 | 
						if opts.Private != nil {
 | 
				
			||||||
 | 
							// Visibility of forked repository is forced sync with base repository.
 | 
				
			||||||
 | 
							if repo.IsFork {
 | 
				
			||||||
 | 
								*opts.Private = repo.BaseRepo.IsPrivate
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							visibilityChanged = repo.IsPrivate != *opts.Private
 | 
				
			||||||
 | 
							// when ForcePrivate enabled, you could change public repo to private, but only admin users can change private to public
 | 
				
			||||||
 | 
							if visibilityChanged && setting.Repository.ForcePrivate && !*opts.Private && !ctx.User.IsAdmin {
 | 
				
			||||||
 | 
								err := fmt.Errorf("cannot change private repository to public")
 | 
				
			||||||
 | 
								ctx.Error(http.StatusUnprocessableEntity, "Force Private enabled", err)
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							repo.IsPrivate = *opts.Private
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := models.UpdateRepository(repo, visibilityChanged); err != nil {
 | 
				
			||||||
 | 
							ctx.Error(http.StatusInternalServerError, "UpdateRepository", err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log.Trace("Repository basic settings updated: %s/%s", owner.Name, repo.Name)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func unitTypeInTypes(unitType models.UnitType, unitTypes []models.UnitType) bool {
 | 
				
			||||||
 | 
						for _, tp := range unitTypes {
 | 
				
			||||||
 | 
							if unitType == tp {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// updateRepoUnits updates repo units: Issue settings, Wiki settings, PR settings
 | 
				
			||||||
 | 
					func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
 | 
				
			||||||
 | 
						owner := ctx.Repo.Owner
 | 
				
			||||||
 | 
						repo := ctx.Repo.Repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var units []models.RepoUnit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tp := range models.MustRepoUnits {
 | 
				
			||||||
 | 
							units = append(units, models.RepoUnit{
 | 
				
			||||||
 | 
								RepoID: repo.ID,
 | 
				
			||||||
 | 
								Type:   tp,
 | 
				
			||||||
 | 
								Config: new(models.UnitConfig),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if opts.HasIssues != nil {
 | 
				
			||||||
 | 
							if *opts.HasIssues {
 | 
				
			||||||
 | 
								// We don't currently allow setting individual issue settings through the API,
 | 
				
			||||||
 | 
								// only can enable/disable issues, so when enabling issues,
 | 
				
			||||||
 | 
								// we either get the existing config which means it was already enabled,
 | 
				
			||||||
 | 
								// or create a new config since it doesn't exist.
 | 
				
			||||||
 | 
								unit, err := repo.GetUnit(models.UnitTypeIssues)
 | 
				
			||||||
 | 
								var config *models.IssuesConfig
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									// Unit type doesn't exist so we make a new config file with default values
 | 
				
			||||||
 | 
									config = &models.IssuesConfig{
 | 
				
			||||||
 | 
										EnableTimetracker:                true,
 | 
				
			||||||
 | 
										AllowOnlyContributorsToTrackTime: true,
 | 
				
			||||||
 | 
										EnableDependencies:               true,
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									config = unit.IssuesConfig()
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								units = append(units, models.RepoUnit{
 | 
				
			||||||
 | 
									RepoID: repo.ID,
 | 
				
			||||||
 | 
									Type:   models.UnitTypeIssues,
 | 
				
			||||||
 | 
									Config: config,
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if opts.HasWiki != nil {
 | 
				
			||||||
 | 
							if *opts.HasWiki {
 | 
				
			||||||
 | 
								// We don't currently allow setting individual wiki settings through the API,
 | 
				
			||||||
 | 
								// only can enable/disable the wiki, so when enabling the wiki,
 | 
				
			||||||
 | 
								// we either get the existing config which means it was already enabled,
 | 
				
			||||||
 | 
								// or create a new config since it doesn't exist.
 | 
				
			||||||
 | 
								config := &models.UnitConfig{}
 | 
				
			||||||
 | 
								units = append(units, models.RepoUnit{
 | 
				
			||||||
 | 
									RepoID: repo.ID,
 | 
				
			||||||
 | 
									Type:   models.UnitTypeWiki,
 | 
				
			||||||
 | 
									Config: config,
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if opts.HasPullRequests != nil {
 | 
				
			||||||
 | 
							if *opts.HasPullRequests {
 | 
				
			||||||
 | 
								// We do allow setting individual PR settings through the API, so
 | 
				
			||||||
 | 
								// we get the config settings and then set them
 | 
				
			||||||
 | 
								// if those settings were provided in the opts.
 | 
				
			||||||
 | 
								unit, err := repo.GetUnit(models.UnitTypePullRequests)
 | 
				
			||||||
 | 
								var config *models.PullRequestsConfig
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									// Unit type doesn't exist so we make a new config file with default values
 | 
				
			||||||
 | 
									config = &models.PullRequestsConfig{
 | 
				
			||||||
 | 
										IgnoreWhitespaceConflicts: false,
 | 
				
			||||||
 | 
										AllowMerge:                true,
 | 
				
			||||||
 | 
										AllowRebase:               true,
 | 
				
			||||||
 | 
										AllowRebaseMerge:          true,
 | 
				
			||||||
 | 
										AllowSquash:               true,
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									config = unit.PullRequestsConfig()
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if opts.IgnoreWhitespaceConflicts != nil {
 | 
				
			||||||
 | 
									config.IgnoreWhitespaceConflicts = *opts.IgnoreWhitespaceConflicts
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if opts.AllowMerge != nil {
 | 
				
			||||||
 | 
									config.AllowMerge = *opts.AllowMerge
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if opts.AllowRebase != nil {
 | 
				
			||||||
 | 
									config.AllowRebase = *opts.AllowRebase
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if opts.AllowRebaseMerge != nil {
 | 
				
			||||||
 | 
									config.AllowRebaseMerge = *opts.AllowRebaseMerge
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if opts.AllowSquash != nil {
 | 
				
			||||||
 | 
									config.AllowSquash = *opts.AllowSquash
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								units = append(units, models.RepoUnit{
 | 
				
			||||||
 | 
									RepoID: repo.ID,
 | 
				
			||||||
 | 
									Type:   models.UnitTypePullRequests,
 | 
				
			||||||
 | 
									Config: config,
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := models.UpdateRepositoryUnits(repo, units); err != nil {
 | 
				
			||||||
 | 
							ctx.Error(http.StatusInternalServerError, "UpdateRepositoryUnits", err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log.Trace("Repository advanced settings updated: %s/%s", owner.Name, repo.Name)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// updateRepoArchivedState updates repo's archive state
 | 
				
			||||||
 | 
					func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) error {
 | 
				
			||||||
 | 
						repo := ctx.Repo.Repository
 | 
				
			||||||
 | 
						// archive / un-archive
 | 
				
			||||||
 | 
						if opts.Archived != nil {
 | 
				
			||||||
 | 
							if repo.IsMirror {
 | 
				
			||||||
 | 
								err := fmt.Errorf("repo is a mirror, cannot archive/un-archive")
 | 
				
			||||||
 | 
								ctx.Error(http.StatusUnprocessableEntity, err.Error(), err)
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if *opts.Archived {
 | 
				
			||||||
 | 
								if err := repo.SetArchiveRepoState(*opts.Archived); err != nil {
 | 
				
			||||||
 | 
									log.Error("Tried to archive a repo: %s", err)
 | 
				
			||||||
 | 
									ctx.Error(http.StatusInternalServerError, "ArchiveRepoState", err)
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								log.Trace("Repository was archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if err := repo.SetArchiveRepoState(*opts.Archived); err != nil {
 | 
				
			||||||
 | 
									log.Error("Tried to un-archive a repo: %s", err)
 | 
				
			||||||
 | 
									ctx.Error(http.StatusInternalServerError, "ArchiveRepoState", err)
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								log.Trace("Repository was un-archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Delete one repository
 | 
					// Delete one repository
 | 
				
			||||||
func Delete(ctx *context.APIContext) {
 | 
					func Delete(ctx *context.APIContext) {
 | 
				
			||||||
	// swagger:operation DELETE /repos/{owner}/{repo} repository repoDelete
 | 
						// swagger:operation DELETE /repos/{owner}/{repo} repository repoDelete
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										82
									
								
								routers/api/v1/repo/repo_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								routers/api/v1/repo/repo_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					// Copyright 2019 The Gitea Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package repo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/context"
 | 
				
			||||||
 | 
						api "code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/test"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestRepoEdit(t *testing.T) {
 | 
				
			||||||
 | 
						models.PrepareTestEnv(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx := test.MockContext(t, "user2/repo1")
 | 
				
			||||||
 | 
						test.LoadRepo(t, ctx, 1)
 | 
				
			||||||
 | 
						test.LoadUser(t, ctx, 2)
 | 
				
			||||||
 | 
						ctx.Repo.Owner = ctx.User
 | 
				
			||||||
 | 
						description := "new description"
 | 
				
			||||||
 | 
						website := "http://wwww.newwebsite.com"
 | 
				
			||||||
 | 
						private := true
 | 
				
			||||||
 | 
						hasIssues := false
 | 
				
			||||||
 | 
						hasWiki := false
 | 
				
			||||||
 | 
						defaultBranch := "master"
 | 
				
			||||||
 | 
						hasPullRequests := true
 | 
				
			||||||
 | 
						ignoreWhitespaceConflicts := true
 | 
				
			||||||
 | 
						allowMerge := false
 | 
				
			||||||
 | 
						allowRebase := false
 | 
				
			||||||
 | 
						allowRebaseMerge := false
 | 
				
			||||||
 | 
						allowSquashMerge := false
 | 
				
			||||||
 | 
						archived := true
 | 
				
			||||||
 | 
						opts := api.EditRepoOption{
 | 
				
			||||||
 | 
							Name:                      &ctx.Repo.Repository.Name,
 | 
				
			||||||
 | 
							Description:               &description,
 | 
				
			||||||
 | 
							Website:                   &website,
 | 
				
			||||||
 | 
							Private:                   &private,
 | 
				
			||||||
 | 
							HasIssues:                 &hasIssues,
 | 
				
			||||||
 | 
							HasWiki:                   &hasWiki,
 | 
				
			||||||
 | 
							DefaultBranch:             &defaultBranch,
 | 
				
			||||||
 | 
							HasPullRequests:           &hasPullRequests,
 | 
				
			||||||
 | 
							IgnoreWhitespaceConflicts: &ignoreWhitespaceConflicts,
 | 
				
			||||||
 | 
							AllowMerge:                &allowMerge,
 | 
				
			||||||
 | 
							AllowRebase:               &allowRebase,
 | 
				
			||||||
 | 
							AllowRebaseMerge:          &allowRebaseMerge,
 | 
				
			||||||
 | 
							AllowSquash:               &allowSquashMerge,
 | 
				
			||||||
 | 
							Archived:                  &archived,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Edit(&context.APIContext{Context: ctx, Org: nil}, opts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
 | 
				
			||||||
 | 
						models.AssertExistsAndLoadBean(t, &models.Repository{
 | 
				
			||||||
 | 
							ID: 1,
 | 
				
			||||||
 | 
						}, models.Cond("name = ? AND is_archived = 1", *opts.Name))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestRepoEditNameChange(t *testing.T) {
 | 
				
			||||||
 | 
						models.PrepareTestEnv(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx := test.MockContext(t, "user2/repo1")
 | 
				
			||||||
 | 
						test.LoadRepo(t, ctx, 1)
 | 
				
			||||||
 | 
						test.LoadUser(t, ctx, 2)
 | 
				
			||||||
 | 
						ctx.Repo.Owner = ctx.User
 | 
				
			||||||
 | 
						name := "newname"
 | 
				
			||||||
 | 
						opts := api.EditRepoOption{
 | 
				
			||||||
 | 
							Name: &name,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Edit(&context.APIContext{Context: ctx, Org: nil}, opts)
 | 
				
			||||||
 | 
						assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						models.AssertExistsAndLoadBean(t, &models.Repository{
 | 
				
			||||||
 | 
							ID: 1,
 | 
				
			||||||
 | 
						}, models.Cond("name = ?", opts.Name))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -82,6 +82,8 @@ type swaggerParameterBodies struct {
 | 
				
			|||||||
	// in:body
 | 
						// in:body
 | 
				
			||||||
	CreateRepoOption api.CreateRepoOption
 | 
						CreateRepoOption api.CreateRepoOption
 | 
				
			||||||
	// in:body
 | 
						// in:body
 | 
				
			||||||
 | 
						EditRepoOption api.EditRepoOption
 | 
				
			||||||
 | 
						// in:body
 | 
				
			||||||
	CreateForkOption api.CreateForkOption
 | 
						CreateForkOption api.CreateForkOption
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// in:body
 | 
						// in:body
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1210,6 +1210,51 @@
 | 
				
			|||||||
            "$ref": "#/responses/forbidden"
 | 
					            "$ref": "#/responses/forbidden"
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "patch": {
 | 
				
			||||||
 | 
					        "produces": [
 | 
				
			||||||
 | 
					          "application/json"
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "tags": [
 | 
				
			||||||
 | 
					          "repository"
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "summary": "Edit a repository's properties. Only fields that are set will be changed.",
 | 
				
			||||||
 | 
					        "operationId": "repoEdit",
 | 
				
			||||||
 | 
					        "parameters": [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            "type": "string",
 | 
				
			||||||
 | 
					            "description": "owner of the repo to edit",
 | 
				
			||||||
 | 
					            "name": "owner",
 | 
				
			||||||
 | 
					            "in": "path",
 | 
				
			||||||
 | 
					            "required": true
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            "type": "string",
 | 
				
			||||||
 | 
					            "description": "name of the repo to edit",
 | 
				
			||||||
 | 
					            "name": "repo",
 | 
				
			||||||
 | 
					            "in": "path",
 | 
				
			||||||
 | 
					            "required": true
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            "description": "Properties of a repo that you can edit",
 | 
				
			||||||
 | 
					            "name": "body",
 | 
				
			||||||
 | 
					            "in": "body",
 | 
				
			||||||
 | 
					            "schema": {
 | 
				
			||||||
 | 
					              "$ref": "#/definitions/EditRepoOption"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "responses": {
 | 
				
			||||||
 | 
					          "200": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/Repository"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "403": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/forbidden"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "422": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/validationError"
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "/repos/{owner}/{repo}/archive/{archive}": {
 | 
					    "/repos/{owner}/{repo}/archive/{archive}": {
 | 
				
			||||||
@@ -6037,6 +6082,12 @@
 | 
				
			|||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "201": {
 | 
					          "201": {
 | 
				
			||||||
            "$ref": "#/responses/Repository"
 | 
					            "$ref": "#/responses/Repository"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "409": {
 | 
				
			||||||
 | 
					            "description": "The repository with the same name already exists."
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "422": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/validationError"
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -7738,6 +7789,84 @@
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
      "x-go-package": "code.gitea.io/gitea/modules/structs"
 | 
					      "x-go-package": "code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "EditRepoOption": {
 | 
				
			||||||
 | 
					      "description": "EditRepoOption options when editing a repository's properties",
 | 
				
			||||||
 | 
					      "type": "object",
 | 
				
			||||||
 | 
					      "properties": {
 | 
				
			||||||
 | 
					        "allow_merge_commits": {
 | 
				
			||||||
 | 
					          "description": "either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. `has_pull_requests` must be `true`.",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "AllowMerge"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "allow_rebase": {
 | 
				
			||||||
 | 
					          "description": "either `true` to allow rebase-merging pull requests, or `false` to prevent rebase-merging. `has_pull_requests` must be `true`.",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "AllowRebase"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "allow_rebase_explicit": {
 | 
				
			||||||
 | 
					          "description": "either `true` to allow rebase with explicit merge commits (--no-ff), or `false` to prevent rebase with explicit merge commits. `has_pull_requests` must be `true`.",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "AllowRebaseMerge"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "allow_squash_merge": {
 | 
				
			||||||
 | 
					          "description": "either `true` to allow squash-merging pull requests, or `false` to prevent squash-merging. `has_pull_requests` must be `true`.",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "AllowSquash"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "archived": {
 | 
				
			||||||
 | 
					          "description": "set to `true` to archive this repository.",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "Archived"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "default_branch": {
 | 
				
			||||||
 | 
					          "description": "sets the default branch for this repository.",
 | 
				
			||||||
 | 
					          "type": "string",
 | 
				
			||||||
 | 
					          "x-go-name": "DefaultBranch"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "description": {
 | 
				
			||||||
 | 
					          "description": "a short description of the repository.",
 | 
				
			||||||
 | 
					          "type": "string",
 | 
				
			||||||
 | 
					          "x-go-name": "Description"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "has_issues": {
 | 
				
			||||||
 | 
					          "description": "either `true` to enable issues for this repository or `false` to disable them.",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "HasIssues"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "has_pull_requests": {
 | 
				
			||||||
 | 
					          "description": "either `true` to allow pull requests, or `false` to prevent pull request.",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "HasPullRequests"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "has_wiki": {
 | 
				
			||||||
 | 
					          "description": "either `true` to enable the wiki for this repository or `false` to disable it.",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "HasWiki"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "ignore_whitespace_conflicts": {
 | 
				
			||||||
 | 
					          "description": "either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. `has_pull_requests` must be `true`.",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "IgnoreWhitespaceConflicts"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "name": {
 | 
				
			||||||
 | 
					          "description": "name of the repository",
 | 
				
			||||||
 | 
					          "type": "string",
 | 
				
			||||||
 | 
					          "uniqueItems": true,
 | 
				
			||||||
 | 
					          "x-go-name": "Name"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "private": {
 | 
				
			||||||
 | 
					          "description": "either `true` to make the repository private or `false` to make it public.\nNote: you will get a 422 error if the organization restricts changing repository visibility to organization\nowners and a non-owner tries to change the value of private.",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "Private"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "website": {
 | 
				
			||||||
 | 
					          "description": "a URL with more information about the repository.",
 | 
				
			||||||
 | 
					          "type": "string",
 | 
				
			||||||
 | 
					          "x-go-name": "Website"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "x-go-package": "code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "EditTeamOption": {
 | 
					    "EditTeamOption": {
 | 
				
			||||||
      "description": "EditTeamOption options for editing a team",
 | 
					      "description": "EditTeamOption options for editing a team",
 | 
				
			||||||
      "type": "object",
 | 
					      "type": "object",
 | 
				
			||||||
@@ -9062,6 +9191,22 @@
 | 
				
			|||||||
      "description": "Repository represents a repository",
 | 
					      "description": "Repository represents a repository",
 | 
				
			||||||
      "type": "object",
 | 
					      "type": "object",
 | 
				
			||||||
      "properties": {
 | 
					      "properties": {
 | 
				
			||||||
 | 
					        "allow_merge_commits": {
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "AllowMerge"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "allow_rebase": {
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "AllowRebase"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "allow_rebase_explicit": {
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "AllowRebaseMerge"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "allow_squash_merge": {
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "AllowSquash"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "archived": {
 | 
					        "archived": {
 | 
				
			||||||
          "type": "boolean",
 | 
					          "type": "boolean",
 | 
				
			||||||
          "x-go-name": "Archived"
 | 
					          "x-go-name": "Archived"
 | 
				
			||||||
@@ -9104,6 +9249,18 @@
 | 
				
			|||||||
          "type": "string",
 | 
					          "type": "string",
 | 
				
			||||||
          "x-go-name": "FullName"
 | 
					          "x-go-name": "FullName"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "has_issues": {
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "HasIssues"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "has_pull_requests": {
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "HasPullRequests"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "has_wiki": {
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "HasWiki"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "html_url": {
 | 
					        "html_url": {
 | 
				
			||||||
          "type": "string",
 | 
					          "type": "string",
 | 
				
			||||||
          "x-go-name": "HTMLURL"
 | 
					          "x-go-name": "HTMLURL"
 | 
				
			||||||
@@ -9113,6 +9270,10 @@
 | 
				
			|||||||
          "format": "int64",
 | 
					          "format": "int64",
 | 
				
			||||||
          "x-go-name": "ID"
 | 
					          "x-go-name": "ID"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "ignore_whitespace_conflicts": {
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "x-go-name": "IgnoreWhitespaceConflicts"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "mirror": {
 | 
					        "mirror": {
 | 
				
			||||||
          "type": "boolean",
 | 
					          "type": "boolean",
 | 
				
			||||||
          "x-go-name": "Mirror"
 | 
					          "x-go-name": "Mirror"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user