dmitri.shuralyov.com/service/change/...

gerritapi: Begin ListCommitsOptions support in GetDiff.
dmitshur committed 2 years ago commit c9b447fb9de9befc9975c615ed5a1e0cdd6408ca
gerritapi/gerritapi.go
@@ -164,17 +164,103 @@ func (s service) ListCommits(ctx context.Context, _ string, id uint64, opt *chan
 		}}, nil
 	}
 }
 
 func (s service) GetDiff(ctx context.Context, _ string, id uint64, opt *changes.ListCommitsOptions) ([]byte, error) {
-	diff, _, err := s.cl.Changes.GetPatch(fmt.Sprint(id), "current", &gerrit.PatchOptions{
-		Path: "src", // TODO.
-	})
-	if err != nil {
-		return nil, err
+	switch opt {
+	case nil:
+		diff, _, err := s.cl.Changes.GetPatch(fmt.Sprint(id), "current", &gerrit.PatchOptions{
+			Path: "src", // TODO.
+		})
+		if err != nil {
+			return nil, err
+		}
+		return []byte(*diff), nil
+	default:
+		change, _, err := s.cl.Changes.GetChange(fmt.Sprint(id), &gerrit.ChangeOptions{
+			AdditionalFields: []string{"ALL_REVISIONS"},
+		})
+		if err != nil {
+			return nil, err
+		}
+		if change.Status == "DRAFT" {
+			return nil, os.ErrNotExist
+		}
+		r, ok := change.Revisions[opt.Commit]
+		if !ok {
+			return nil, os.ErrNotExist
+		}
+		var base string
+		switch r.Number {
+		case 1:
+			base = ""
+		default:
+			base = fmt.Sprint(r.Number - 1)
+		}
+		files, _, err := s.cl.Changes.ListFiles(fmt.Sprint(id), opt.Commit, &gerrit.FilesOptions{
+			Base: base,
+		})
+		if err != nil {
+			return nil, err
+		}
+		var sortedFiles []string
+		for file := range *files {
+			sortedFiles = append(sortedFiles, file)
+		}
+		sort.Strings(sortedFiles)
+		var diff string
+		for _, file := range sortedFiles {
+			diffInfo, _, err := s.cl.Changes.GetDiff(fmt.Sprint(id), opt.Commit, file, &gerrit.DiffOptions{
+				Base:    base,
+				Context: "5",
+			})
+			if err != nil {
+				return nil, err
+			}
+			diff += strings.Join(diffInfo.DiffHeader, "\n") + "\n"
+			for i, c := range diffInfo.Content {
+				if i == 0 {
+					diff += "@@ -154,6 +154,7 @@\n" // TODO.
+				}
+				switch {
+				case len(c.AB) > 0:
+					if len(c.AB) <= 10 {
+						for _, line := range c.AB {
+							diff += " " + line + "\n"
+						}
+					} else {
+						switch i {
+						case 0:
+							for _, line := range c.AB[len(c.AB)-5:] {
+								diff += " " + line + "\n"
+							}
+						default:
+							for _, line := range c.AB[:5] {
+								diff += " " + line + "\n"
+							}
+							diff += "@@ -154,6 +154,7 @@\n" // TODO.
+							for _, line := range c.AB[len(c.AB)-5:] {
+								diff += " " + line + "\n"
+							}
+						case len(diffInfo.Content) - 1:
+							for _, line := range c.AB[:5] {
+								diff += " " + line + "\n"
+							}
+						}
+					}
+				case len(c.A) > 0 || len(c.B) > 0:
+					for _, line := range c.A {
+						diff += "-" + line + "\n"
+					}
+					for _, line := range c.B {
+						diff += "+" + line + "\n"
+					}
+				}
+			}
+		}
+		return []byte(diff), nil
 	}
-	return []byte(*diff), nil
 }
 
 func (s service) ListComments(ctx context.Context, _ string, id uint64, opt *changes.ListCommentsOptions) ([]issues.Comment, error) {
 	// TODO: Pagination. Respect opt.Start and opt.Length, if given.