From f433cede0a4bfa4514fb381d48aae0f6f98d1bed Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 26 Jul 2022 09:39:15 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routers/api/v1/repo/wiki.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go index 1d8e3b3b1..ef4bab5c1 100644 --- a/routers/api/v1/repo/wiki.go +++ b/routers/api/v1/repo/wiki.go @@ -326,7 +326,12 @@ func ListWikiPages(ctx *context.APIContext) { continue } if entry.IsRegular() { - c, err := wikiRepo.GetCommitByPath(fmt.Sprintf("%s/%s", filePath, entry.Name())) + var commit *git.Commit + if filePath == "" { + commit, err = wikiRepo.GetCommitByPath(entry.Name()) + } else { + commit, err = wikiRepo.GetCommitByPath(fmt.Sprintf("%s/%s", filePath, entry.Name())) + } if err != nil { ctx.Error(http.StatusInternalServerError, "GetCommit", err) return @@ -339,15 +344,20 @@ func ListWikiPages(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "WikiFilenameToName", err) return } - lists = append(lists, convert.RegularToWikiPageMetaData(wikiName, c, ctx.Repo.Repository)) + lists = append(lists, convert.RegularToWikiPageMetaData(wikiName, commit, ctx.Repo.Repository)) } if entry.IsDir() { - c, err := wikiRepo.GetCommitByPath(fmt.Sprintf("%s/%s", filePath, entry.Name())) + var commit *git.Commit + if filePath == "" { + commit, err = wikiRepo.GetCommitByPath(entry.Name()) + } else { + commit, err = wikiRepo.GetCommitByPath(fmt.Sprintf("%s/%s", filePath, entry.Name())) + } if err != nil { ctx.Error(http.StatusInternalServerError, "GetCommit", err) return } - lists = append(lists, convert.DirToWikiPageMetaData(entry.Name(), c, ctx.Repo.Repository)) + lists = append(lists, convert.DirToWikiPageMetaData(entry.Name(), commit, ctx.Repo.Repository)) } } -- 2.34.1 From a69d22aa0f3727366626eddf05b4c2dd62eb541e Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 28 Jul 2022 13:55:50 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=8F=90=E4=BA=A4=E6=96=87=E4=BB=B6=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=8D=E8=BF=94=E5=9B=9E=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/repofiles/file.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/repofiles/file.go b/modules/repofiles/file.go index 7581552a4..0313d0430 100644 --- a/modules/repofiles/file.go +++ b/modules/repofiles/file.go @@ -24,6 +24,9 @@ func GetBatchFileResponseFromCommit(repo *models.Repository, commit *git.Commit, } for _, treeName := range treeNames { fileContent, _ := GetContents(repo, treeName, branch, false) + if fileContent == nil { + continue + } batchFileResponse.Contents = append(batchFileResponse.Contents, fileContent) } -- 2.34.1 From 66ed1b8f14c7509808cfa2dcd6ae5409a14dc428 Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 2 Aug 2022 18:59:48 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E7=89=88?= =?UTF-8?q?=E6=9C=ACdiff=E6=96=B0=E5=A2=9Ediff=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/git/repo_compare.go | 5 + services/gitdiff/gitdiff.go | 263 +++++++++++++++++++++++++++++++++++- 2 files changed, 267 insertions(+), 1 deletion(-) diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go index 3255e6839..32fdbc97e 100644 --- a/modules/git/repo_compare.go +++ b/modules/git/repo_compare.go @@ -217,6 +217,11 @@ func (repo *Repository) GetDiff(base, head string, w io.Writer) error { RunInDirPipeline(repo.Path, w, nil) } +func (repo *Repository) GetDiffStringByFilePath(base, head, filepath string) (string, error) { + return NewCommand("diff", "-p", base, head, "--", filepath). + RunInDir(repo.Path) +} + // GetPatch generates and returns format-patch data between given revisions. func (repo *Repository) GetPatch(base, head string, w io.Writer) error { stderr := new(bytes.Buffer) diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 687259efa..e55a02d53 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -593,6 +593,7 @@ type DiffFile struct { IsIncomplete bool IsIncompleteLineTooLong bool IsProtected bool + Diff string } // GetType returns type of diff file. @@ -936,6 +937,266 @@ parsingLoop: return diff, nil } +// ParsePatch builds a Diff object from a io.Reader and some parameters. +func ParsePatchWithGitRepo(maxLines, maxLineCharacters, maxFiles int, reader io.Reader, beforeCommitID, afterCommitID string, gitRepo *git.Repository) (*Diff, error) { + var curFile *DiffFile + + diff := &Diff{Files: make([]*DiffFile, 0)} + + sb := strings.Builder{} + + // OK let's set a reasonable buffer size. + // This should be let's say at least the size of maxLineCharacters or 4096 whichever is larger. + readerSize := maxLineCharacters + if readerSize < 4096 { + readerSize = 4096 + } + + input := bufio.NewReaderSize(reader, readerSize) + line, err := input.ReadString('\n') + if err != nil { + if err == io.EOF { + return diff, nil + } + return diff, err + } +parsingLoop: + for { + // 1. A patch file always begins with `diff --git ` + `a/path b/path` (possibly quoted) + // if it does not we have bad input! + if !strings.HasPrefix(line, cmdDiffHead) { + return diff, fmt.Errorf("Invalid first file line: %s", line) + } + + // TODO: Handle skipping first n files + if len(diff.Files) >= maxFiles { + diff.IsIncomplete = true + _, err := io.Copy(ioutil.Discard, reader) + if err != nil { + // By the definition of io.Copy this never returns io.EOF + return diff, fmt.Errorf("Copy: %v", err) + } + break parsingLoop + } + + curFile = createDiffFile(diff, line) + if diffString, err := gitRepo.GetDiffStringByFilePath(beforeCommitID, afterCommitID, curFile.Name); err == nil { + stringArray := strings.Split(diffString, "\n") + curFile.Diff = strings.Join(stringArray[5:len(stringArray)-2], "") + } + + diff.Files = append(diff.Files, curFile) + + // 2. It is followed by one or more extended header lines: + // + // old mode + // new mode + // deleted file mode + // new file mode + // copy from + // copy to + // rename from + // rename to + // similarity index + // dissimilarity index + // index .. + // + // * 6-digit octal numbers including the file type and file permission bits. + // * does not include the a/ and b/ prefixes + // * percentage of unchanged lines for similarity, percentage of changed + // lines dissimilarity as integer rounded down with terminal %. 100% => equal files. + // * The index line includes the blob object names before and after the change. + // The is included if the file mode does not change; otherwise, separate + // lines indicate the old and the new mode. + // 3. Following this header the "standard unified" diff format header may be encountered: (but not for every case...) + // + // --- a/ + // +++ b/ + // + // With multiple hunks + // + // @@ @@ + // +added line + // -removed line + // unchanged line + // + // 4. Binary files get: + // + // Binary files a/ and b/ differ + // + // but one of a/ and b/ could be /dev/null. + curFileLoop: + for { + line, err = input.ReadString('\n') + if err != nil { + if err != io.EOF { + return diff, err + } + break parsingLoop + } + fmt.Println(line) + switch { + case strings.HasPrefix(line, cmdDiffHead): + break curFileLoop + case strings.HasPrefix(line, "old mode ") || + strings.HasPrefix(line, "new mode "): + if strings.HasSuffix(line, " 160000\n") { + curFile.IsSubmodule = true + } + case strings.HasPrefix(line, "rename from "): + curFile.IsRenamed = true + curFile.Type = DiffFileRename + if curFile.IsAmbiguous { + curFile.OldName = line[len("rename from ") : len(line)-1] + } + case strings.HasPrefix(line, "rename to "): + curFile.IsRenamed = true + curFile.Type = DiffFileRename + if curFile.IsAmbiguous { + curFile.Name = line[len("rename to ") : len(line)-1] + curFile.IsAmbiguous = false + } + case strings.HasPrefix(line, "copy from "): + curFile.IsRenamed = true + curFile.Type = DiffFileCopy + if curFile.IsAmbiguous { + curFile.OldName = line[len("copy from ") : len(line)-1] + } + case strings.HasPrefix(line, "copy to "): + curFile.IsRenamed = true + curFile.Type = DiffFileCopy + if curFile.IsAmbiguous { + curFile.Name = line[len("copy to ") : len(line)-1] + curFile.IsAmbiguous = false + } + case strings.HasPrefix(line, "new file"): + curFile.Type = DiffFileAdd + curFile.IsCreated = true + if strings.HasSuffix(line, " 160000\n") { + curFile.IsSubmodule = true + } + case strings.HasPrefix(line, "deleted"): + curFile.Type = DiffFileDel + curFile.IsDeleted = true + if strings.HasSuffix(line, " 160000\n") { + curFile.IsSubmodule = true + } + case strings.HasPrefix(line, "index"): + if strings.HasSuffix(line, " 160000\n") { + curFile.IsSubmodule = true + } + case strings.HasPrefix(line, "similarity index 100%"): + curFile.Type = DiffFileRename + case strings.HasPrefix(line, "Binary"): + curFile.IsBin = true + case strings.HasPrefix(line, "--- "): + // Handle ambiguous filenames + if curFile.IsAmbiguous { + if len(line) > 6 && line[4] == 'a' { + curFile.OldName = line[6 : len(line)-1] + if line[len(line)-2] == '\t' { + curFile.OldName = curFile.OldName[:len(curFile.OldName)-1] + } + } else { + curFile.OldName = "" + } + } + // Otherwise do nothing with this line + case strings.HasPrefix(line, "+++ "): + // Handle ambiguous filenames + if curFile.IsAmbiguous { + if len(line) > 6 && line[4] == 'b' { + curFile.Name = line[6 : len(line)-1] + if line[len(line)-2] == '\t' { + curFile.Name = curFile.Name[:len(curFile.Name)-1] + } + if curFile.OldName == "" { + curFile.OldName = curFile.Name + } + } else { + curFile.Name = curFile.OldName + } + curFile.IsAmbiguous = false + } + // Otherwise do nothing with this line, but now switch to parsing hunks + lineBytes, isFragment, err := parseHunks(curFile, maxLines, maxLineCharacters, input) + diff.TotalAddition += curFile.Addition + diff.TotalDeletion += curFile.Deletion + if err != nil { + if err != io.EOF { + return diff, err + } + break parsingLoop + } + sb.Reset() + _, _ = sb.Write(lineBytes) + for isFragment { + lineBytes, isFragment, err = input.ReadLine() + if err != nil { + // Now by the definition of ReadLine this cannot be io.EOF + return diff, fmt.Errorf("Unable to ReadLine: %v", err) + } + _, _ = sb.Write(lineBytes) + } + line = sb.String() + sb.Reset() + + break curFileLoop + } + } + + } + + // TODO: There are numerous issues with this: + // - we might want to consider detecting encoding while parsing but... + // - we're likely to fail to get the correct encoding here anyway as we won't have enough information + var diffLineTypeBuffers = make(map[DiffLineType]*bytes.Buffer, 3) + var diffLineTypeDecoders = make(map[DiffLineType]*encoding.Decoder, 3) + diffLineTypeBuffers[DiffLinePlain] = new(bytes.Buffer) + diffLineTypeBuffers[DiffLineAdd] = new(bytes.Buffer) + diffLineTypeBuffers[DiffLineDel] = new(bytes.Buffer) + for _, f := range diff.Files { + for _, buffer := range diffLineTypeBuffers { + buffer.Reset() + } + for _, sec := range f.Sections { + for _, l := range sec.Lines { + if l.Type == DiffLineSection { + continue + } + diffLineTypeBuffers[l.Type].WriteString(l.Content[1:]) + diffLineTypeBuffers[l.Type].WriteString("\n") + } + } + for lineType, buffer := range diffLineTypeBuffers { + diffLineTypeDecoders[lineType] = nil + if buffer.Len() == 0 { + continue + } + charsetLabel, err := charset.DetectEncoding(buffer.Bytes()) + if charsetLabel != "UTF-8" && err == nil { + encoding, _ := stdcharset.Lookup(charsetLabel) + if encoding != nil { + diffLineTypeDecoders[lineType] = encoding.NewDecoder() + } + } + } + for _, sec := range f.Sections { + for _, l := range sec.Lines { + decoder := diffLineTypeDecoders[l.Type] + if decoder != nil { + if c, _, err := transform.String(decoder, l.Content[1:]); err == nil { + l.Content = l.Content[0:1] + c + } + } + } + } + } + + diff.NumFiles = len(diff.Files) + return diff, nil +} + func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio.Reader) (lineBytes []byte, isFragment bool, err error) { sb := strings.Builder{} @@ -1276,7 +1537,7 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID, pid := process.GetManager().Add(fmt.Sprintf("GetDiffRange [repo_path: %s]", repoPath), cancel) defer process.GetManager().Remove(pid) - diff, err := ParsePatch(maxLines, maxLineCharacters, maxFiles, stdout) + diff, err := ParsePatchWithGitRepo(maxLines, maxLineCharacters, maxFiles, stdout, beforeCommitID, afterCommitID, gitRepo) if err != nil { return nil, fmt.Errorf("ParsePatch: %v", err) } -- 2.34.1 From b128dae4bc1f2349f4ef8a5ca3cf4a02fd627a68 Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 2 Aug 2022 19:28:06 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E6=95=88=E7=8E=87=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routers/api/v1/repo/pull_version.go | 5 +++++ services/gitdiff/gitdiff.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/routers/api/v1/repo/pull_version.go b/routers/api/v1/repo/pull_version.go index bfe0083ff..093ba4f1a 100644 --- a/routers/api/v1/repo/pull_version.go +++ b/routers/api/v1/repo/pull_version.go @@ -3,6 +3,7 @@ package repo import ( "fmt" "net/http" + "strings" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" @@ -157,6 +158,10 @@ func GetPullRequestVersionDiff(ctx *context.APIContext) { var targetDiffFile *gitdiff.DiffFile for _, file := range diffs.Files { if file.Name == filepath { + if diffString, err := ctx.Repo.GitRepo.GetDiffStringByFilePath(prv.BaseCommitID, prv.HeadCommitID, file.Name); err == nil { + stringArray := strings.Split(diffString, "\n") + file.Diff = strings.Join(stringArray[5:len(stringArray)-2], "") + } targetDiffFile = file break } diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index e55a02d53..4b6318285 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -1537,7 +1537,7 @@ func GetDiffRangeWithWhitespaceBehavior(gitRepo *git.Repository, beforeCommitID, pid := process.GetManager().Add(fmt.Sprintf("GetDiffRange [repo_path: %s]", repoPath), cancel) defer process.GetManager().Remove(pid) - diff, err := ParsePatchWithGitRepo(maxLines, maxLineCharacters, maxFiles, stdout, beforeCommitID, afterCommitID, gitRepo) + diff, err := ParsePatch(maxLines, maxLineCharacters, maxFiles, stdout) if err != nil { return nil, fmt.Errorf("ParsePatch: %v", err) } -- 2.34.1 From 9d0fe5b008b0c2627537e032674e6af9c147a07d Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 2 Aug 2022 20:16:54 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8D:=20=E5=A4=84=E7=90=86d?= =?UTF-8?q?iff=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routers/api/v1/repo/pull_version.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/routers/api/v1/repo/pull_version.go b/routers/api/v1/repo/pull_version.go index 093ba4f1a..8088abfba 100644 --- a/routers/api/v1/repo/pull_version.go +++ b/routers/api/v1/repo/pull_version.go @@ -160,7 +160,27 @@ func GetPullRequestVersionDiff(ctx *context.APIContext) { if file.Name == filepath { if diffString, err := ctx.Repo.GitRepo.GetDiffStringByFilePath(prv.BaseCommitID, prv.HeadCommitID, file.Name); err == nil { stringArray := strings.Split(diffString, "\n") - file.Diff = strings.Join(stringArray[5:len(stringArray)-2], "") + for i, item := range stringArray { + switch { + case strings.HasPrefix(item, "diff --git"): + stringArray[i] = "" + case strings.HasPrefix(item, "index"): + stringArray[i] = "" + case strings.HasPrefix(item, "---"): + stringArray[i] = "" + case strings.HasPrefix(item, "+++"): + stringArray[i] = "" + case strings.HasPrefix(item, "new file mode"): + stringArray[i] = "" + case strings.HasPrefix(item, "deleted file mode"): + stringArray[i] = "" + case strings.HasSuffix(item, "No newline at end of file"): + stringArray[i] = "" + default: + continue + } + } + file.Diff = strings.Join(stringArray, "") } targetDiffFile = file break -- 2.34.1 From 5795a3f8d644a04bf0c8470db6c38ba1336f5eeb Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 3 Aug 2022 09:45:09 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9Anotfound?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routers/api/v1/repo/pull_version.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/routers/api/v1/repo/pull_version.go b/routers/api/v1/repo/pull_version.go index 8088abfba..e299d9aaf 100644 --- a/routers/api/v1/repo/pull_version.go +++ b/routers/api/v1/repo/pull_version.go @@ -186,7 +186,11 @@ func GetPullRequestVersionDiff(ctx *context.APIContext) { break } } - ctx.JSON(http.StatusOK, targetDiffFile) + if targetDiffFile == nil { + ctx.NotFound() + } else { + ctx.JSON(http.StatusOK, targetDiffFile) + } } } -- 2.34.1 From ef32b08ee424abee5b031eee31c4c7f52e7dcd51 Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 3 Aug 2022 10:40:19 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9Ajoin=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=94=A8=E6=8D=A2=E8=A1=8C=E7=AC=A6=E9=9A=94=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routers/api/v1/repo/pull_version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/v1/repo/pull_version.go b/routers/api/v1/repo/pull_version.go index e299d9aaf..8f0e9e21b 100644 --- a/routers/api/v1/repo/pull_version.go +++ b/routers/api/v1/repo/pull_version.go @@ -180,7 +180,7 @@ func GetPullRequestVersionDiff(ctx *context.APIContext) { continue } } - file.Diff = strings.Join(stringArray, "") + file.Diff = strings.Join(stringArray, "\n") } targetDiffFile = file break -- 2.34.1 From cf39a4b405534abb142a8c97f304284839f91bd5 Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 3 Aug 2022 14:21:07 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9Awebhook=20type?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/webhook.go | 1 + modules/structs/hook.go | 2 +- services/webhook/webhook.go | 8 +++++++- templates/swagger/v1_json.tmpl | 6 +++++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/models/webhook.go b/models/webhook.go index 4545fd0e1..34a2da13a 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -130,6 +130,7 @@ const ( MSTEAMS HookType = "msteams" FEISHU HookType = "feishu" MATRIX HookType = "matrix" + JIANMU HookType = "jianmu" ) // HookStatus is the status of a web hook diff --git a/modules/structs/hook.go b/modules/structs/hook.go index b985575ae..0d3818593 100644 --- a/modules/structs/hook.go +++ b/modules/structs/hook.go @@ -58,7 +58,7 @@ type CreateHookOptionConfig map[string]string // CreateHookOption options when create a hook type CreateHookOption struct { // required: true - // enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu + // enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,jianmu Type string `json:"type" binding:"Required"` // required: true Config CreateHookOptionConfig `json:"config" binding:"Required"` diff --git a/services/webhook/webhook.go b/services/webhook/webhook.go index d094a7754..ff9e8711b 100644 --- a/services/webhook/webhook.go +++ b/services/webhook/webhook.go @@ -65,6 +65,12 @@ func IsValidHookTaskType(name string) bool { if name == models.GITEA || name == models.GOGS { return true } + + // 建木devops + if name == models.JIANMU { + return true + } + _, ok := webhooks[models.HookType(name)] return ok } @@ -135,7 +141,7 @@ func prepareWebhook(w *models.Webhook, repo *models.Repository, event models.Hoo // Avoid sending "0 new commits" to non-integration relevant webhooks (e.g. slack, discord, etc.). // Integration webhooks (e.g. drone) still receive the required data. if pushEvent, ok := p.(*api.PushPayload); ok && - w.Type != models.GITEA && w.Type != models.GOGS && + w.Type != models.GITEA && w.Type != models.GOGS && w.Type != models.JIANMU && len(pushEvent.Commits) == 0 { return nil } diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 50a035cae..2966ecd4b 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -14615,7 +14615,8 @@ "msteams", "slack", "telegram", - "feishu" + "feishu", + "jianmu" ], "x-go-name": "Type" } @@ -15387,6 +15388,9 @@ "format": "int64", "x-go-name": "Deletion" }, + "Diff": { + "type": "string" + }, "Index": { "type": "integer", "format": "int64" -- 2.34.1 From e6022ba1420c5b7278412fe575fd6f0c0f336c06 Mon Sep 17 00:00:00 2001 From: yystopf Date: Mon, 8 Aug 2022 11:43:46 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9Areadme?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=8C=B9=E9=85=8D=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routers/api/v1/repo/file.go | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 301ab5a0a..bb7fe4666 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -761,8 +761,23 @@ func GetReadmeContents(ctx *context.APIContext) { // treePath := ctx.Params("*") ref := ctx.QueryTrim("ref") + var readmePath string + filesListInterface, _ := repofiles.GetContentsOrList(ctx, ctx.Repo.Repository, "", ref) + filesList, ok := filesListInterface.([]*api.ContentsResponse) + if ok { + for _, file := range filesList { + if strings.ToLower(file.Name) == "readme.md" { + readmePath = file.Name + } + if readmePath != "" { + break + } + } + } else { + readmePath = "README.md" + } - if fileList, err := repofiles.GetContentsOrList(ctx, ctx.Repo.Repository, "README.md", ref); err != nil { + if fileList, err := repofiles.GetContentsOrList(ctx, ctx.Repo.Repository, readmePath, ref); err != nil { if git.IsErrNotExist(err) { ctx.NotFound("GetContentsOrList", err) return @@ -816,7 +831,22 @@ func GetReadmeContentsByPath(ctx *context.APIContext) { treePath := ctx.Params("*") ref := ctx.QueryTrim("ref") - newTreePath := treePath + "/" + "README.md" + var readmePath string + filesListInterface, _ := repofiles.GetContentsOrList(ctx, ctx.Repo.Repository, treePath, ref) + filesList, ok := filesListInterface.([]*api.ContentsResponse) + if ok { + for _, file := range filesList { + if strings.ToLower(file.Name) == "readme.md" { + readmePath = file.Name + } + if readmePath != "" { + break + } + } + } else { + readmePath = "README.md" + } + newTreePath := treePath + "/" + readmePath if fileList, err := repofiles.GetContentsOrList(ctx, ctx.Repo.Repository, newTreePath, ref); err != nil { if git.IsErrNotExist(err) { ctx.NotFound("GetContentsOrList", err) -- 2.34.1 From db945157cded839c82c7bcf3171346a7651c9086 Mon Sep 17 00:00:00 2001 From: yystopf Date: Mon, 8 Aug 2022 11:48:02 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8D:=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=97=A0=E7=94=A8=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/gitdiff/gitdiff.go | 260 ------------------------------------ 1 file changed, 260 deletions(-) diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 4b6318285..0abfee5bb 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -937,266 +937,6 @@ parsingLoop: return diff, nil } -// ParsePatch builds a Diff object from a io.Reader and some parameters. -func ParsePatchWithGitRepo(maxLines, maxLineCharacters, maxFiles int, reader io.Reader, beforeCommitID, afterCommitID string, gitRepo *git.Repository) (*Diff, error) { - var curFile *DiffFile - - diff := &Diff{Files: make([]*DiffFile, 0)} - - sb := strings.Builder{} - - // OK let's set a reasonable buffer size. - // This should be let's say at least the size of maxLineCharacters or 4096 whichever is larger. - readerSize := maxLineCharacters - if readerSize < 4096 { - readerSize = 4096 - } - - input := bufio.NewReaderSize(reader, readerSize) - line, err := input.ReadString('\n') - if err != nil { - if err == io.EOF { - return diff, nil - } - return diff, err - } -parsingLoop: - for { - // 1. A patch file always begins with `diff --git ` + `a/path b/path` (possibly quoted) - // if it does not we have bad input! - if !strings.HasPrefix(line, cmdDiffHead) { - return diff, fmt.Errorf("Invalid first file line: %s", line) - } - - // TODO: Handle skipping first n files - if len(diff.Files) >= maxFiles { - diff.IsIncomplete = true - _, err := io.Copy(ioutil.Discard, reader) - if err != nil { - // By the definition of io.Copy this never returns io.EOF - return diff, fmt.Errorf("Copy: %v", err) - } - break parsingLoop - } - - curFile = createDiffFile(diff, line) - if diffString, err := gitRepo.GetDiffStringByFilePath(beforeCommitID, afterCommitID, curFile.Name); err == nil { - stringArray := strings.Split(diffString, "\n") - curFile.Diff = strings.Join(stringArray[5:len(stringArray)-2], "") - } - - diff.Files = append(diff.Files, curFile) - - // 2. It is followed by one or more extended header lines: - // - // old mode - // new mode - // deleted file mode - // new file mode - // copy from - // copy to - // rename from - // rename to - // similarity index - // dissimilarity index - // index .. - // - // * 6-digit octal numbers including the file type and file permission bits. - // * does not include the a/ and b/ prefixes - // * percentage of unchanged lines for similarity, percentage of changed - // lines dissimilarity as integer rounded down with terminal %. 100% => equal files. - // * The index line includes the blob object names before and after the change. - // The is included if the file mode does not change; otherwise, separate - // lines indicate the old and the new mode. - // 3. Following this header the "standard unified" diff format header may be encountered: (but not for every case...) - // - // --- a/ - // +++ b/ - // - // With multiple hunks - // - // @@ @@ - // +added line - // -removed line - // unchanged line - // - // 4. Binary files get: - // - // Binary files a/ and b/ differ - // - // but one of a/ and b/ could be /dev/null. - curFileLoop: - for { - line, err = input.ReadString('\n') - if err != nil { - if err != io.EOF { - return diff, err - } - break parsingLoop - } - fmt.Println(line) - switch { - case strings.HasPrefix(line, cmdDiffHead): - break curFileLoop - case strings.HasPrefix(line, "old mode ") || - strings.HasPrefix(line, "new mode "): - if strings.HasSuffix(line, " 160000\n") { - curFile.IsSubmodule = true - } - case strings.HasPrefix(line, "rename from "): - curFile.IsRenamed = true - curFile.Type = DiffFileRename - if curFile.IsAmbiguous { - curFile.OldName = line[len("rename from ") : len(line)-1] - } - case strings.HasPrefix(line, "rename to "): - curFile.IsRenamed = true - curFile.Type = DiffFileRename - if curFile.IsAmbiguous { - curFile.Name = line[len("rename to ") : len(line)-1] - curFile.IsAmbiguous = false - } - case strings.HasPrefix(line, "copy from "): - curFile.IsRenamed = true - curFile.Type = DiffFileCopy - if curFile.IsAmbiguous { - curFile.OldName = line[len("copy from ") : len(line)-1] - } - case strings.HasPrefix(line, "copy to "): - curFile.IsRenamed = true - curFile.Type = DiffFileCopy - if curFile.IsAmbiguous { - curFile.Name = line[len("copy to ") : len(line)-1] - curFile.IsAmbiguous = false - } - case strings.HasPrefix(line, "new file"): - curFile.Type = DiffFileAdd - curFile.IsCreated = true - if strings.HasSuffix(line, " 160000\n") { - curFile.IsSubmodule = true - } - case strings.HasPrefix(line, "deleted"): - curFile.Type = DiffFileDel - curFile.IsDeleted = true - if strings.HasSuffix(line, " 160000\n") { - curFile.IsSubmodule = true - } - case strings.HasPrefix(line, "index"): - if strings.HasSuffix(line, " 160000\n") { - curFile.IsSubmodule = true - } - case strings.HasPrefix(line, "similarity index 100%"): - curFile.Type = DiffFileRename - case strings.HasPrefix(line, "Binary"): - curFile.IsBin = true - case strings.HasPrefix(line, "--- "): - // Handle ambiguous filenames - if curFile.IsAmbiguous { - if len(line) > 6 && line[4] == 'a' { - curFile.OldName = line[6 : len(line)-1] - if line[len(line)-2] == '\t' { - curFile.OldName = curFile.OldName[:len(curFile.OldName)-1] - } - } else { - curFile.OldName = "" - } - } - // Otherwise do nothing with this line - case strings.HasPrefix(line, "+++ "): - // Handle ambiguous filenames - if curFile.IsAmbiguous { - if len(line) > 6 && line[4] == 'b' { - curFile.Name = line[6 : len(line)-1] - if line[len(line)-2] == '\t' { - curFile.Name = curFile.Name[:len(curFile.Name)-1] - } - if curFile.OldName == "" { - curFile.OldName = curFile.Name - } - } else { - curFile.Name = curFile.OldName - } - curFile.IsAmbiguous = false - } - // Otherwise do nothing with this line, but now switch to parsing hunks - lineBytes, isFragment, err := parseHunks(curFile, maxLines, maxLineCharacters, input) - diff.TotalAddition += curFile.Addition - diff.TotalDeletion += curFile.Deletion - if err != nil { - if err != io.EOF { - return diff, err - } - break parsingLoop - } - sb.Reset() - _, _ = sb.Write(lineBytes) - for isFragment { - lineBytes, isFragment, err = input.ReadLine() - if err != nil { - // Now by the definition of ReadLine this cannot be io.EOF - return diff, fmt.Errorf("Unable to ReadLine: %v", err) - } - _, _ = sb.Write(lineBytes) - } - line = sb.String() - sb.Reset() - - break curFileLoop - } - } - - } - - // TODO: There are numerous issues with this: - // - we might want to consider detecting encoding while parsing but... - // - we're likely to fail to get the correct encoding here anyway as we won't have enough information - var diffLineTypeBuffers = make(map[DiffLineType]*bytes.Buffer, 3) - var diffLineTypeDecoders = make(map[DiffLineType]*encoding.Decoder, 3) - diffLineTypeBuffers[DiffLinePlain] = new(bytes.Buffer) - diffLineTypeBuffers[DiffLineAdd] = new(bytes.Buffer) - diffLineTypeBuffers[DiffLineDel] = new(bytes.Buffer) - for _, f := range diff.Files { - for _, buffer := range diffLineTypeBuffers { - buffer.Reset() - } - for _, sec := range f.Sections { - for _, l := range sec.Lines { - if l.Type == DiffLineSection { - continue - } - diffLineTypeBuffers[l.Type].WriteString(l.Content[1:]) - diffLineTypeBuffers[l.Type].WriteString("\n") - } - } - for lineType, buffer := range diffLineTypeBuffers { - diffLineTypeDecoders[lineType] = nil - if buffer.Len() == 0 { - continue - } - charsetLabel, err := charset.DetectEncoding(buffer.Bytes()) - if charsetLabel != "UTF-8" && err == nil { - encoding, _ := stdcharset.Lookup(charsetLabel) - if encoding != nil { - diffLineTypeDecoders[lineType] = encoding.NewDecoder() - } - } - } - for _, sec := range f.Sections { - for _, l := range sec.Lines { - decoder := diffLineTypeDecoders[l.Type] - if decoder != nil { - if c, _, err := transform.String(decoder, l.Content[1:]); err == nil { - l.Content = l.Content[0:1] + c - } - } - } - } - } - - diff.NumFiles = len(diff.Files) - return diff, nil -} - func parseHunks(curFile *DiffFile, maxLines, maxLineCharacters int, input *bufio.Reader) (lineBytes []byte, isFragment bool, err error) { sb := strings.Builder{} -- 2.34.1