forked from tangled.org/core
this repo has no description

patchutil: move AsDiff and AsNiceDiff to patchutil

Also move FormatPatch to types to avoid an import cycle.

Changed files
+114 -104
appview
knotserver
git
patchutil
types
+2 -69
appview/db/pulls.go
···
"strings"
"time"
-
"github.com/bluekeyes/go-gitdiff/gitdiff"
"github.com/bluesky-social/indigo/atproto/syntax"
"tangled.sh/tangled.sh/core/api/tangled"
"tangled.sh/tangled.sh/core/patchutil"
···
return p.StackId != ""
}
-
func (s PullSubmission) AsDiff(targetBranch string) ([]*gitdiff.File, error) {
-
patch := s.Patch
-
-
// if format-patch; then extract each patch
-
var diffs []*gitdiff.File
-
if patchutil.IsFormatPatch(patch) {
-
patches, err := patchutil.ExtractPatches(patch)
-
if err != nil {
-
return nil, err
-
}
-
var ps [][]*gitdiff.File
-
for _, p := range patches {
-
ps = append(ps, p.Files)
-
}
-
-
diffs = patchutil.CombineDiff(ps...)
-
} else {
-
d, _, err := gitdiff.Parse(strings.NewReader(patch))
-
if err != nil {
-
return nil, err
-
}
-
diffs = d
-
}
-
-
return diffs, nil
-
}
-
-
func (s PullSubmission) AsNiceDiff(targetBranch string) types.NiceDiff {
-
diffs, err := s.AsDiff(targetBranch)
-
if err != nil {
-
log.Println(err)
-
}
-
-
nd := types.NiceDiff{}
-
nd.Commit.Parent = targetBranch
-
-
for _, d := range diffs {
-
ndiff := types.Diff{}
-
ndiff.Name.New = d.NewName
-
ndiff.Name.Old = d.OldName
-
ndiff.IsBinary = d.IsBinary
-
ndiff.IsNew = d.IsNew
-
ndiff.IsDelete = d.IsDelete
-
ndiff.IsCopy = d.IsCopy
-
ndiff.IsRename = d.IsRename
-
-
for _, tf := range d.TextFragments {
-
ndiff.TextFragments = append(ndiff.TextFragments, *tf)
-
for _, l := range tf.Lines {
-
switch l.Op {
-
case gitdiff.OpAdd:
-
nd.Stat.Insertions += 1
-
case gitdiff.OpDelete:
-
nd.Stat.Deletions += 1
-
}
-
}
-
}
-
-
nd.Diff = append(nd.Diff, ndiff)
-
}
-
-
nd.Stat.FilesChanged = len(diffs)
-
-
return nd
-
}
-
func (s PullSubmission) IsFormatPatch() bool {
return patchutil.IsFormatPatch(s.Patch)
}
-
func (s PullSubmission) AsFormatPatch() []patchutil.FormatPatch {
+
func (s PullSubmission) AsFormatPatch() []types.FormatPatch {
patches, err := patchutil.ExtractPatches(s.Patch)
if err != nil {
log.Println("error extracting patches from submission:", err)
-
return []patchutil.FormatPatch{}
+
return []types.FormatPatch{}
}
return patches
+6 -5
appview/state/pull.go
···
}
}
-
diff := pull.Submissions[roundIdInt].AsNiceDiff(pull.TargetBranch)
+
patch := pull.Submissions[roundIdInt].Patch
+
diff := patchutil.AsNiceDiff(patch, pull.TargetBranch)
s.pages.RepoPullPatchPage(w, pages.RepoPullPatchParams{
LoggedInUser: user,
···
}
}
-
currentPatch, err := pull.Submissions[roundIdInt].AsDiff(pull.TargetBranch)
+
currentPatch, err := patchutil.AsDiff(pull.Submissions[roundIdInt].Patch)
if err != nil {
log.Println("failed to interdiff; current patch malformed")
s.pages.Notice(w, fmt.Sprintf("interdiff-error-%d", roundIdInt), "Failed to calculate interdiff; current patch is invalid.")
return
}
-
previousPatch, err := pull.Submissions[roundIdInt-1].AsDiff(pull.TargetBranch)
+
previousPatch, err := patchutil.AsDiff(pull.Submissions[roundIdInt-1].Patch)
if err != nil {
log.Println("failed to interdiff; previous patch malformed")
s.pages.Notice(w, fmt.Sprintf("interdiff-error-%d", roundIdInt), "Failed to calculate interdiff; previous patch is invalid.")
···
return
-
branches := result.Branches
+
branches := result.Branches
sort.Slice(branches, func(i int, j int) bool {
return branches[i].Commit.Committer.When.After(branches[j].Commit.Committer.When)
})
···
s.pages.PullCompareForkBranchesFragment(w, pages.PullCompareForkBranchesParams{
RepoInfo: f.RepoInfo(s, user),
-
SourceBranches: sourceResult.Branches,
+
SourceBranches: sourceBranches,
TargetBranches: targetResult.Branches,
})
+9 -5
appview/state/repo.go
···
return
-
forks, err := db.GetForksByDid(s.db, user.Did)
-
if err != nil {
-
s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
-
log.Println("failed to get forks", err)
-
return
+
var forks []db.Repo
+
if user != nil {
+
var err error
+
forks, err = db.GetForksByDid(s.db, user.Did)
+
if err != nil {
+
s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
+
log.Println("failed to get forks", err)
+
return
+
}
s.pages.RepoCompare(w, pages.RepoCompareParams{
+3 -3
knotserver/git/diff.go
···
// FormatPatch generates a git-format-patch output between two commits,
// and returns the raw format-patch series, a parsed FormatPatch and an error.
-
func (g *GitRepo) formatSinglePatch(base, commit2 plumbing.Hash, extraArgs ...string) (string, *patchutil.FormatPatch, error) {
+
func (g *GitRepo) formatSinglePatch(base, commit2 plumbing.Hash, extraArgs ...string) (string, *types.FormatPatch, error) {
var stdout bytes.Buffer
args := []string{
···
return commits, nil
}
-
func (g *GitRepo) FormatPatch(base, commit2 *object.Commit) (string, []patchutil.FormatPatch, error) {
+
func (g *GitRepo) FormatPatch(base, commit2 *object.Commit) (string, []types.FormatPatch, error) {
// get list of commits between commir2 and base
commits, err := g.commitsBetween(commit2, base)
if err != nil {
···
slices.Reverse(commits)
var allPatchesContent strings.Builder
-
var allPatches []patchutil.FormatPatch
+
var allPatches []types.FormatPatch
for _, commit := range commits {
changeId := ""
+69 -16
patchutil/patchutil.go
···
import (
"fmt"
+
"log"
"os"
"os/exec"
"regexp"
···
"strings"
"github.com/bluekeyes/go-gitdiff/gitdiff"
+
"tangled.sh/tangled.sh/core/types"
)
-
type FormatPatch struct {
-
Files []*gitdiff.File
-
*gitdiff.PatchHeader
-
Raw string
-
}
-
-
func (f FormatPatch) ChangeId() (string, error) {
-
if vals, ok := f.RawHeaders["Change-Id"]; ok && len(vals) == 1 {
-
return vals[0], nil
-
}
-
return "", fmt.Errorf("no change-id found")
-
}
-
-
func ExtractPatches(formatPatch string) ([]FormatPatch, error) {
+
func ExtractPatches(formatPatch string) ([]types.FormatPatch, error) {
patches := splitFormatPatch(formatPatch)
-
result := []FormatPatch{}
+
result := []types.FormatPatch{}
for _, patch := range patches {
files, headerStr, err := gitdiff.Parse(strings.NewReader(patch))
···
return nil, fmt.Errorf("failed to parse patch header: %w", err)
}
-
result = append(result, FormatPatch{
+
result = append(result, types.FormatPatch{
Files: files,
PatchHeader: header,
Raw: patch,
···
return strings.Compare(bestName(a), bestName(b))
})
}
+
+
func AsDiff(patch string) ([]*gitdiff.File, error) {
+
// if format-patch; then extract each patch
+
var diffs []*gitdiff.File
+
if IsFormatPatch(patch) {
+
patches, err := ExtractPatches(patch)
+
if err != nil {
+
return nil, err
+
}
+
var ps [][]*gitdiff.File
+
for _, p := range patches {
+
ps = append(ps, p.Files)
+
}
+
+
diffs = CombineDiff(ps...)
+
} else {
+
d, _, err := gitdiff.Parse(strings.NewReader(patch))
+
if err != nil {
+
return nil, err
+
}
+
diffs = d
+
}
+
+
return diffs, nil
+
}
+
+
func AsNiceDiff(patch, targetBranch string) types.NiceDiff {
+
diffs, err := AsDiff(patch)
+
if err != nil {
+
log.Println(err)
+
}
+
+
nd := types.NiceDiff{}
+
nd.Commit.Parent = targetBranch
+
+
for _, d := range diffs {
+
ndiff := types.Diff{}
+
ndiff.Name.New = d.NewName
+
ndiff.Name.Old = d.OldName
+
ndiff.IsBinary = d.IsBinary
+
ndiff.IsNew = d.IsNew
+
ndiff.IsDelete = d.IsDelete
+
ndiff.IsCopy = d.IsCopy
+
ndiff.IsRename = d.IsRename
+
+
for _, tf := range d.TextFragments {
+
ndiff.TextFragments = append(ndiff.TextFragments, *tf)
+
for _, l := range tf.Lines {
+
switch l.Op {
+
case gitdiff.OpAdd:
+
nd.Stat.Insertions += 1
+
case gitdiff.OpDelete:
+
nd.Stat.Deletions += 1
+
}
+
}
+
}
+
+
nd.Diff = append(nd.Diff, ndiff)
+
}
+
+
nd.Stat.FilesChanged = len(diffs)
+
+
return nd
+
}
+20
types/patch.go
···
+
package types
+
+
import (
+
"fmt"
+
+
"github.com/bluekeyes/go-gitdiff/gitdiff"
+
)
+
+
type FormatPatch struct {
+
Files []*gitdiff.File
+
*gitdiff.PatchHeader
+
Raw string
+
}
+
+
func (f FormatPatch) ChangeId() (string, error) {
+
if vals, ok := f.RawHeaders["Change-Id"]; ok && len(vals) == 1 {
+
return vals[0], nil
+
}
+
return "", fmt.Errorf("no change-id found")
+
}
+5 -6
types/repo.go
···
import (
"github.com/go-git/go-git/v5/plumbing/object"
-
"tangled.sh/tangled.sh/core/patchutil"
)
type RepoIndexResponse struct {
···
}
type RepoFormatPatchResponse struct {
-
Rev1 string `json:"rev1,omitempty"`
-
Rev2 string `json:"rev2,omitempty"`
-
FormatPatch []patchutil.FormatPatch `json:"format_patch,omitempty"`
-
MergeBase string `json:"merge_base,omitempty"`
-
Patch string `json:"patch,omitempty"`
+
Rev1 string `json:"rev1,omitempty"`
+
Rev2 string `json:"rev2,omitempty"`
+
FormatPatch []FormatPatch `json:"format_patch,omitempty"`
+
MergeBase string `json:"merge_base,omitempty"`
+
Patch string `json:"patch,omitempty"`
}
type RepoTreeResponse struct {