From cbe7f5296e0400a6327b484cf78d6ffb93c9dd2c Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sun, 7 Feb 2021 15:43:40 +0100 Subject: [PATCH 1/9] [API] Add affected files of commits to commit struct (#14579) * Add files affected by a commit to gitea API -- similar to github * Add files affected by a commit to gitea API * Fix stupid error * Fix other stupid typo * Generate swagger tmpl * Comply with convert to git commit refacto * update swagger docs * extend test * format code * Update integrations/api_repo_git_commits_test.go * Update modules/convert/git_commit.go Co-authored-by: Laurent Cahour Co-authored-by: zeripath --- integrations/api_repo_git_commits_test.go | 24 +++++++++++++++++------ modules/convert/git_commit.go | 15 ++++++++++++++ modules/structs/repo_commit.go | 16 ++++++++++----- templates/swagger/v1_json.tmpl | 18 +++++++++++++++++ 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/integrations/api_repo_git_commits_test.go b/integrations/api_repo_git_commits_test.go index 5b0f82e854121..d6bd5fc62e6bd 100644 --- a/integrations/api_repo_git_commits_test.go +++ b/integrations/api_repo_git_commits_test.go @@ -14,6 +14,14 @@ import ( "github.com/stretchr/testify/assert" ) +func compareCommitFiles(t *testing.T, expect []string, files []*api.CommitAffectedFiles) { + var actual []string + for i := range files { + actual = append(actual, files[i].Filename) + } + assert.ElementsMatch(t, expect, actual) +} + func TestAPIReposGitCommits(t *testing.T) { defer prepareTestEnv(t)() user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) @@ -56,10 +64,13 @@ func TestAPIReposGitCommitList(t *testing.T) { var apiData []api.Commit DecodeJSON(t, resp, &apiData) - assert.Equal(t, 3, len(apiData)) - assert.Equal(t, "69554a64c1e6030f051e5c3f94bfbd773cd6a324", apiData[0].CommitMeta.SHA) - assert.Equal(t, "27566bd5738fc8b4e3fef3c5e72cce608537bd95", apiData[1].CommitMeta.SHA) - assert.Equal(t, "5099b81332712fe655e34e8dd63574f503f61811", apiData[2].CommitMeta.SHA) + assert.Len(t, apiData, 3) + assert.EqualValues(t, "69554a64c1e6030f051e5c3f94bfbd773cd6a324", apiData[0].CommitMeta.SHA) + compareCommitFiles(t, []string{"readme.md"}, apiData[0].Files) + assert.EqualValues(t, "27566bd5738fc8b4e3fef3c5e72cce608537bd95", apiData[1].CommitMeta.SHA) + compareCommitFiles(t, []string{"readme.md"}, apiData[1].Files) + assert.EqualValues(t, "5099b81332712fe655e34e8dd63574f503f61811", apiData[2].CommitMeta.SHA) + compareCommitFiles(t, []string{"readme.md"}, apiData[2].Files) } func TestAPIReposGitCommitListPage2Empty(t *testing.T) { @@ -76,7 +87,7 @@ func TestAPIReposGitCommitListPage2Empty(t *testing.T) { var apiData []api.Commit DecodeJSON(t, resp, &apiData) - assert.Equal(t, 0, len(apiData)) + assert.Len(t, apiData, 0) } func TestAPIReposGitCommitListDifferentBranch(t *testing.T) { @@ -93,6 +104,7 @@ func TestAPIReposGitCommitListDifferentBranch(t *testing.T) { var apiData []api.Commit DecodeJSON(t, resp, &apiData) - assert.Equal(t, 1, len(apiData)) + assert.Len(t, apiData, 1) assert.Equal(t, "f27c2b2b03dcab38beaf89b0ab4ff61f6de63441", apiData[0].CommitMeta.SHA) + compareCommitFiles(t, []string{"readme.md"}, apiData[0].Files) } diff --git a/modules/convert/git_commit.go b/modules/convert/git_commit.go index 87dfb51e70688..4e30ec2c0b334 100644 --- a/modules/convert/git_commit.go +++ b/modules/convert/git_commit.go @@ -131,6 +131,20 @@ func ToCommit(repo *models.Repository, commit *git.Commit, userCache map[string] } } + // Retrieve files affected by the commit + fileStatus, err := git.GetCommitFileStatus(repo.RepoPath(), commit.ID.String()) + if err != nil { + return nil, err + } + affectedFileList := make([]*api.CommitAffectedFiles, 0, len(fileStatus.Added)+len(fileStatus.Removed)+len(fileStatus.Modified)) + for _, files := range [][]string{fileStatus.Added, fileStatus.Removed, fileStatus.Modified} { + for _, filename := range files { + affectedFileList = append(affectedFileList, &api.CommitAffectedFiles{ + Filename: filename, + }) + } + } + return &api.Commit{ CommitMeta: &api.CommitMeta{ URL: repo.APIURL() + "/git/commits/" + commit.ID.String(), @@ -162,5 +176,6 @@ func ToCommit(repo *models.Repository, commit *git.Commit, userCache map[string] Author: apiAuthor, Committer: apiCommitter, Parents: apiParents, + Files: affectedFileList, }, nil } diff --git a/modules/structs/repo_commit.go b/modules/structs/repo_commit.go index b9607b185bd6c..f5c5f1b940181 100644 --- a/modules/structs/repo_commit.go +++ b/modules/structs/repo_commit.go @@ -42,11 +42,12 @@ type RepoCommit struct { // Commit contains information generated from a Git commit. type Commit struct { *CommitMeta - HTMLURL string `json:"html_url"` - RepoCommit *RepoCommit `json:"commit"` - Author *User `json:"author"` - Committer *User `json:"committer"` - Parents []*CommitMeta `json:"parents"` + HTMLURL string `json:"html_url"` + RepoCommit *RepoCommit `json:"commit"` + Author *User `json:"author"` + Committer *User `json:"committer"` + Parents []*CommitMeta `json:"parents"` + Files []*CommitAffectedFiles `json:"files"` } // CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE @@ -56,3 +57,8 @@ type CommitDateOptions struct { // swagger:strfmt date-time Committer time.Time `json:"committer"` } + +// CommitAffectedFiles store information about files affected by the commit +type CommitAffectedFiles struct { + Filename string `json:"filename"` +} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index fd760a28e6c47..5a3be37b4aec4 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -11821,6 +11821,13 @@ "format": "date-time", "x-go-name": "Created" }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/CommitAffectedFiles" + }, + "x-go-name": "Files" + }, "html_url": { "type": "string", "x-go-name": "HTMLURL" @@ -11843,6 +11850,17 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, + "CommitAffectedFiles": { + "description": "CommitAffectedFiles store information about files affected by the commit", + "type": "object", + "properties": { + "filename": { + "type": "string", + "x-go-name": "Filename" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, "CommitDateOptions": { "description": "CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE", "type": "object", From 240fea8c14434f836677e6c883ef90523950ece5 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 7 Feb 2021 23:56:11 +0800 Subject: [PATCH 2/9] Fix rate limit bug when downloading assets on migrating from github (#14564) --- modules/migrations/github.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/migrations/github.go b/modules/migrations/github.go index 4d832387ba30e..8d49f9308e8ab 100644 --- a/modules/migrations/github.go +++ b/modules/migrations/github.go @@ -301,10 +301,15 @@ func (g *GithubDownloaderV3) convertGithubRelease(rel *github.RepositoryRelease) Created: asset.CreatedAt.Time, Updated: asset.UpdatedAt.Time, DownloadFunc: func() (io.ReadCloser, error) { + g.sleep() asset, redir, err := g.client.Repositories.DownloadReleaseAsset(g.ctx, g.repoOwner, g.repoName, *asset.ID, http.DefaultClient) if err != nil { return nil, err } + err = g.RefreshRate() + if err != nil { + log.Error("g.client.RateLimits: %s", err) + } if asset == nil { return ioutil.NopCloser(bytes.NewBufferString(redir)), nil } From 5f248d0df290fd08ed54e31424cbb8d8517229e3 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sun, 7 Feb 2021 19:32:18 +0100 Subject: [PATCH 3/9] [API] Add delete release by tag & fix unreleased inconsistency (#14563) * DeleteReleaseByTag delete release not git tags * Add api to delete tag (without release) * fix & extend tests * fix swagger doc --- integrations/api_releases_test.go | 20 ++++----- integrations/api_repo_git_tags_test.go | 24 +++++++++++ routers/api/v1/api.go | 5 ++- routers/api/v1/repo/release_tags.go | 29 ++++++------- routers/api/v1/repo/tag.go | 56 ++++++++++++++++++++++++ templates/swagger/v1_json.tmpl | 59 ++++++++++++++++++++++---- 6 files changed, 157 insertions(+), 36 deletions(-) diff --git a/integrations/api_releases_test.go b/integrations/api_releases_test.go index 2b310d11e0847..26bf752ccae9e 100644 --- a/integrations/api_releases_test.go +++ b/integrations/api_releases_test.go @@ -154,7 +154,7 @@ func TestAPIGetReleaseByTag(t *testing.T) { assert.EqualValues(t, "Not Found", err.Message) } -func TestAPIDeleteTagByName(t *testing.T) { +func TestAPIDeleteReleaseByTagName(t *testing.T) { defer prepareTestEnv(t)() repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository) @@ -162,17 +162,17 @@ func TestAPIDeleteTagByName(t *testing.T) { session := loginUser(t, owner.LowerName) token := getTokenForLoggedInUser(t, session) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/delete-tag?token=%s", - owner.Name, repo.Name, token) + createNewReleaseUsingAPI(t, session, token, owner, repo, "release-tag", "", "Release Tag", "test") - req := NewRequestf(t, http.MethodDelete, urlStr) + // delete release + req := NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/release-tag?token=%s", owner.Name, repo.Name, token)) _ = session.MakeRequest(t, req, http.StatusNoContent) - // Make sure that actual releases can't be deleted outright - createNewReleaseUsingAPI(t, session, token, owner, repo, "release-tag", "", "Release Tag", "test") - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/release-tag?token=%s", - owner.Name, repo.Name, token) + // make sure release is deleted + req = NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/release-tag?token=%s", owner.Name, repo.Name, token)) + _ = session.MakeRequest(t, req, http.StatusNotFound) - req = NewRequestf(t, http.MethodDelete, urlStr) - _ = session.MakeRequest(t, req, http.StatusConflict) + // delete release tag too + req = NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/tags/release-tag?token=%s", owner.Name, repo.Name, token)) + _ = session.MakeRequest(t, req, http.StatusNoContent) } diff --git a/integrations/api_repo_git_tags_test.go b/integrations/api_repo_git_tags_test.go index ad710a45204da..bf6fc7c858137 100644 --- a/integrations/api_repo_git_tags_test.go +++ b/integrations/api_repo_git_tags_test.go @@ -5,6 +5,7 @@ package integrations import ( + "fmt" "net/http" "testing" @@ -59,3 +60,26 @@ func TestAPIGitTags(t *testing.T) { badReq := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/tags/%s?token=%s", user.Name, repo.Name, commit.ID.String(), token) session.MakeRequest(t, badReq, http.StatusBadRequest) } + +func TestAPIDeleteTagByName(t *testing.T) { + defer prepareTestEnv(t)() + + repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository) + owner := models.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User) + session := loginUser(t, owner.LowerName) + token := getTokenForLoggedInUser(t, session) + + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/tags/delete-tag?token=%s", + owner.Name, repo.Name, token) + + req := NewRequestf(t, http.MethodDelete, urlStr) + _ = session.MakeRequest(t, req, http.StatusNoContent) + + // Make sure that actual releases can't be deleted outright + createNewReleaseUsingAPI(t, session, token, owner, repo, "release-tag", "", "Release Tag", "test") + urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/tags/release-tag?token=%s", + owner.Name, repo.Name, token) + + req = NewRequestf(t, http.MethodDelete, urlStr) + _ = session.MakeRequest(t, req, http.StatusConflict) +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 42b52db93657d..9c21107a2892c 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -754,6 +754,7 @@ func Routes() *web.Route { }, reqToken(), reqAdmin()) m.Group("/tags", func() { m.Get("", repo.ListTags) + m.Delete("/{tag}", repo.DeleteTag) }, reqRepoReader(models.UnitTypeCode), context.ReferencesGitRepo(true)) m.Group("/keys", func() { m.Combo("").Get(repo.ListDeployKeys). @@ -862,8 +863,8 @@ func Routes() *web.Route { }) m.Group("/tags", func() { m.Combo("/{tag}"). - Get(repo.GetReleaseTag). - Delete(reqToken(), reqRepoWriter(models.UnitTypeReleases), repo.DeleteReleaseTag) + Get(repo.GetReleaseByTag). + Delete(reqToken(), reqRepoWriter(models.UnitTypeReleases), repo.DeleteReleaseByTag) }) }, reqRepoReader(models.UnitTypeReleases)) m.Post("/mirror-sync", reqToken(), reqRepoWriter(models.UnitTypeCode), repo.MirrorSync) diff --git a/routers/api/v1/repo/release_tags.go b/routers/api/v1/repo/release_tags.go index 70011a6a8edcc..4b853d44bb956 100644 --- a/routers/api/v1/repo/release_tags.go +++ b/routers/api/v1/repo/release_tags.go @@ -5,7 +5,6 @@ package repo import ( - "errors" "net/http" "code.gitea.io/gitea/models" @@ -14,9 +13,9 @@ import ( releaseservice "code.gitea.io/gitea/services/release" ) -// GetReleaseTag get a single release of a repository by its tagname -func GetReleaseTag(ctx *context.APIContext) { - // swagger:operation GET /repos/{owner}/{repo}/releases/tags/{tag} repository repoGetReleaseTag +// GetReleaseByTag get a single release of a repository by tag name +func GetReleaseByTag(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/releases/tags/{tag} repository repoGetReleaseByTag // --- // summary: Get a release by tag name // produces: @@ -34,7 +33,7 @@ func GetReleaseTag(ctx *context.APIContext) { // required: true // - name: tag // in: path - // description: tagname of the release to get + // description: tag name of the release to get // type: string // required: true // responses: @@ -67,11 +66,11 @@ func GetReleaseTag(ctx *context.APIContext) { ctx.JSON(http.StatusOK, convert.ToRelease(release)) } -// DeleteReleaseTag delete a tag from a repository -func DeleteReleaseTag(ctx *context.APIContext) { - // swagger:operation DELETE /repos/{owner}/{repo}/releases/tags/{tag} repository repoDeleteReleaseTag +// DeleteReleaseByTag delete a release from a repository by tag name +func DeleteReleaseByTag(ctx *context.APIContext) { + // swagger:operation DELETE /repos/{owner}/{repo}/releases/tags/{tag} repository repoDeleteReleaseByTag // --- - // summary: Delete a release tag + // summary: Delete a release by tag name // parameters: // - name: owner // in: path @@ -85,7 +84,7 @@ func DeleteReleaseTag(ctx *context.APIContext) { // required: true // - name: tag // in: path - // description: name of the tag to delete + // description: tag name of the release to delete // type: string // required: true // responses: @@ -93,27 +92,25 @@ func DeleteReleaseTag(ctx *context.APIContext) { // "$ref": "#/responses/empty" // "404": // "$ref": "#/responses/notFound" - // "409": - // "$ref": "#/responses/conflict" tag := ctx.Params(":tag") release, err := models.GetRelease(ctx.Repo.Repository.ID, tag) if err != nil { if models.IsErrReleaseNotExist(err) { - ctx.Error(http.StatusNotFound, "GetRelease", err) + ctx.NotFound() return } ctx.Error(http.StatusInternalServerError, "GetRelease", err) return } - if !release.IsTag { - ctx.Error(http.StatusConflict, "IsTag", errors.New("a tag attached to a release cannot be deleted directly")) + if release.IsTag { + ctx.NotFound() return } - if err := releaseservice.DeleteReleaseByID(release.ID, ctx.User, true); err != nil { + if err = releaseservice.DeleteReleaseByID(release.ID, ctx.User, false); err != nil { ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err) } diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go index 76c612bea4205..ec9b541bd41d3 100644 --- a/routers/api/v1/repo/tag.go +++ b/routers/api/v1/repo/tag.go @@ -5,12 +5,15 @@ package repo import ( + "errors" "net/http" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + releaseservice "code.gitea.io/gitea/services/release" ) // ListTags list all the tags of a repository @@ -104,3 +107,56 @@ func GetTag(ctx *context.APIContext) { ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx.Repo.Repository, tag, commit)) } } + +// DeleteTag delete a specific tag of in a repository by name +func DeleteTag(ctx *context.APIContext) { + // swagger:operation DELETE /repos/{owner}/{repo}/tags/{tag} repository repoDeleteTag + // --- + // summary: Delete a repository's tag by name + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: tag + // in: path + // description: name of tag to delete + // type: string + // required: true + // responses: + // "204": + // "$ref": "#/responses/empty" + // "404": + // "$ref": "#/responses/notFound" + // "409": + // "$ref": "#/responses/conflict" + + tag, err := models.GetRelease(ctx.Repo.Repository.ID, ctx.Params("tag")) + if err != nil { + if models.IsErrReleaseNotExist(err) { + ctx.NotFound() + return + } + ctx.Error(http.StatusInternalServerError, "GetRelease", err) + return + } + + if !tag.IsTag { + ctx.Error(http.StatusConflict, "IsTag", errors.New("a tag attached to a release cannot be deleted directly")) + return + } + + if err = releaseservice.DeleteReleaseByID(tag.ID, ctx.User, true); err != nil { + ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err) + } + + ctx.Status(http.StatusNoContent) +} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 5a3be37b4aec4..45f396f2830f6 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -7964,7 +7964,7 @@ "repository" ], "summary": "Get a release by tag name", - "operationId": "repoGetReleaseTag", + "operationId": "repoGetReleaseByTag", "parameters": [ { "type": "string", @@ -7982,7 +7982,7 @@ }, { "type": "string", - "description": "tagname of the release to get", + "description": "tag name of the release to get", "name": "tag", "in": "path", "required": true @@ -8001,8 +8001,8 @@ "tags": [ "repository" ], - "summary": "Delete a release tag", - "operationId": "repoDeleteReleaseTag", + "summary": "Delete a release by tag name", + "operationId": "repoDeleteReleaseByTag", "parameters": [ { "type": "string", @@ -8020,7 +8020,7 @@ }, { "type": "string", - "description": "name of the tag to delete", + "description": "tag name of the release to delete", "name": "tag", "in": "path", "required": true @@ -8032,9 +8032,6 @@ }, "404": { "$ref": "#/responses/notFound" - }, - "409": { - "$ref": "#/responses/conflict" } } } @@ -8815,6 +8812,52 @@ } } }, + "/repos/{owner}/{repo}/tags/{tag}": { + "delete": { + "produces": [ + "application/json" + ], + "tags": [ + "repository" + ], + "summary": "Delete a repository's tag by name", + "operationId": "repoDeleteTag", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of tag to delete", + "name": "tag", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "$ref": "#/responses/conflict" + } + } + } + }, "/repos/{owner}/{repo}/teams": { "get": { "produces": [ From e65cfabda7caa22eef92137c5c501d1c60fcc42a Mon Sep 17 00:00:00 2001 From: zeripath Date: Sun, 7 Feb 2021 21:04:58 +0000 Subject: [PATCH 4/9] Remove spurious DataAsync Error logging (#14599) Breaking the pipe is a valid way of killing a piped command and any error from a broken cat-file batch command should be passed back up to the writer any way therefore specifically logging it is unnecessary. Signed-off-by: Andrew Thornton --- modules/git/blob_nogogit.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/git/blob_nogogit.go b/modules/git/blob_nogogit.go index 731f7d06e8a60..e917a316195d1 100644 --- a/modules/git/blob_nogogit.go +++ b/modules/git/blob_nogogit.go @@ -11,8 +11,6 @@ import ( "io" "strconv" "strings" - - gitea_log "code.gitea.io/gitea/modules/log" ) // Blob represents a Git object. @@ -35,7 +33,6 @@ func (b *Blob) DataAsync() (io.ReadCloser, error) { err := NewCommand("cat-file", "--batch").RunInDirFullPipeline(b.repoPath, stdoutWriter, stderr, strings.NewReader(b.ID.String()+"\n")) if err != nil { err = ConcatenateError(err, stderr.String()) - gitea_log.Error("Blob.DataAsync Error: %v", err) _ = stdoutWriter.CloseWithError(err) } else { _ = stdoutWriter.Close() From 3477e616abe9ad47eb020d19a3ac925bd961e47b Mon Sep 17 00:00:00 2001 From: zeripath Date: Mon, 8 Feb 2021 01:00:12 +0000 Subject: [PATCH 5/9] Exclude the current dump file from the dump (#14606) * Exclude the current dump file from the dump Always prevent the current file from being added to the dump. Fix #13618 Signed-off-by: Andrew Thornton * Add skip custom directory option Signed-off-by: Andrew Thornton * placate lint Signed-off-by: Andrew Thornton Co-authored-by: 6543 <6543@obermui.de> --- cmd/dump.go | 66 +++++++------------- docs/content/doc/usage/command-line.en-us.md | 1 + 2 files changed, 25 insertions(+), 42 deletions(-) diff --git a/cmd/dump.go b/cmd/dump.go index 65e2c817f92b5..1acc69f1c8569 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -49,38 +49,6 @@ func addFile(w archiver.Writer, filePath string, absPath string, verbose bool) e }) } -func addRecursive(w archiver.Writer, dirPath string, absPath string, verbose bool) error { - if verbose { - log.Info("Adding dir %s\n", dirPath) - } - dir, err := os.Open(absPath) - if err != nil { - return fmt.Errorf("Could not open directory %s: %s", absPath, err) - } - defer dir.Close() - - files, err := dir.Readdir(0) - if err != nil { - return fmt.Errorf("Unable to list files in %s: %s", absPath, err) - } - - if err := addFile(w, dirPath, absPath, false); err != nil { - return err - } - - for _, fileInfo := range files { - if fileInfo.IsDir() { - err = addRecursive(w, filepath.Join(dirPath, fileInfo.Name()), filepath.Join(absPath, fileInfo.Name()), verbose) - } else { - err = addFile(w, filepath.Join(dirPath, fileInfo.Name()), filepath.Join(absPath, fileInfo.Name()), verbose) - } - if err != nil { - return err - } - } - return nil -} - func isSubdir(upper string, lower string) (bool, error) { if relPath, err := filepath.Rel(upper, lower); err != nil { return false, err @@ -157,6 +125,10 @@ It can be used for backup and capture Gitea server image to send to maintainer`, Name: "skip-log, L", Usage: "Skip the log dumping", }, + cli.BoolFlag{ + Name: "skip-custom-dir", + Usage: "Skip custom directory", + }, cli.GenericFlag{ Name: "type", Value: outputTypeEnum, @@ -211,6 +183,11 @@ func runDump(ctx *cli.Context) error { } defer file.Close() + absFileName, err := filepath.Abs(fileName) + if err != nil { + return err + } + verbose := ctx.Bool("verbose") outType := ctx.String("type") var iface interface{} @@ -233,7 +210,7 @@ func runDump(ctx *cli.Context) error { log.Info("Skip dumping local repositories") } else { log.Info("Dumping local repositories... %s", setting.RepoRootPath) - if err := addRecursive(w, "repos", setting.RepoRootPath, verbose); err != nil { + if err := addRecursiveExclude(w, "repos", setting.RepoRootPath, []string{absFileName}, verbose); err != nil { fatal("Failed to include repositories: %v", err) } @@ -292,17 +269,21 @@ func runDump(ctx *cli.Context) error { } } - customDir, err := os.Stat(setting.CustomPath) - if err == nil && customDir.IsDir() { - if is, _ := isSubdir(setting.AppDataPath, setting.CustomPath); !is { - if err := addRecursive(w, "custom", setting.CustomPath, verbose); err != nil { - fatal("Failed to include custom: %v", err) + if ctx.IsSet("skip-custom-dir") && ctx.Bool("skip-custom-dir") { + log.Info("Skiping custom directory") + } else { + customDir, err := os.Stat(setting.CustomPath) + if err == nil && customDir.IsDir() { + if is, _ := isSubdir(setting.AppDataPath, setting.CustomPath); !is { + if err := addRecursiveExclude(w, "custom", setting.CustomPath, []string{absFileName}, verbose); err != nil { + fatal("Failed to include custom: %v", err) + } + } else { + log.Info("Custom dir %s is inside data dir %s, skipped", setting.CustomPath, setting.AppDataPath) } } else { - log.Info("Custom dir %s is inside data dir %s, skipped", setting.CustomPath, setting.AppDataPath) + log.Info("Custom dir %s doesn't exist, skipped", setting.CustomPath) } - } else { - log.Info("Custom dir %s doesn't exist, skipped", setting.CustomPath) } isExist, err := util.IsExist(setting.AppDataPath) @@ -325,6 +306,7 @@ func runDump(ctx *cli.Context) error { excludes = append(excludes, setting.LFS.Path) excludes = append(excludes, setting.Attachment.Path) excludes = append(excludes, setting.LogRootPath) + excludes = append(excludes, absFileName) if err := addRecursiveExclude(w, "data", setting.AppDataPath, excludes, verbose); err != nil { fatal("Failed to include data directory: %v", err) } @@ -358,7 +340,7 @@ func runDump(ctx *cli.Context) error { log.Error("Unable to check if %s exists. Error: %v", setting.LogRootPath, err) } if isExist { - if err := addRecursive(w, "log", setting.LogRootPath, verbose); err != nil { + if err := addRecursiveExclude(w, "log", setting.LogRootPath, []string{absFileName}, verbose); err != nil { fatal("Failed to include log: %v", err) } } diff --git a/docs/content/doc/usage/command-line.en-us.md b/docs/content/doc/usage/command-line.en-us.md index 192eaa2c5aa46..97882f9203b7d 100644 --- a/docs/content/doc/usage/command-line.en-us.md +++ b/docs/content/doc/usage/command-line.en-us.md @@ -253,6 +253,7 @@ in the current directory. - `--file name`, `-f name`: Name of the dump file with will be created. Optional. (default: gitea-dump-[timestamp].zip). - `--tempdir path`, `-t path`: Path to the temporary directory used. Optional. (default: /tmp). - `--skip-repository`, `-R`: Skip the repository dumping. Optional. + - `--skip-custom-dir`: Skip dumping of the custom dir. Optional. - `--database`, `-d`: Specify the database SQL syntax. Optional. - `--verbose`, `-V`: If provided, shows additional details. Optional. - Examples: From f1800093754849b676df82fc204fe7b9bca4da2a Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Mon, 8 Feb 2021 01:01:27 +0000 Subject: [PATCH 6/9] [skip ci] Updated translations via Crowdin --- options/locale/locale_es-ES.ini | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index a54832730f1f9..95fe653e74c64 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -86,6 +86,8 @@ write=Escribir preview=Vista previa loading=Cargando… +step1=Paso 1: +step2=Paso 2: error404=La página a la que está intentando acceder o no existe o no está autorizado para verla. @@ -214,6 +216,7 @@ my_mirrors=Mis réplicas view_home=Ver %s search_repos=Buscar un repositorio… filter=Otros filtros +filter_by_team_repositories=Filtrar por repositorios de equipo show_archived=Archivado show_both_archived_unarchived=Mostrar respositorios archivados y desarchivados @@ -618,6 +621,7 @@ or_enter_secret=O introduzca el secreto: %s then_enter_passcode=E introduzca el código de acceso mostrado en la aplicación: passcode_invalid=El código de acceso es incorrecto. Vuelva a intentarlo. twofa_enrolled=Su cuenta ha sido inscrita en la autenticación de doble factor. ¡Guarde su código de respaldo (%s) en un lugar seguro, ya que sólo se muestra una vez! +twofa_failed_get_secret=No se pudo obtener el secreto. u2f_desc=Las claves de seguridad son dispositivos hardware que contienen claves criptográficas. Pueden ser usados para la autenticación de doble factor. Las claves de seguridad deben soportar el estándar FIDOU2F. u2f_require_twofa=Su cuenta debe tener activada la autenticación de doble factor para utilizar claves de seguridad. @@ -814,6 +818,8 @@ tag=Etiqueta released_this=publicó esto file_raw=Original file_history=Histórico +file_view_source=Ver código fuente +file_view_rendered=Ver procesado file_view_raw=Ver original file_permalink=Enlace permanente file_too_large=El archivo es demasiado grande para ser mostrado. @@ -910,6 +916,8 @@ ext_issues=Incidencias externas ext_issues.desc=Enlace a un gestor de incidencias externo. projects=Proyectos +projects.description=Descripción (opcional) +projects.description_placeholder=Descripción projects.create=Crear Proyecto projects.title=Título projects.new=Nuevo proyecto @@ -1121,10 +1129,13 @@ issues.lock.title=Bloquear conversación sobre esta incidencia. issues.unlock.title=Desbloquear conversación sobre esta incidencia. issues.comment_on_locked=No puede comentar una incidencia bloqueada. issues.tracker=Gestor de tiempo +issues.start_tracking_short=Iniciar temporizador issues.start_tracking=Inicio de seguimiento de tiempo issues.start_tracking_history=`ha empezado a trabajar %s` issues.tracker_auto_close=El temporizador se detendrá automáticamente cuando se cierre este problema +issues.stop_tracking=Detener temporizador issues.stop_tracking_history=`dejó de trabajar %s` +issues.cancel_tracking=Descartar issues.cancel_tracking_history=`canceló el seguimiento de tiempo %s` issues.add_time=Añadir tiempo gastado manualmente issues.add_time_short=Añadir tiempo gastado @@ -1204,6 +1215,7 @@ issues.review.resolve_conversation=Resolver conversación issues.review.un_resolve_conversation=Marcar conversación sin resolver issues.review.resolved_by=ha marcado esta conversación como resuelta issues.assignee.error=No todos los asignados fueron añadidos debido a un error inesperado. +issues.reference_issue.body=Cuerpo pulls.desc=Activar Pull Requests y revisiones de código. pulls.new=Nuevo Pull Request @@ -2030,6 +2042,7 @@ dashboard.resync_all_sshprincipals.desc=(No es necesario para el servidor SSH in dashboard.resync_all_hooks=Resincronizar los hooks de pre-recepción, actualización y post-recepción de todos los repositorios. dashboard.reinit_missing_repos=Reiniciar todos los repositorios Git faltantes de los que existen registros dashboard.sync_external_users=Sincronizar datos de usuario externo +dashboard.cleanup_hook_task_table=Limpiar tabla hook_task dashboard.server_uptime=Tiempo de actividad del servidor dashboard.current_goroutine=Gorutinas actuales dashboard.current_memory_usage=Uso de memoria actual @@ -2180,6 +2193,7 @@ auths.enable_tls=Habilitar cifrado TLS auths.skip_tls_verify=Omitir la verificación TLS auths.pam_service_name=Nombre del Servicio PAM auths.oauth2_provider=Proveedor OAuth2 +auths.oauth2_icon_url=URL de icono auths.oauth2_clientID=ID de cliente (clave) auths.oauth2_clientSecret=Secreto del cliente auths.openIdConnectAutoDiscoveryURL=URL de descubrimiento automático de OpenID Connect From 98827e99f63178c43187e686ffc4bf03d9d18d36 Mon Sep 17 00:00:00 2001 From: zeripath Date: Mon, 8 Feb 2021 02:06:21 +0000 Subject: [PATCH 7/9] Add information on how to build statically (#14594) Fix #14576 Signed-off-by: Andrew Thornton Co-authored-by: Lunny Xiao --- docs/content/doc/installation/from-source.en-us.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/content/doc/installation/from-source.en-us.md b/docs/content/doc/installation/from-source.en-us.md index bff206a86213d..5525faf3d574f 100644 --- a/docs/content/doc/installation/from-source.en-us.md +++ b/docs/content/doc/installation/from-source.en-us.md @@ -186,3 +186,11 @@ CC=aarch64-unknown-linux-gnu-gcc GOOS=linux GOARCH=arm64 TAGS="bindata sqlite sq ``` Replace `CC`, `GOOS`, and `GOARCH` as appropriate for your architecture target. + +You will sometimes need to build a static compiled image. To do this you will need to add: + +``` +LDFLAGS="-linkmode external -extldflags '-static' $LDFLAGS" TAGS="netgo osusergo $TAGS" make build +``` + +This can be combined with `CC`, `GOOS`, and `GOARCH` as above. From 378acc9d966554299e4a7dbe15e6e41026963653 Mon Sep 17 00:00:00 2001 From: zeripath Date: Mon, 8 Feb 2021 03:09:14 +0000 Subject: [PATCH 8/9] Use OldRef instead of CommitSHA for DeleteBranch comments (#14604) Fix #14545 Signed-off-by: Andrew Thornton Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Lunny Xiao --- models/issue.go | 10 +++++----- models/migrations/migrations.go | 2 ++ models/migrations/v169.go | 14 ++++++++++++++ templates/repo/issue/view_content/comments.tmpl | 2 +- 4 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 models/migrations/v169.go diff --git a/models/issue.go b/models/issue.go index a7392633af51f..b903e82ad7d40 100644 --- a/models/issue.go +++ b/models/issue.go @@ -745,11 +745,11 @@ func AddDeletePRBranchComment(doer *User, repo *Repository, issueID int64, branc return err } var opts = &CreateCommentOptions{ - Type: CommentTypeDeleteBranch, - Doer: doer, - Repo: repo, - Issue: issue, - CommitSHA: branchName, + Type: CommentTypeDeleteBranch, + Doer: doer, + Repo: repo, + Issue: issue, + OldRef: branchName, } if _, err = createComment(sess, opts); err != nil { return err diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index c1a3b186cf873..c926ee6ccf191 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -284,6 +284,8 @@ var migrations = []Migration{ NewMigration("Add user redirect", addUserRedirect), // v168 -> v169 NewMigration("Recreate user table to fix default values", recreateUserTableToFixDefaultValues), + // v169 -> v170 + NewMigration("Update DeleteBranch comments to set the old_ref to the commit_sha", commentTypeDeleteBranchUseOldRef), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v169.go b/models/migrations/v169.go new file mode 100644 index 0000000000000..e976281c5b102 --- /dev/null +++ b/models/migrations/v169.go @@ -0,0 +1,14 @@ +// Copyright 2021 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 migrations + +import ( + "xorm.io/xorm" +) + +func commentTypeDeleteBranchUseOldRef(x *xorm.Engine) error { + _, err := x.Exec("UPDATE comment SET old_ref = commit_sha, commit_sha = '' WHERE type = 11") + return err +} diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index abf5792a9ee1c..63fe73857ca5a 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -251,7 +251,7 @@ {{.Poster.GetDisplayName}} - {{$.i18n.Tr "repo.issues.delete_branch_at" (.CommitSHA|Escape) $createdStr | Safe}} + {{$.i18n.Tr "repo.issues.delete_branch_at" (.OldRef|Escape) $createdStr | Safe}} {{else if eq .Type 12}} From 758627cf8f3f32681bf792b3a6b9f74572210d89 Mon Sep 17 00:00:00 2001 From: uli-heller Date: Mon, 8 Feb 2021 16:16:53 +0100 Subject: [PATCH 9/9] Fixed irritating error message related to go version (#14611) I do have go-1.13.8 installed and get the error message ``` Gitea requires Go 1.13 or greater to build. You can get it at https://golang.org/dl/ ``` I do thing that Go 1.14 or greater is actually required --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e044ed09f2690..7dd7464acb2fe 100644 --- a/Makefile +++ b/Makefile @@ -190,7 +190,7 @@ help: go-check: $(eval GO_VERSION := $(shell printf "%03d%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9.]+' | tr '.' ' ');)) @if [ "$(GO_VERSION)" -lt "$(MIN_GO_VERSION)" ]; then \ - echo "Gitea requires Go 1.13 or greater to build. You can get it at https://golang.org/dl/"; \ + echo "Gitea requires Go 1.14 or greater to build. You can get it at https://golang.org/dl/"; \ exit 1; \ fi