* Move repofiles from modules to services * rename services/repository/repofiles -> services/repository/files * Fix test Co-authored-by: 6543 <6543@obermui.de>tags/v1.16.0-rc1
@@ -6,12 +6,12 @@ package integrations | |||
import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/repofiles" | |||
api "code.gitea.io/gitea/modules/structs" | |||
files_service "code.gitea.io/gitea/services/repository/files" | |||
) | |||
func createFileInBranch(user *models.User, repo *models.Repository, treePath, branchName, content string) (*api.FileResponse, error) { | |||
opts := &repofiles.UpdateRepoFileOptions{ | |||
opts := &files_service.UpdateRepoFileOptions{ | |||
OldBranch: branchName, | |||
TreePath: treePath, | |||
Content: content, | |||
@@ -19,7 +19,7 @@ func createFileInBranch(user *models.User, repo *models.Repository, treePath, br | |||
Author: nil, | |||
Committer: nil, | |||
} | |||
return repofiles.CreateOrUpdateRepoFile(repo, user, opts) | |||
return files_service.CreateOrUpdateRepoFile(repo, user, opts) | |||
} | |||
func createFile(user *models.User, repo *models.Repository, treePath string) (*api.FileResponse, error) { |
@@ -12,9 +12,9 @@ import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/models/unittest" | |||
"code.gitea.io/gitea/modules/repofiles" | |||
pull_service "code.gitea.io/gitea/services/pull" | |||
repo_service "code.gitea.io/gitea/services/repository" | |||
files_service "code.gitea.io/gitea/services/repository/files" | |||
"github.com/stretchr/testify/assert" | |||
) | |||
@@ -97,22 +97,22 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *models.User) *models.PullReq | |||
assert.NotEmpty(t, headRepo) | |||
//create a commit on base Repo | |||
_, err = repofiles.CreateOrUpdateRepoFile(baseRepo, actor, &repofiles.UpdateRepoFileOptions{ | |||
_, err = files_service.CreateOrUpdateRepoFile(baseRepo, actor, &files_service.UpdateRepoFileOptions{ | |||
TreePath: "File_A", | |||
Message: "Add File A", | |||
Content: "File A", | |||
IsNewFile: true, | |||
OldBranch: "master", | |||
NewBranch: "master", | |||
Author: &repofiles.IdentityOptions{ | |||
Author: &files_service.IdentityOptions{ | |||
Name: actor.Name, | |||
Email: actor.Email, | |||
}, | |||
Committer: &repofiles.IdentityOptions{ | |||
Committer: &files_service.IdentityOptions{ | |||
Name: actor.Name, | |||
Email: actor.Email, | |||
}, | |||
Dates: &repofiles.CommitDateOptions{ | |||
Dates: &files_service.CommitDateOptions{ | |||
Author: time.Now(), | |||
Committer: time.Now(), | |||
}, | |||
@@ -120,22 +120,22 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *models.User) *models.PullReq | |||
assert.NoError(t, err) | |||
//create a commit on head Repo | |||
_, err = repofiles.CreateOrUpdateRepoFile(headRepo, actor, &repofiles.UpdateRepoFileOptions{ | |||
_, err = files_service.CreateOrUpdateRepoFile(headRepo, actor, &files_service.UpdateRepoFileOptions{ | |||
TreePath: "File_B", | |||
Message: "Add File on PR branch", | |||
Content: "File B", | |||
IsNewFile: true, | |||
OldBranch: "master", | |||
NewBranch: "newBranch", | |||
Author: &repofiles.IdentityOptions{ | |||
Author: &files_service.IdentityOptions{ | |||
Name: actor.Name, | |||
Email: actor.Email, | |||
}, | |||
Committer: &repofiles.IdentityOptions{ | |||
Committer: &files_service.IdentityOptions{ | |||
Name: actor.Name, | |||
Email: actor.Email, | |||
}, | |||
Dates: &repofiles.CommitDateOptions{ | |||
Dates: &files_service.CommitDateOptions{ | |||
Author: time.Now(), | |||
Committer: time.Now(), | |||
}, |
@@ -10,22 +10,22 @@ import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/models/unittest" | |||
"code.gitea.io/gitea/modules/repofiles" | |||
api "code.gitea.io/gitea/modules/structs" | |||
"code.gitea.io/gitea/modules/test" | |||
files_service "code.gitea.io/gitea/services/repository/files" | |||
"github.com/stretchr/testify/assert" | |||
) | |||
func getDeleteRepoFileOptions(repo *models.Repository) *repofiles.DeleteRepoFileOptions { | |||
return &repofiles.DeleteRepoFileOptions{ | |||
func getDeleteRepoFileOptions(repo *models.Repository) *files_service.DeleteRepoFileOptions { | |||
return &files_service.DeleteRepoFileOptions{ | |||
LastCommitID: "", | |||
OldBranch: repo.DefaultBranch, | |||
NewBranch: repo.DefaultBranch, | |||
TreePath: "README.md", | |||
Message: "Deletes README.md", | |||
SHA: "4b4851ad51df6a7d9f25c979345979eaeb5b349f", | |||
Author: &repofiles.IdentityOptions{ | |||
Author: &files_service.IdentityOptions{ | |||
Name: "Bob Smith", | |||
Email: "bob@smith.com", | |||
}, | |||
@@ -80,7 +80,7 @@ func testDeleteRepoFile(t *testing.T, u *url.URL) { | |||
opts := getDeleteRepoFileOptions(repo) | |||
t.Run("Delete README.md file", func(t *testing.T) { | |||
fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts) | |||
assert.NoError(t, err) | |||
expectedFileResponse := getExpectedDeleteFileResponse(u) | |||
assert.NotNil(t, fileResponse) | |||
@@ -92,7 +92,7 @@ func testDeleteRepoFile(t *testing.T, u *url.URL) { | |||
}) | |||
t.Run("Verify README.md has been deleted", func(t *testing.T) { | |||
fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts) | |||
assert.Nil(t, fileResponse) | |||
expectedError := "repository file does not exist [path: " + opts.TreePath + "]" | |||
assert.EqualError(t, err, expectedError) | |||
@@ -122,7 +122,7 @@ func testDeleteRepoFileWithoutBranchNames(t *testing.T, u *url.URL) { | |||
opts.NewBranch = "" | |||
t.Run("Delete README.md without Branch Name", func(t *testing.T) { | |||
fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts) | |||
assert.NoError(t, err) | |||
expectedFileResponse := getExpectedDeleteFileResponse(u) | |||
assert.NotNil(t, fileResponse) | |||
@@ -151,7 +151,7 @@ func TestDeleteRepoFileErrors(t *testing.T) { | |||
t.Run("Bad branch", func(t *testing.T) { | |||
opts := getDeleteRepoFileOptions(repo) | |||
opts.OldBranch = "bad_branch" | |||
fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts) | |||
assert.Error(t, err) | |||
assert.Nil(t, fileResponse) | |||
expectedError := "branch does not exist [name: " + opts.OldBranch + "]" | |||
@@ -162,7 +162,7 @@ func TestDeleteRepoFileErrors(t *testing.T) { | |||
opts := getDeleteRepoFileOptions(repo) | |||
origSHA := opts.SHA | |||
opts.SHA = "bad_sha" | |||
fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts) | |||
assert.Nil(t, fileResponse) | |||
assert.Error(t, err) | |||
expectedError := "sha does not match [given: " + opts.SHA + ", expected: " + origSHA + "]" | |||
@@ -172,7 +172,7 @@ func TestDeleteRepoFileErrors(t *testing.T) { | |||
t.Run("New branch already exists", func(t *testing.T) { | |||
opts := getDeleteRepoFileOptions(repo) | |||
opts.NewBranch = "develop" | |||
fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts) | |||
assert.Nil(t, fileResponse) | |||
assert.Error(t, err) | |||
expectedError := "branch already exists [name: " + opts.NewBranch + "]" | |||
@@ -182,7 +182,7 @@ func TestDeleteRepoFileErrors(t *testing.T) { | |||
t.Run("TreePath is empty:", func(t *testing.T) { | |||
opts := getDeleteRepoFileOptions(repo) | |||
opts.TreePath = "" | |||
fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts) | |||
assert.Nil(t, fileResponse) | |||
assert.Error(t, err) | |||
expectedError := "path contains a malformed path component [path: ]" | |||
@@ -192,7 +192,7 @@ func TestDeleteRepoFileErrors(t *testing.T) { | |||
t.Run("TreePath is a git directory:", func(t *testing.T) { | |||
opts := getDeleteRepoFileOptions(repo) | |||
opts.TreePath = ".git" | |||
fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts) | |||
assert.Nil(t, fileResponse) | |||
assert.Error(t, err) | |||
expectedError := "path contains a malformed path component [path: " + opts.TreePath + "]" |
@@ -12,16 +12,16 @@ import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/repofiles" | |||
"code.gitea.io/gitea/modules/setting" | |||
api "code.gitea.io/gitea/modules/structs" | |||
"code.gitea.io/gitea/modules/test" | |||
files_service "code.gitea.io/gitea/services/repository/files" | |||
"github.com/stretchr/testify/assert" | |||
) | |||
func getCreateRepoFileOptions(repo *models.Repository) *repofiles.UpdateRepoFileOptions { | |||
return &repofiles.UpdateRepoFileOptions{ | |||
func getCreateRepoFileOptions(repo *models.Repository) *files_service.UpdateRepoFileOptions { | |||
return &files_service.UpdateRepoFileOptions{ | |||
OldBranch: repo.DefaultBranch, | |||
NewBranch: repo.DefaultBranch, | |||
TreePath: "new/file.txt", | |||
@@ -33,8 +33,8 @@ func getCreateRepoFileOptions(repo *models.Repository) *repofiles.UpdateRepoFile | |||
} | |||
} | |||
func getUpdateRepoFileOptions(repo *models.Repository) *repofiles.UpdateRepoFileOptions { | |||
return &repofiles.UpdateRepoFileOptions{ | |||
func getUpdateRepoFileOptions(repo *models.Repository) *files_service.UpdateRepoFileOptions { | |||
return &files_service.UpdateRepoFileOptions{ | |||
OldBranch: repo.DefaultBranch, | |||
NewBranch: repo.DefaultBranch, | |||
TreePath: "README.md", | |||
@@ -198,7 +198,7 @@ func TestCreateOrUpdateRepoFileForCreate(t *testing.T) { | |||
opts := getCreateRepoFileOptions(repo) | |||
// test | |||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts) | |||
// asserts | |||
assert.NoError(t, err) | |||
@@ -234,7 +234,7 @@ func TestCreateOrUpdateRepoFileForUpdate(t *testing.T) { | |||
opts := getUpdateRepoFileOptions(repo) | |||
// test | |||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts) | |||
// asserts | |||
assert.NoError(t, err) | |||
@@ -269,7 +269,7 @@ func TestCreateOrUpdateRepoFileForUpdateWithFileMove(t *testing.T) { | |||
opts.TreePath = "README_new.md" // new file name, README_new.md | |||
// test | |||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts) | |||
// asserts | |||
assert.NoError(t, err) | |||
@@ -319,7 +319,7 @@ func TestCreateOrUpdateRepoFileWithoutBranchNames(t *testing.T) { | |||
opts.NewBranch = "" | |||
// test | |||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts) | |||
// asserts | |||
assert.NoError(t, err) | |||
@@ -349,7 +349,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) { | |||
t.Run("bad branch", func(t *testing.T) { | |||
opts := getUpdateRepoFileOptions(repo) | |||
opts.OldBranch = "bad_branch" | |||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts) | |||
assert.Error(t, err) | |||
assert.Nil(t, fileResponse) | |||
expectedError := "branch does not exist [name: " + opts.OldBranch + "]" | |||
@@ -360,7 +360,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) { | |||
opts := getUpdateRepoFileOptions(repo) | |||
origSHA := opts.SHA | |||
opts.SHA = "bad_sha" | |||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts) | |||
assert.Nil(t, fileResponse) | |||
assert.Error(t, err) | |||
expectedError := "sha does not match [given: " + opts.SHA + ", expected: " + origSHA + "]" | |||
@@ -370,7 +370,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) { | |||
t.Run("new branch already exists", func(t *testing.T) { | |||
opts := getUpdateRepoFileOptions(repo) | |||
opts.NewBranch = "develop" | |||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts) | |||
assert.Nil(t, fileResponse) | |||
assert.Error(t, err) | |||
expectedError := "branch already exists [name: " + opts.NewBranch + "]" | |||
@@ -380,7 +380,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) { | |||
t.Run("treePath is empty:", func(t *testing.T) { | |||
opts := getUpdateRepoFileOptions(repo) | |||
opts.TreePath = "" | |||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts) | |||
assert.Nil(t, fileResponse) | |||
assert.Error(t, err) | |||
expectedError := "path contains a malformed path component [path: ]" | |||
@@ -390,7 +390,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) { | |||
t.Run("treePath is a git directory:", func(t *testing.T) { | |||
opts := getUpdateRepoFileOptions(repo) | |||
opts.TreePath = ".git" | |||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts) | |||
assert.Nil(t, fileResponse) | |||
assert.Error(t, err) | |||
expectedError := "path contains a malformed path component [path: " + opts.TreePath + "]" | |||
@@ -400,7 +400,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) { | |||
t.Run("create file that already exists", func(t *testing.T) { | |||
opts := getCreateRepoFileOptions(repo) | |||
opts.TreePath = "README.md" //already exists | |||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts) | |||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts) | |||
assert.Nil(t, fileResponse) | |||
assert.Error(t, err) | |||
expectedError := "repository file already exists [path: " + opts.TreePath + "]" |
@@ -10,7 +10,6 @@ import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/log" | |||
repo_module "code.gitea.io/gitea/modules/repository" | |||
api "code.gitea.io/gitea/modules/structs" | |||
) | |||
@@ -83,7 +82,14 @@ func ToAPIPullRequest(pr *models.PullRequest, doer *models.User) *api.PullReques | |||
}, | |||
} | |||
baseBranch, err = repo_module.GetBranch(pr.BaseRepo, pr.BaseBranch) | |||
gitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath()) | |||
if err != nil { | |||
log.Error("OpenRepository[%s]: %v", pr.BaseRepo.RepoPath(), err) | |||
return nil | |||
} | |||
defer gitRepo.Close() | |||
baseBranch, err = gitRepo.GetBranch(pr.BaseBranch) | |||
if err != nil && !git.IsErrBranchNotExist(err) { | |||
log.Error("GetBranch[%s]: %v", pr.BaseBranch, err) | |||
return nil |
@@ -1,41 +0,0 @@ | |||
// 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 repofiles | |||
import ( | |||
"net/url" | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/setting" | |||
api "code.gitea.io/gitea/modules/structs" | |||
) | |||
// GetBlobBySHA get the GitBlobResponse of a repository using a sha hash. | |||
func GetBlobBySHA(repo *models.Repository, sha string) (*api.GitBlobResponse, error) { | |||
gitRepo, err := git.OpenRepository(repo.RepoPath()) | |||
if err != nil { | |||
return nil, err | |||
} | |||
defer gitRepo.Close() | |||
gitBlob, err := gitRepo.GetBlob(sha) | |||
if err != nil { | |||
return nil, err | |||
} | |||
content := "" | |||
if gitBlob.Size() <= setting.API.DefaultMaxBlobSize { | |||
content, err = gitBlob.GetBlobContentBase64() | |||
if err != nil { | |||
return nil, err | |||
} | |||
} | |||
return &api.GitBlobResponse{ | |||
SHA: gitBlob.ID.String(), | |||
URL: repo.APIURL() + "/git/blobs/" + url.PathEscape(gitBlob.ID.String()), | |||
Size: gitBlob.Size(), | |||
Encoding: "base64", | |||
Content: content, | |||
}, nil | |||
} |
@@ -1,40 +0,0 @@ | |||
// 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 repofiles | |||
import ( | |||
"testing" | |||
"code.gitea.io/gitea/models/unittest" | |||
api "code.gitea.io/gitea/modules/structs" | |||
"code.gitea.io/gitea/modules/test" | |||
"github.com/stretchr/testify/assert" | |||
) | |||
func TestGetBlobBySHA(t *testing.T) { | |||
unittest.PrepareTestEnv(t) | |||
ctx := test.MockContext(t, "user2/repo1") | |||
test.LoadRepo(t, ctx, 1) | |||
test.LoadRepoCommit(t, ctx) | |||
test.LoadUser(t, ctx, 2) | |||
test.LoadGitRepo(t, ctx) | |||
defer ctx.Repo.GitRepo.Close() | |||
sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d" | |||
ctx.SetParams(":id", "1") | |||
ctx.SetParams(":sha", sha) | |||
gbr, err := GetBlobBySHA(ctx.Repo.Repository, ctx.Params(":sha")) | |||
expectedGBR := &api.GitBlobResponse{ | |||
Content: "dHJlZSAyYTJmMWQ0NjcwNzI4YTJlMTAwNDllMzQ1YmQ3YTI3NjQ2OGJlYWI2CmF1dGhvciB1c2VyMSA8YWRkcmVzczFAZXhhbXBsZS5jb20+IDE0ODk5NTY0NzkgLTA0MDAKY29tbWl0dGVyIEV0aGFuIEtvZW5pZyA8ZXRoYW50a29lbmlnQGdtYWlsLmNvbT4gMTQ4OTk1NjQ3OSAtMDQwMAoKSW5pdGlhbCBjb21taXQK", | |||
Encoding: "base64", | |||
URL: "https://try.gitea.io/api/v1/repos/user2/repo1/git/blobs/65f1bf27bc3bf70f64657658635e66094edbcb4d", | |||
SHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d", | |||
Size: 180, | |||
} | |||
assert.NoError(t, err) | |||
assert.Equal(t, expectedGBR, gbr) | |||
} |
@@ -1,19 +0,0 @@ | |||
// 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 repofiles | |||
import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/git" | |||
) | |||
// CountDivergingCommits determines how many commits a branch is ahead or behind the repository's base branch | |||
func CountDivergingCommits(repo *models.Repository, branch string) (*git.DivergeObject, error) { | |||
divergence, err := git.GetDivergingCommits(repo.RepoPath(), repo.DefaultBranch, branch) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return &divergence, nil | |||
} |
@@ -1,41 +0,0 @@ | |||
// 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 repofiles | |||
import ( | |||
"fmt" | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/git" | |||
) | |||
// CreateCommitStatus creates a new CommitStatus given a bunch of parameters | |||
// NOTE: All text-values will be trimmed from whitespaces. | |||
// Requires: Repo, Creator, SHA | |||
func CreateCommitStatus(repo *models.Repository, creator *models.User, sha string, status *models.CommitStatus) error { | |||
repoPath := repo.RepoPath() | |||
// confirm that commit is exist | |||
gitRepo, err := git.OpenRepository(repoPath) | |||
if err != nil { | |||
return fmt.Errorf("OpenRepository[%s]: %v", repoPath, err) | |||
} | |||
if _, err := gitRepo.GetCommit(sha); err != nil { | |||
gitRepo.Close() | |||
return fmt.Errorf("GetCommit[%s]: %v", sha, err) | |||
} | |||
gitRepo.Close() | |||
if err := models.NewCommitStatus(models.NewCommitStatusOptions{ | |||
Repo: repo, | |||
Creator: creator, | |||
SHA: sha, | |||
CommitStatus: status, | |||
}); err != nil { | |||
return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %v", repo.ID, creator.ID, sha, err) | |||
} | |||
return nil | |||
} |
@@ -1,23 +0,0 @@ | |||
// 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 repofiles | |||
package repofiles | |||
import ( | |||
"path" | |||
"strings" | |||
) | |||
// CleanUploadFileName Trims a filename and returns empty string if it is a .git directory | |||
func CleanUploadFileName(name string) string { | |||
// Rebase the filename | |||
name = strings.Trim(path.Clean("/"+name), " /") | |||
// Git disallows any filenames to have a .git directory in them. | |||
for _, part := range strings.Split(name, "/") { | |||
if strings.ToLower(part) == ".git" { | |||
return "" | |||
} | |||
} | |||
return name | |||
} |
@@ -1,27 +0,0 @@ | |||
// 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 repofiles | |||
import ( | |||
"testing" | |||
"github.com/stretchr/testify/assert" | |||
) | |||
func TestCleanUploadFileName(t *testing.T) { | |||
t.Run("Clean regular file", func(t *testing.T) { | |||
name := "this/is/test" | |||
cleanName := CleanUploadFileName(name) | |||
expectedCleanName := name | |||
assert.EqualValues(t, expectedCleanName, cleanName) | |||
}) | |||
t.Run("Clean a .git path", func(t *testing.T) { | |||
name := "this/is/test/.git" | |||
cleanName := CleanUploadFileName(name) | |||
expectedCleanName := "" | |||
assert.EqualValues(t, expectedCleanName, cleanName) | |||
}) | |||
} |
@@ -1,33 +0,0 @@ | |||
// 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 repofiles | |||
import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/structs" | |||
) | |||
// GetPayloadCommitVerification returns the verification information of a commit | |||
func GetPayloadCommitVerification(commit *git.Commit) *structs.PayloadCommitVerification { | |||
verification := &structs.PayloadCommitVerification{} | |||
commitVerification := models.ParseCommitWithSignature(commit) | |||
if commit.Signature != nil { | |||
verification.Signature = commit.Signature.Signature | |||
verification.Payload = commit.Signature.Payload | |||
} | |||
if commitVerification.SigningUser != nil { | |||
verification.Signer = &structs.PayloadUser{ | |||
Name: commitVerification.SigningUser.Name, | |||
Email: commitVerification.SigningUser.Email, | |||
} | |||
} | |||
verification.Verified = commitVerification.Verified | |||
verification.Reason = commitVerification.Reason | |||
if verification.Reason == "" && !verification.Verified { | |||
verification.Reason = "gpg.error.not_signed_commit" | |||
} | |||
return verification | |||
} |
@@ -1,26 +0,0 @@ | |||
// Copyright 2020 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 repository | |||
import ( | |||
"fmt" | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/git" | |||
) | |||
// GetBranch returns a branch by its name | |||
func GetBranch(repo *models.Repository, branch string) (*git.Branch, error) { | |||
if len(branch) == 0 { | |||
return nil, fmt.Errorf("GetBranch: empty string for branch") | |||
} | |||
gitRepo, err := git.OpenRepository(repo.RepoPath()) | |||
if err != nil { | |||
return nil, err | |||
} | |||
defer gitRepo.Close() | |||
return gitRepo.GetBranch(branch) | |||
} |
@@ -8,7 +8,7 @@ import ( | |||
"net/http" | |||
"code.gitea.io/gitea/modules/context" | |||
"code.gitea.io/gitea/modules/repofiles" | |||
files_service "code.gitea.io/gitea/services/repository/files" | |||
) | |||
// GetBlob get the blob of a repository file. | |||
@@ -45,7 +45,7 @@ func GetBlob(ctx *context.APIContext) { | |||
ctx.Error(http.StatusBadRequest, "", "sha not provided") | |||
return | |||
} | |||
if blob, err := repofiles.GetBlobBySHA(ctx.Repo.Repository, sha); err != nil { | |||
if blob, err := files_service.GetBlobBySHA(ctx.Repo.Repository, sha); err != nil { | |||
ctx.Error(http.StatusBadRequest, "", err) | |||
} else { | |||
ctx.JSON(http.StatusOK, blob) |
@@ -14,7 +14,6 @@ import ( | |||
"code.gitea.io/gitea/modules/context" | |||
"code.gitea.io/gitea/modules/convert" | |||
"code.gitea.io/gitea/modules/git" | |||
repo_module "code.gitea.io/gitea/modules/repository" | |||
api "code.gitea.io/gitea/modules/structs" | |||
"code.gitea.io/gitea/modules/web" | |||
"code.gitea.io/gitea/routers/api/v1/utils" | |||
@@ -53,7 +52,7 @@ func GetBranch(ctx *context.APIContext) { | |||
branchName := ctx.Params("*") | |||
branch, err := repo_module.GetBranch(ctx.Repo.Repository, branchName) | |||
branch, err := repo_service.GetBranch(ctx.Repo.Repository, branchName) | |||
if err != nil { | |||
if git.IsErrBranchNotExist(err) { | |||
ctx.NotFound(err) | |||
@@ -198,7 +197,7 @@ func CreateBranch(ctx *context.APIContext) { | |||
return | |||
} | |||
branch, err := repo_module.GetBranch(ctx.Repo.Repository, opt.BranchName) | |||
branch, err := repo_service.GetBranch(ctx.Repo.Repository, opt.BranchName) | |||
if err != nil { | |||
ctx.Error(http.StatusInternalServerError, "GetBranch", err) | |||
return |
@@ -15,11 +15,11 @@ import ( | |||
"code.gitea.io/gitea/models/unit" | |||
"code.gitea.io/gitea/modules/context" | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/repofiles" | |||
api "code.gitea.io/gitea/modules/structs" | |||
"code.gitea.io/gitea/modules/web" | |||
"code.gitea.io/gitea/routers/common" | |||
"code.gitea.io/gitea/routers/web/repo" | |||
files_service "code.gitea.io/gitea/services/repository/files" | |||
) | |||
// GetRawFile get a file by path on a repository | |||
@@ -240,22 +240,22 @@ func CreateFile(ctx *context.APIContext) { | |||
apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch | |||
} | |||
opts := &repofiles.UpdateRepoFileOptions{ | |||
opts := &files_service.UpdateRepoFileOptions{ | |||
Content: apiOpts.Content, | |||
IsNewFile: true, | |||
Message: apiOpts.Message, | |||
TreePath: ctx.Params("*"), | |||
OldBranch: apiOpts.BranchName, | |||
NewBranch: apiOpts.NewBranchName, | |||
Committer: &repofiles.IdentityOptions{ | |||
Committer: &files_service.IdentityOptions{ | |||
Name: apiOpts.Committer.Name, | |||
Email: apiOpts.Committer.Email, | |||
}, | |||
Author: &repofiles.IdentityOptions{ | |||
Author: &files_service.IdentityOptions{ | |||
Name: apiOpts.Author.Name, | |||
Email: apiOpts.Author.Email, | |||
}, | |||
Dates: &repofiles.CommitDateOptions{ | |||
Dates: &files_service.CommitDateOptions{ | |||
Author: apiOpts.Dates.Author, | |||
Committer: apiOpts.Dates.Committer, | |||
}, | |||
@@ -327,7 +327,7 @@ func UpdateFile(ctx *context.APIContext) { | |||
apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch | |||
} | |||
opts := &repofiles.UpdateRepoFileOptions{ | |||
opts := &files_service.UpdateRepoFileOptions{ | |||
Content: apiOpts.Content, | |||
SHA: apiOpts.SHA, | |||
IsNewFile: false, | |||
@@ -336,15 +336,15 @@ func UpdateFile(ctx *context.APIContext) { | |||
TreePath: ctx.Params("*"), | |||
OldBranch: apiOpts.BranchName, | |||
NewBranch: apiOpts.NewBranchName, | |||
Committer: &repofiles.IdentityOptions{ | |||
Committer: &files_service.IdentityOptions{ | |||
Name: apiOpts.Committer.Name, | |||
Email: apiOpts.Committer.Email, | |||
}, | |||
Author: &repofiles.IdentityOptions{ | |||
Author: &files_service.IdentityOptions{ | |||
Name: apiOpts.Author.Name, | |||
Email: apiOpts.Author.Email, | |||
}, | |||
Dates: &repofiles.CommitDateOptions{ | |||
Dates: &files_service.CommitDateOptions{ | |||
Author: apiOpts.Dates.Author, | |||
Committer: apiOpts.Dates.Committer, | |||
}, | |||
@@ -387,7 +387,7 @@ func handleCreateOrUpdateFileError(ctx *context.APIContext, err error) { | |||
} | |||
// Called from both CreateFile or UpdateFile to handle both | |||
func createOrUpdateFile(ctx *context.APIContext, opts *repofiles.UpdateRepoFileOptions) (*api.FileResponse, error) { | |||
func createOrUpdateFile(ctx *context.APIContext, opts *files_service.UpdateRepoFileOptions) (*api.FileResponse, error) { | |||
if !canWriteFiles(ctx.Repo) { | |||
return nil, models.ErrUserDoesNotHaveAccessToRepo{ | |||
UserID: ctx.User.ID, | |||
@@ -401,7 +401,7 @@ func createOrUpdateFile(ctx *context.APIContext, opts *repofiles.UpdateRepoFileO | |||
} | |||
opts.Content = string(content) | |||
return repofiles.CreateOrUpdateRepoFile(ctx.Repo.Repository, ctx.User, opts) | |||
return files_service.CreateOrUpdateRepoFile(ctx.Repo.Repository, ctx.User, opts) | |||
} | |||
// DeleteFile Delete a fle in a repository | |||
@@ -457,21 +457,21 @@ func DeleteFile(ctx *context.APIContext) { | |||
apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch | |||
} | |||
opts := &repofiles.DeleteRepoFileOptions{ | |||
opts := &files_service.DeleteRepoFileOptions{ | |||
Message: apiOpts.Message, | |||
OldBranch: apiOpts.BranchName, | |||
NewBranch: apiOpts.NewBranchName, | |||
SHA: apiOpts.SHA, | |||
TreePath: ctx.Params("*"), | |||
Committer: &repofiles.IdentityOptions{ | |||
Committer: &files_service.IdentityOptions{ | |||
Name: apiOpts.Committer.Name, | |||
Email: apiOpts.Committer.Email, | |||
}, | |||
Author: &repofiles.IdentityOptions{ | |||
Author: &files_service.IdentityOptions{ | |||
Name: apiOpts.Author.Name, | |||
Email: apiOpts.Author.Email, | |||
}, | |||
Dates: &repofiles.CommitDateOptions{ | |||
Dates: &files_service.CommitDateOptions{ | |||
Author: apiOpts.Dates.Author, | |||
Committer: apiOpts.Dates.Committer, | |||
}, | |||
@@ -488,7 +488,7 @@ func DeleteFile(ctx *context.APIContext) { | |||
opts.Message = ctx.Tr("repo.editor.delete", opts.TreePath) | |||
} | |||
if fileResponse, err := repofiles.DeleteRepoFile(ctx.Repo.Repository, ctx.User, opts); err != nil { | |||
if fileResponse, err := files_service.DeleteRepoFile(ctx.Repo.Repository, ctx.User, opts); err != nil { | |||
if git.IsErrBranchNotExist(err) || models.IsErrRepoFileDoesNotExist(err) || git.IsErrNotExist(err) { | |||
ctx.Error(http.StatusNotFound, "DeleteFile", err) | |||
return | |||
@@ -554,7 +554,7 @@ func GetContents(ctx *context.APIContext) { | |||
treePath := ctx.Params("*") | |||
ref := ctx.FormTrim("ref") | |||
if fileList, err := repofiles.GetContentsOrList(ctx.Repo.Repository, treePath, ref); err != nil { | |||
if fileList, err := files_service.GetContentsOrList(ctx.Repo.Repository, treePath, ref); err != nil { | |||
if git.IsErrNotExist(err) { | |||
ctx.NotFound("GetContentsOrList", err) | |||
return |
@@ -11,10 +11,10 @@ import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/context" | |||
"code.gitea.io/gitea/modules/convert" | |||
"code.gitea.io/gitea/modules/repofiles" | |||
api "code.gitea.io/gitea/modules/structs" | |||
"code.gitea.io/gitea/modules/web" | |||
"code.gitea.io/gitea/routers/api/v1/utils" | |||
files_service "code.gitea.io/gitea/services/repository/files" | |||
) | |||
// NewCommitStatus creates a new CommitStatus | |||
@@ -62,7 +62,7 @@ func NewCommitStatus(ctx *context.APIContext) { | |||
Description: form.Description, | |||
Context: form.Context, | |||
} | |||
if err := repofiles.CreateCommitStatus(ctx.Repo.Repository, ctx.User, sha, status); err != nil { | |||
if err := files_service.CreateCommitStatus(ctx.Repo.Repository, ctx.User, sha, status); err != nil { | |||
ctx.Error(http.StatusInternalServerError, "CreateCommitStatus", err) | |||
return | |||
} |
@@ -8,7 +8,7 @@ import ( | |||
"net/http" | |||
"code.gitea.io/gitea/modules/context" | |||
"code.gitea.io/gitea/modules/repofiles" | |||
files_service "code.gitea.io/gitea/services/repository/files" | |||
) | |||
// GetTree get the tree of a repository. | |||
@@ -60,7 +60,7 @@ func GetTree(ctx *context.APIContext) { | |||
ctx.Error(http.StatusBadRequest, "", "sha not provided") | |||
return | |||
} | |||
if tree, err := repofiles.GetTreeBySHA(ctx.Repo.Repository, sha, ctx.FormInt("page"), ctx.FormInt("per_page"), ctx.FormBool("recursive")); err != nil { | |||
if tree, err := files_service.GetTreeBySHA(ctx.Repo.Repository, sha, ctx.FormInt("page"), ctx.FormInt("per_page"), ctx.FormBool("recursive")); err != nil { | |||
ctx.Error(http.StatusBadRequest, "", err.Error()) | |||
} else { | |||
ctx.JSON(http.StatusOK, tree) |
@@ -17,7 +17,6 @@ import ( | |||
"code.gitea.io/gitea/modules/context" | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/modules/repofiles" | |||
repo_module "code.gitea.io/gitea/modules/repository" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/util" | |||
@@ -26,6 +25,7 @@ import ( | |||
"code.gitea.io/gitea/services/forms" | |||
release_service "code.gitea.io/gitea/services/release" | |||
repo_service "code.gitea.io/gitea/services/repository" | |||
files_service "code.gitea.io/gitea/services/repository/files" | |||
) | |||
const ( | |||
@@ -165,7 +165,7 @@ func redirect(ctx *context.Context) { | |||
// loadBranches loads branches from the repository limited by page & pageSize. | |||
// NOTE: May write to context on error. | |||
func loadBranches(ctx *context.Context, skip, limit int) ([]*Branch, int) { | |||
defaultBranch, err := repo_module.GetBranch(ctx.Repo.Repository, ctx.Repo.Repository.DefaultBranch) | |||
defaultBranch, err := repo_service.GetBranch(ctx.Repo.Repository, ctx.Repo.Repository.DefaultBranch) | |||
if err != nil { | |||
log.Error("loadBranches: get default branch: %v", err) | |||
ctx.ServerError("GetDefaultBranch", err) | |||
@@ -242,7 +242,7 @@ func loadOneBranch(ctx *context.Context, rawBranch *git.Branch, protectedBranche | |||
} | |||
} | |||
divergence, divergenceError := repofiles.CountDivergingCommits(ctx.Repo.Repository, git.BranchPrefix+branchName) | |||
divergence, divergenceError := files_service.CountDivergingCommits(ctx.Repo.Repository, git.BranchPrefix+branchName) | |||
if divergenceError != nil { | |||
ctx.ServerError("CountDivergingCommits", divergenceError) | |||
return nil |
@@ -19,8 +19,6 @@ import ( | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/json" | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/modules/repofiles" | |||
repo_module "code.gitea.io/gitea/modules/repository" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/typesniffer" | |||
"code.gitea.io/gitea/modules/upload" | |||
@@ -28,6 +26,8 @@ import ( | |||
"code.gitea.io/gitea/modules/web" | |||
"code.gitea.io/gitea/routers/utils" | |||
"code.gitea.io/gitea/services/forms" | |||
repo_service "code.gitea.io/gitea/services/repository" | |||
files_service "code.gitea.io/gitea/services/repository/files" | |||
) | |||
const ( | |||
@@ -244,7 +244,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b | |||
message += "\n\n" + form.CommitMessage | |||
} | |||
if _, err := repofiles.CreateOrUpdateRepoFile(ctx.Repo.Repository, ctx.User, &repofiles.UpdateRepoFileOptions{ | |||
if _, err := files_service.CreateOrUpdateRepoFile(ctx.Repo.Repository, ctx.User, &files_service.UpdateRepoFileOptions{ | |||
LastCommitID: form.LastCommit, | |||
OldBranch: ctx.Repo.BranchName, | |||
NewBranch: branchName, | |||
@@ -255,7 +255,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b | |||
IsNewFile: isNewFile, | |||
Signoff: form.Signoff, | |||
}); err != nil { | |||
// This is where we handle all the errors thrown by repofiles.CreateOrUpdateRepoFile | |||
// This is where we handle all the errors thrown by files_service.CreateOrUpdateRepoFile | |||
if git.IsErrNotExist(err) { | |||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_editing_no_longer_exists", ctx.Repo.TreePath), tplEditFile, &form) | |||
} else if models.IsErrLFSFileLocked(err) { | |||
@@ -369,7 +369,7 @@ func DiffPreviewPost(ctx *context.Context) { | |||
return | |||
} | |||
diff, err := repofiles.GetDiffPreview(ctx.Repo.Repository, ctx.Repo.BranchName, treePath, form.Content) | |||
diff, err := files_service.GetDiffPreview(ctx.Repo.Repository, ctx.Repo.BranchName, treePath, form.Content) | |||
if err != nil { | |||
ctx.Error(http.StatusInternalServerError, "GetDiffPreview: "+err.Error()) | |||
return | |||
@@ -450,7 +450,7 @@ func DeleteFilePost(ctx *context.Context) { | |||
message += "\n\n" + form.CommitMessage | |||
} | |||
if _, err := repofiles.DeleteRepoFile(ctx.Repo.Repository, ctx.User, &repofiles.DeleteRepoFileOptions{ | |||
if _, err := files_service.DeleteRepoFile(ctx.Repo.Repository, ctx.User, &files_service.DeleteRepoFileOptions{ | |||
LastCommitID: form.LastCommit, | |||
OldBranch: ctx.Repo.BranchName, | |||
NewBranch: branchName, | |||
@@ -614,7 +614,7 @@ func UploadFilePost(ctx *context.Context) { | |||
} | |||
if oldBranchName != branchName { | |||
if _, err := repo_module.GetBranch(ctx.Repo.Repository, branchName); err == nil { | |||
if _, err := repo_service.GetBranch(ctx.Repo.Repository, branchName); err == nil { | |||
ctx.Data["Err_NewBranchName"] = true | |||
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchName), tplUploadFile, &form) | |||
return | |||
@@ -658,7 +658,7 @@ func UploadFilePost(ctx *context.Context) { | |||
message += "\n\n" + form.CommitMessage | |||
} | |||
if err := repofiles.UploadRepoFiles(ctx.Repo.Repository, ctx.User, &repofiles.UploadRepoFileOptions{ | |||
if err := files_service.UploadRepoFiles(ctx.Repo.Repository, ctx.User, &files_service.UploadRepoFileOptions{ | |||
LastCommitID: ctx.Repo.CommitID, | |||
OldBranch: oldBranchName, | |||
NewBranch: branchName, | |||
@@ -806,7 +806,7 @@ func GetUniquePatchBranchName(ctx *context.Context) string { | |||
prefix := ctx.User.LowerName + "-patch-" | |||
for i := 1; i <= 1000; i++ { | |||
branchName := fmt.Sprintf("%s%d", prefix, i) | |||
if _, err := repo_module.GetBranch(ctx.Repo.Repository, branchName); err != nil { | |||
if _, err := repo_service.GetBranch(ctx.Repo.Repository, branchName); err != nil { | |||
if git.IsErrBranchNotExist(err) { | |||
return branchName | |||
} |
@@ -10,11 +10,11 @@ import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/models/webhook" | |||
repository_service "code.gitea.io/gitea/modules/repository" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/services/auth" | |||
"code.gitea.io/gitea/services/migrations" | |||
mirror_service "code.gitea.io/gitea/services/mirror" | |||
repository_service "code.gitea.io/gitea/services/repository" | |||
) | |||
func registerUpdateMirrorTask() { |
@@ -9,7 +9,6 @@ import ( | |||
"time" | |||
"code.gitea.io/gitea/models" | |||
repo_module "code.gitea.io/gitea/modules/repository" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/updatechecker" | |||
repo_service "code.gitea.io/gitea/services/repository" | |||
@@ -56,7 +55,7 @@ func registerGarbageCollectRepositories() { | |||
Args: setting.Git.GCArgs, | |||
}, func(ctx context.Context, _ *models.User, config Config) error { | |||
rhcConfig := config.(*RepoHealthCheckConfig) | |||
return repo_module.GitGcRepos(ctx, rhcConfig.Timeout, rhcConfig.Args...) | |||
return repo_service.GitGcRepos(ctx, rhcConfig.Timeout, rhcConfig.Args...) | |||
}) | |||
} | |||
@@ -96,7 +95,7 @@ func registerReinitMissingRepositories() { | |||
RunAtStart: false, | |||
Schedule: "@every 72h", | |||
}, func(ctx context.Context, _ *models.User, _ Config) error { | |||
return repo_module.ReinitMissingRepositories(ctx) | |||
return repo_service.ReinitMissingRepositories(ctx) | |||
}) | |||
} | |||
@@ -106,7 +105,7 @@ func registerDeleteMissingRepositories() { | |||
RunAtStart: false, | |||
Schedule: "@every 72h", | |||
}, func(ctx context.Context, user *models.User, _ Config) error { | |||
return repo_module.DeleteMissingRepositories(ctx, user) | |||
return repo_service.DeleteMissingRepositories(ctx, user) | |||
}) | |||
} | |||
@@ -43,6 +43,20 @@ func CreateNewBranch(doer *models.User, repo *models.Repository, oldBranchName, | |||
return nil | |||
} | |||
// GetBranch returns a branch by its name | |||
func GetBranch(repo *models.Repository, branch string) (*git.Branch, error) { | |||
if len(branch) == 0 { | |||
return nil, fmt.Errorf("GetBranch: empty string for branch") | |||
} | |||
gitRepo, err := git.OpenRepository(repo.RepoPath()) | |||
if err != nil { | |||
return nil, err | |||
} | |||
defer gitRepo.Close() | |||
return gitRepo.GetBranch(branch) | |||
} | |||
// GetBranches returns branches from the repository, skipping skip initial branches and | |||
// returning at most limit branches, or all branches if limit is 0. | |||
func GetBranches(repo *models.Repository, skip, limit int) ([]*git.Branch, int, error) { |
@@ -0,0 +1,73 @@ | |||
// 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 files | |||
import ( | |||
"fmt" | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/structs" | |||
) | |||
// CreateCommitStatus creates a new CommitStatus given a bunch of parameters | |||
// NOTE: All text-values will be trimmed from whitespaces. | |||
// Requires: Repo, Creator, SHA | |||
func CreateCommitStatus(repo *models.Repository, creator *models.User, sha string, status *models.CommitStatus) error { | |||
repoPath := repo.RepoPath() | |||
// confirm that commit is exist | |||
gitRepo, err := git.OpenRepository(repoPath) | |||
if err != nil { | |||
return fmt.Errorf("OpenRepository[%s]: %v", repoPath, err) | |||
} | |||
if _, err := gitRepo.GetCommit(sha); err != nil { | |||
gitRepo.Close() | |||
return fmt.Errorf("GetCommit[%s]: %v", sha, err) | |||
} | |||
gitRepo.Close() | |||
if err := models.NewCommitStatus(models.NewCommitStatusOptions{ | |||
Repo: repo, | |||
Creator: creator, | |||
SHA: sha, | |||
CommitStatus: status, | |||
}); err != nil { | |||
return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %v", repo.ID, creator.ID, sha, err) | |||
} | |||
return nil | |||
} | |||
// CountDivergingCommits determines how many commits a branch is ahead or behind the repository's base branch | |||
func CountDivergingCommits(repo *models.Repository, branch string) (*git.DivergeObject, error) { | |||
divergence, err := git.GetDivergingCommits(repo.RepoPath(), repo.DefaultBranch, branch) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return &divergence, nil | |||
} | |||
// GetPayloadCommitVerification returns the verification information of a commit | |||
func GetPayloadCommitVerification(commit *git.Commit) *structs.PayloadCommitVerification { | |||
verification := &structs.PayloadCommitVerification{} | |||
commitVerification := models.ParseCommitWithSignature(commit) | |||
if commit.Signature != nil { | |||
verification.Signature = commit.Signature.Signature | |||
verification.Payload = commit.Signature.Payload | |||
} | |||
if commitVerification.SigningUser != nil { | |||
verification.Signer = &structs.PayloadUser{ | |||
Name: commitVerification.SigningUser.Name, | |||
Email: commitVerification.SigningUser.Email, | |||
} | |||
} | |||
verification.Verified = commitVerification.Verified | |||
verification.Reason = commitVerification.Reason | |||
if verification.Reason == "" && !verification.Verified { | |||
verification.Reason = "gpg.error.not_signed_commit" | |||
} | |||
return verification | |||
} |
@@ -2,7 +2,7 @@ | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repofiles | |||
package files | |||
import ( | |||
"fmt" | |||
@@ -12,6 +12,7 @@ import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/setting" | |||
api "code.gitea.io/gitea/modules/structs" | |||
) | |||
@@ -215,3 +216,30 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (* | |||
return contentsResponse, nil | |||
} | |||
// GetBlobBySHA get the GitBlobResponse of a repository using a sha hash. | |||
func GetBlobBySHA(repo *models.Repository, sha string) (*api.GitBlobResponse, error) { | |||
gitRepo, err := git.OpenRepository(repo.RepoPath()) | |||
if err != nil { | |||
return nil, err | |||
} | |||
defer gitRepo.Close() | |||
gitBlob, err := gitRepo.GetBlob(sha) | |||
if err != nil { | |||
return nil, err | |||
} | |||
content := "" | |||
if gitBlob.Size() <= setting.API.DefaultMaxBlobSize { | |||
content, err = gitBlob.GetBlobContentBase64() | |||
if err != nil { | |||
return nil, err | |||
} | |||
} | |||
return &api.GitBlobResponse{ | |||
SHA: gitBlob.ID.String(), | |||
URL: repo.APIURL() + "/git/blobs/" + url.PathEscape(gitBlob.ID.String()), | |||
Size: gitBlob.Size(), | |||
Encoding: "base64", | |||
Content: content, | |||
}, nil | |||
} |
@@ -2,7 +2,7 @@ | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repofiles | |||
package files | |||
import ( | |||
"path/filepath" | |||
@@ -16,7 +16,7 @@ import ( | |||
) | |||
func TestMain(m *testing.M) { | |||
unittest.MainTest(m, filepath.Join("..", "..")) | |||
unittest.MainTest(m, filepath.Join("..", "..", "..")) | |||
} | |||
func getExpectedReadmeContentsResponse() *api.ContentsResponse { | |||
@@ -218,3 +218,28 @@ func TestGetContentsOrListOfEmptyRepos(t *testing.T) { | |||
assert.Empty(t, contents) | |||
}) | |||
} | |||
func TestGetBlobBySHA(t *testing.T) { | |||
unittest.PrepareTestEnv(t) | |||
ctx := test.MockContext(t, "user2/repo1") | |||
test.LoadRepo(t, ctx, 1) | |||
test.LoadRepoCommit(t, ctx) | |||
test.LoadUser(t, ctx, 2) | |||
test.LoadGitRepo(t, ctx) | |||
defer ctx.Repo.GitRepo.Close() | |||
sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d" | |||
ctx.SetParams(":id", "1") | |||
ctx.SetParams(":sha", sha) | |||
gbr, err := GetBlobBySHA(ctx.Repo.Repository, ctx.Params(":sha")) | |||
expectedGBR := &api.GitBlobResponse{ | |||
Content: "dHJlZSAyYTJmMWQ0NjcwNzI4YTJlMTAwNDllMzQ1YmQ3YTI3NjQ2OGJlYWI2CmF1dGhvciB1c2VyMSA8YWRkcmVzczFAZXhhbXBsZS5jb20+IDE0ODk5NTY0NzkgLTA0MDAKY29tbWl0dGVyIEV0aGFuIEtvZW5pZyA8ZXRoYW50a29lbmlnQGdtYWlsLmNvbT4gMTQ4OTk1NjQ3OSAtMDQwMAoKSW5pdGlhbCBjb21taXQK", | |||
Encoding: "base64", | |||
URL: "https://try.gitea.io/api/v1/repos/user2/repo1/git/blobs/65f1bf27bc3bf70f64657658635e66094edbcb4d", | |||
SHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d", | |||
Size: 180, | |||
} | |||
assert.NoError(t, err) | |||
assert.Equal(t, expectedGBR, gbr) | |||
} |
@@ -2,7 +2,7 @@ | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repofiles | |||
package files | |||
import ( | |||
"fmt" | |||
@@ -10,8 +10,8 @@ import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/git" | |||
repo_module "code.gitea.io/gitea/modules/repository" | |||
api "code.gitea.io/gitea/modules/structs" | |||
repo_service "code.gitea.io/gitea/services/repository" | |||
) | |||
// DeleteRepoFileOptions holds the repository delete file options | |||
@@ -39,7 +39,7 @@ func DeleteRepoFile(repo *models.Repository, doer *models.User, opts *DeleteRepo | |||
} | |||
// oldBranch must exist for this operation | |||
if _, err := repo_module.GetBranch(repo, opts.OldBranch); err != nil { | |||
if _, err := repo_service.GetBranch(repo, opts.OldBranch); err != nil { | |||
return nil, err | |||
} | |||
@@ -47,7 +47,7 @@ func DeleteRepoFile(repo *models.Repository, doer *models.User, opts *DeleteRepo | |||
// Check to make sure the branch does not already exist, otherwise we can't proceed. | |||
// If we aren't branching to a new branch, make sure user can commit to the given branch | |||
if opts.NewBranch != opts.OldBranch { | |||
newBranch, err := repo_module.GetBranch(repo, opts.NewBranch) | |||
newBranch, err := repo_service.GetBranch(repo, opts.NewBranch) | |||
if err != nil && !git.IsErrBranchNotExist(err) { | |||
return nil, err | |||
} |
@@ -2,7 +2,7 @@ | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repofiles | |||
package files | |||
import ( | |||
"strings" |
@@ -2,7 +2,7 @@ | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repofiles | |||
package files | |||
import ( | |||
"testing" |
@@ -2,11 +2,12 @@ | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repofiles | |||
package files | |||
import ( | |||
"fmt" | |||
"net/url" | |||
"path" | |||
"strings" | |||
"time" | |||
@@ -123,3 +124,16 @@ func GetAuthorAndCommitterUsers(author, committer *IdentityOptions, doer *models | |||
} | |||
return authorUser, committerUser | |||
} | |||
// CleanUploadFileName Trims a filename and returns empty string if it is a .git directory | |||
func CleanUploadFileName(name string) string { | |||
// Rebase the filename | |||
name = strings.Trim(path.Clean("/"+name), " /") | |||
// Git disallows any filenames to have a .git directory in them. | |||
for _, part := range strings.Split(name, "/") { | |||
if strings.ToLower(part) == ".git" { | |||
return "" | |||
} | |||
} | |||
return name | |||
} |
@@ -2,7 +2,7 @@ | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repofiles | |||
package files | |||
import ( | |||
"testing" | |||
@@ -16,6 +16,22 @@ import ( | |||
"github.com/stretchr/testify/assert" | |||
) | |||
func TestCleanUploadFileName(t *testing.T) { | |||
t.Run("Clean regular file", func(t *testing.T) { | |||
name := "this/is/test" | |||
cleanName := CleanUploadFileName(name) | |||
expectedCleanName := name | |||
assert.EqualValues(t, expectedCleanName, cleanName) | |||
}) | |||
t.Run("Clean a .git path", func(t *testing.T) { | |||
name := "this/is/test/.git" | |||
cleanName := CleanUploadFileName(name) | |||
expectedCleanName := "" | |||
assert.EqualValues(t, expectedCleanName, cleanName) | |||
}) | |||
} | |||
func getExpectedFileResponse() *api.FileResponse { | |||
treePath := "README.md" | |||
sha := "4b4851ad51df6a7d9f25c979345979eaeb5b349f" |
@@ -2,7 +2,7 @@ | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repofiles | |||
package files | |||
import ( | |||
"bytes" |
@@ -2,7 +2,7 @@ | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repofiles | |||
package files | |||
import ( | |||
"fmt" |
@@ -2,7 +2,7 @@ | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repofiles | |||
package files | |||
import ( | |||
"testing" |
@@ -2,7 +2,7 @@ | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repofiles | |||
package files | |||
import ( | |||
"bytes" | |||
@@ -16,10 +16,10 @@ import ( | |||
"code.gitea.io/gitea/modules/git" | |||
"code.gitea.io/gitea/modules/lfs" | |||
"code.gitea.io/gitea/modules/log" | |||
repo_module "code.gitea.io/gitea/modules/repository" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/structs" | |||
"code.gitea.io/gitea/modules/util" | |||
repo_service "code.gitea.io/gitea/services/repository" | |||
stdcharset "golang.org/x/net/html/charset" | |||
"golang.org/x/text/transform" | |||
@@ -132,7 +132,7 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up | |||
} | |||
// oldBranch must exist for this operation | |||
if _, err := repo_module.GetBranch(repo, opts.OldBranch); err != nil { | |||
if _, err := repo_service.GetBranch(repo, opts.OldBranch); err != nil { | |||
return nil, err | |||
} | |||
@@ -140,7 +140,7 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up | |||
// Check to make sure the branch does not already exist, otherwise we can't proceed. | |||
// If we aren't branching to a new branch, make sure user can commit to the given branch | |||
if opts.NewBranch != opts.OldBranch { | |||
existingBranch, err := repo_module.GetBranch(repo, opts.NewBranch) | |||
existingBranch, err := repo_service.GetBranch(repo, opts.NewBranch) | |||
if existingBranch != nil { | |||
return nil, models.ErrBranchAlreadyExists{ | |||
BranchName: opts.NewBranch, |
@@ -2,7 +2,7 @@ | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repofiles | |||
package files | |||
import ( | |||
"fmt" |