1package types
2
3import (
4 "net/url"
5
6 "github.com/bluekeyes/go-gitdiff/gitdiff"
7 "tangled.org/core/appview/filetree"
8)
9
10type DiffOpts struct {
11 Split bool `json:"split"`
12}
13
14func (d DiffOpts) Encode() string {
15 values := make(url.Values)
16 if d.Split {
17 values.Set("diff", "split")
18 } else {
19 values.Set("diff", "unified")
20 }
21 return values.Encode()
22}
23
24// A nicer git diff representation.
25type NiceDiff struct {
26 Commit Commit `json:"commit"`
27 Stat DiffStat `json:"stat"`
28 Diff []Diff `json:"diff"`
29}
30
31type Diff struct {
32 Name struct {
33 Old string `json:"old"`
34 New string `json:"new"`
35 } `json:"name"`
36 TextFragments []gitdiff.TextFragment `json:"text_fragments"`
37 IsBinary bool `json:"is_binary"`
38 IsNew bool `json:"is_new"`
39 IsDelete bool `json:"is_delete"`
40 IsCopy bool `json:"is_copy"`
41 IsRename bool `json:"is_rename"`
42}
43
44func (d Diff) Stats() DiffFileStat {
45 var stats DiffFileStat
46 for _, f := range d.TextFragments {
47 stats.Insertions += f.LinesAdded
48 stats.Deletions += f.LinesDeleted
49 }
50 return stats
51}
52
53type DiffStat struct {
54 Insertions int64 `json:"insertions"`
55 Deletions int64 `json:"deletions"`
56 FilesChanged int `json:"files_changed"`
57}
58
59type DiffFileStat struct {
60 Insertions int64
61 Deletions int64
62}
63
64type DiffTree struct {
65 Rev1 string `json:"rev1"`
66 Rev2 string `json:"rev2"`
67 Patch string `json:"patch"`
68 Diff []*gitdiff.File `json:"diff"`
69}
70
71type DiffFileName struct {
72 Old string
73 New string
74}
75
76func (d NiceDiff) ChangedFiles() []DiffFileRenderer {
77 drs := make([]DiffFileRenderer, len(d.Diff))
78 for i, s := range d.Diff {
79 drs[i] = s
80 }
81 return drs
82}
83
84func (d NiceDiff) FileTree() *filetree.FileTreeNode {
85 fs := make([]string, len(d.Diff))
86 for i, s := range d.Diff {
87 n := s.Names()
88 if n.New == "" {
89 fs[i] = n.Old
90 } else {
91 fs[i] = n.New
92 }
93 }
94 return filetree.FileTree(fs)
95}
96
97func (d NiceDiff) Stats() DiffStat {
98 return d.Stat
99}
100
101func (d Diff) Id() string {
102 if d.IsDelete {
103 return d.Name.Old
104 }
105 return d.Name.New
106}
107
108func (d Diff) Names() DiffFileName {
109 var n DiffFileName
110 if d.IsDelete {
111 n.Old = d.Name.Old
112 return n
113 } else if d.IsCopy || d.IsRename {
114 n.Old = d.Name.Old
115 n.New = d.Name.New
116 return n
117 } else {
118 n.New = d.Name.New
119 return n
120 }
121}
122
123func (d Diff) CanRender() string {
124 if d.IsBinary {
125 return "This is a binary file and will not be displayed."
126 }
127
128 return ""
129}
130
131func (d Diff) Split() SplitDiff {
132 fragments := make([]SplitFragment, len(d.TextFragments))
133 for i, fragment := range d.TextFragments {
134 leftLines, rightLines := SeparateLines(&fragment)
135 fragments[i] = SplitFragment{
136 Header: fragment.Header(),
137 LeftLines: leftLines,
138 RightLines: rightLines,
139 }
140 }
141
142 return SplitDiff{
143 Name: d.Id(),
144 TextFragments: fragments,
145 }
146}