diff --git a/integrations/api_repo_file_helpers.go b/integrations/api_repo_file_helpers.go index 1dba136de9..ef3b8c610b 100644 --- a/integrations/api_repo_file_helpers.go +++ b/integrations/api_repo_file_helpers.go @@ -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) { diff --git a/integrations/pull_update_test.go b/integrations/pull_update_test.go index 43cfe7debf..d7ea676b79 100644 --- a/integrations/pull_update_test.go +++ b/integrations/pull_update_test.go @@ -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(), }, diff --git a/integrations/repofiles_delete_test.go b/integrations/repofiles_delete_test.go index eb73348950..8490f8d3a7 100644 --- a/integrations/repofiles_delete_test.go +++ b/integrations/repofiles_delete_test.go @@ -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 + "]" diff --git a/integrations/repofiles_update_test.go b/integrations/repofiles_update_test.go index 9e99b36ae4..fe0e2c21c6 100644 --- a/integrations/repofiles_update_test.go +++ b/integrations/repofiles_update_test.go @@ -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 + "]" diff --git a/modules/convert/pull.go b/modules/convert/pull.go index ab17c13421..0f2b5af1b4 100644 --- a/modules/convert/pull.go +++ b/modules/convert/pull.go @@ -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 diff --git a/modules/repofiles/blob.go b/modules/repofiles/blob.go deleted file mode 100644 index 02bc1ebcab..0000000000 --- a/modules/repofiles/blob.go +++ /dev/null @@ -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 -} diff --git a/modules/repofiles/blob_test.go b/modules/repofiles/blob_test.go deleted file mode 100644 index 8950c349e6..0000000000 --- a/modules/repofiles/blob_test.go +++ /dev/null @@ -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) -} diff --git a/modules/repofiles/commit.go b/modules/repofiles/commit.go deleted file mode 100644 index 371e6cf3ab..0000000000 --- a/modules/repofiles/commit.go +++ /dev/null @@ -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 -} diff --git a/modules/repofiles/commit_status.go b/modules/repofiles/commit_status.go deleted file mode 100644 index 3d93c58d85..0000000000 --- a/modules/repofiles/commit_status.go +++ /dev/null @@ -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 -} diff --git a/modules/repofiles/repofiles.go b/modules/repofiles/repofiles.go deleted file mode 100644 index 1fc900490c..0000000000 --- a/modules/repofiles/repofiles.go +++ /dev/null @@ -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 -} diff --git a/modules/repofiles/repofiles_test.go b/modules/repofiles/repofiles_test.go deleted file mode 100644 index 1686378a4a..0000000000 --- a/modules/repofiles/repofiles_test.go +++ /dev/null @@ -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) - }) -} diff --git a/modules/repofiles/verification.go b/modules/repofiles/verification.go deleted file mode 100644 index 3889b7993c..0000000000 --- a/modules/repofiles/verification.go +++ /dev/null @@ -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 -} diff --git a/modules/repository/branch.go b/modules/repository/branch.go deleted file mode 100644 index dcd82554d5..0000000000 --- a/modules/repository/branch.go +++ /dev/null @@ -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) -} diff --git a/routers/api/v1/repo/blob.go b/routers/api/v1/repo/blob.go index 3918a49d51..e3ce0e1916 100644 --- a/routers/api/v1/repo/blob.go +++ b/routers/api/v1/repo/blob.go @@ -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) diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 2e08b56826..04da901239 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -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 diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 009b8a26d6..e84f652ed9 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -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 diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go index b884432f73..583b89dd7a 100644 --- a/routers/api/v1/repo/status.go +++ b/routers/api/v1/repo/status.go @@ -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 } diff --git a/routers/api/v1/repo/tree.go b/routers/api/v1/repo/tree.go index aec336235d..2168a311d0 100644 --- a/routers/api/v1/repo/tree.go +++ b/routers/api/v1/repo/tree.go @@ -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) diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index a6ad3eff5a..64fb1afb2d 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -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 diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index 088edbfd29..d4fc55979c 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -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 } diff --git a/services/cron/tasks_basic.go b/services/cron/tasks_basic.go index 219173ccf0..4832ca98a7 100644 --- a/services/cron/tasks_basic.go +++ b/services/cron/tasks_basic.go @@ -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() { diff --git a/services/cron/tasks_extended.go b/services/cron/tasks_extended.go index b0cb5ee921..95293b1c1d 100644 --- a/services/cron/tasks_extended.go +++ b/services/cron/tasks_extended.go @@ -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) }) } diff --git a/services/repository/branch.go b/services/repository/branch.go index 83980c5bd9..f94a9afcb6 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -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) { diff --git a/modules/repository/check.go b/services/repository/check.go similarity index 100% rename from modules/repository/check.go rename to services/repository/check.go diff --git a/services/repository/files/commit.go b/services/repository/files/commit.go new file mode 100644 index 0000000000..ebae097112 --- /dev/null +++ b/services/repository/files/commit.go @@ -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 +} diff --git a/modules/repofiles/content.go b/services/repository/files/content.go similarity index 88% rename from modules/repofiles/content.go rename to services/repository/files/content.go index 838bfabdc6..afb775fed3 100644 --- a/modules/repofiles/content.go +++ b/services/repository/files/content.go @@ -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 +} diff --git a/modules/repofiles/content_test.go b/services/repository/files/content_test.go similarity index 86% rename from modules/repofiles/content_test.go rename to services/repository/files/content_test.go index f6a953fab9..68b29b1daa 100644 --- a/modules/repofiles/content_test.go +++ b/services/repository/files/content_test.go @@ -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) +} diff --git a/modules/repofiles/delete.go b/services/repository/files/delete.go similarity index 96% rename from modules/repofiles/delete.go rename to services/repository/files/delete.go index 5ae418b7f6..f8d7f62c14 100644 --- a/modules/repofiles/delete.go +++ b/services/repository/files/delete.go @@ -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 } diff --git a/modules/repofiles/diff.go b/services/repository/files/diff.go similarity index 98% rename from modules/repofiles/diff.go rename to services/repository/files/diff.go index c98bbc7684..fadaf20231 100644 --- a/modules/repofiles/diff.go +++ b/services/repository/files/diff.go @@ -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" diff --git a/modules/repofiles/diff_test.go b/services/repository/files/diff_test.go similarity index 99% rename from modules/repofiles/diff_test.go rename to services/repository/files/diff_test.go index 4bd1ef6f4d..be8e92033d 100644 --- a/modules/repofiles/diff_test.go +++ b/services/repository/files/diff_test.go @@ -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" diff --git a/modules/repofiles/file.go b/services/repository/files/file.go similarity index 91% rename from modules/repofiles/file.go rename to services/repository/files/file.go index 4030924017..ad445bb4ae 100644 --- a/modules/repofiles/file.go +++ b/services/repository/files/file.go @@ -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 +} diff --git a/modules/repofiles/file_test.go b/services/repository/files/file_test.go similarity index 87% rename from modules/repofiles/file_test.go rename to services/repository/files/file_test.go index 54205a89c7..25303a6d00 100644 --- a/modules/repofiles/file_test.go +++ b/services/repository/files/file_test.go @@ -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" diff --git a/modules/repofiles/temp_repo.go b/services/repository/files/temp_repo.go similarity index 99% rename from modules/repofiles/temp_repo.go rename to services/repository/files/temp_repo.go index 700ce92ebf..2a6d6c3ab6 100644 --- a/modules/repofiles/temp_repo.go +++ b/services/repository/files/temp_repo.go @@ -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" diff --git a/modules/repofiles/tree.go b/services/repository/files/tree.go similarity index 99% rename from modules/repofiles/tree.go rename to services/repository/files/tree.go index 81579dccc5..ede206274e 100644 --- a/modules/repofiles/tree.go +++ b/services/repository/files/tree.go @@ -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" diff --git a/modules/repofiles/tree_test.go b/services/repository/files/tree_test.go similarity index 98% rename from modules/repofiles/tree_test.go rename to services/repository/files/tree_test.go index 6917b8915b..37a6025d6c 100644 --- a/modules/repofiles/tree_test.go +++ b/services/repository/files/tree_test.go @@ -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" diff --git a/modules/repofiles/update.go b/services/repository/files/update.go similarity index 98% rename from modules/repofiles/update.go rename to services/repository/files/update.go index d25accff18..5d6c3da670 100644 --- a/modules/repofiles/update.go +++ b/services/repository/files/update.go @@ -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, diff --git a/modules/repofiles/upload.go b/services/repository/files/upload.go similarity index 99% rename from modules/repofiles/upload.go rename to services/repository/files/upload.go index e97f55a656..98d01506d5 100644 --- a/modules/repofiles/upload.go +++ b/services/repository/files/upload.go @@ -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"