Skip to content

Commit 8d5c3e6

Browse files
committed
feat: add differ
Signed-off-by: Zxilly <[email protected]>
1 parent e7bbaff commit 8d5c3e6

File tree

3 files changed

+161
-0
lines changed

3 files changed

+161
-0
lines changed

internal/diff/diff.go

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,153 @@
11
package diff
2+
3+
import (
4+
"cmp"
5+
"slices"
6+
)
7+
8+
type diffResult struct {
9+
Size int64 `json:"size"`
10+
Packages []diffPackage `json:"packages"`
11+
Sections []diffSection `json:"sections"`
12+
}
13+
14+
type changeType string
15+
16+
const (
17+
changeTypeAdd changeType = "add"
18+
changeTypeRemove changeType = "remove"
19+
changeTypeChange changeType = "change"
20+
)
21+
22+
type diffBase struct {
23+
Name string `json:"name"`
24+
From int64 `json:"from"`
25+
To int64 `json:"to"`
26+
ChangeType changeType `json:"change_type"`
27+
}
28+
29+
func diffBaseCmp(a, b diffBase) int {
30+
return -cmp.Compare(a.To-a.From, b.To-b.From)
31+
}
32+
33+
type diffPackage struct {
34+
diffBase
35+
}
36+
37+
type diffSection struct {
38+
diffBase
39+
oldFileSize int64
40+
oldKnownSize int64
41+
newFileSize int64
42+
newKnownSize int64
43+
}
44+
45+
func newDiffResult(newResult, oldResult *commonResult) diffResult {
46+
ret := diffResult{
47+
Packages: make([]diffPackage, 0),
48+
Sections: make([]diffSection, 0),
49+
}
50+
51+
// diff packages
52+
for k, v := range newResult.Packages {
53+
if oldV, ok := oldResult.Packages[k]; ok {
54+
if v.Size != oldV.Size {
55+
ret.Packages = append(ret.Packages, diffPackage{
56+
diffBase: diffBase{
57+
Name: k,
58+
From: oldV.Size,
59+
To: v.Size,
60+
ChangeType: changeTypeChange,
61+
},
62+
})
63+
}
64+
} else {
65+
ret.Packages = append(ret.Packages, diffPackage{
66+
diffBase: diffBase{
67+
Name: k,
68+
From: 0,
69+
To: v.Size,
70+
ChangeType: changeTypeAdd,
71+
},
72+
})
73+
}
74+
}
75+
76+
for k, v := range oldResult.Packages {
77+
if _, ok := newResult.Packages[k]; !ok {
78+
ret.Packages = append(ret.Packages, diffPackage{
79+
diffBase: diffBase{
80+
Name: k,
81+
From: v.Size,
82+
To: 0,
83+
ChangeType: changeTypeRemove,
84+
},
85+
})
86+
}
87+
}
88+
89+
// diff sections
90+
newSections := make(map[string]commonSection)
91+
oldSections := make(map[string]commonSection)
92+
93+
for _, v := range newResult.Sections {
94+
newSections[v.Name] = v
95+
}
96+
for _, v := range oldResult.Sections {
97+
oldSections[v.Name] = v
98+
}
99+
100+
for k, v := range newSections {
101+
if oldV, ok := oldSections[k]; ok {
102+
if v.UnknownSize() != oldV.UnknownSize() {
103+
ret.Sections = append(ret.Sections, diffSection{
104+
diffBase: diffBase{
105+
Name: k,
106+
From: oldV.FileSize,
107+
To: v.FileSize,
108+
ChangeType: changeTypeChange,
109+
},
110+
oldFileSize: oldV.FileSize,
111+
oldKnownSize: oldV.KnownSize,
112+
newFileSize: v.FileSize,
113+
newKnownSize: v.KnownSize,
114+
})
115+
}
116+
} else {
117+
ret.Sections = append(ret.Sections, diffSection{
118+
diffBase: diffBase{
119+
Name: k,
120+
From: 0,
121+
To: v.FileSize,
122+
ChangeType: changeTypeAdd,
123+
},
124+
newFileSize: v.FileSize,
125+
newKnownSize: v.KnownSize,
126+
})
127+
}
128+
}
129+
130+
for k, v := range oldSections {
131+
if _, ok := newSections[k]; !ok {
132+
ret.Sections = append(ret.Sections, diffSection{
133+
diffBase: diffBase{
134+
Name: k,
135+
From: v.FileSize,
136+
To: 0,
137+
ChangeType: changeTypeRemove,
138+
},
139+
oldFileSize: v.FileSize,
140+
oldKnownSize: v.KnownSize,
141+
})
142+
}
143+
}
144+
145+
slices.SortFunc(ret.Packages, func(a, b diffPackage) int {
146+
return diffBaseCmp(a.diffBase, b.diffBase)
147+
})
148+
slices.SortFunc(ret.Sections, func(a, b diffSection) int {
149+
return diffBaseCmp(a.diffBase, b.diffBase)
150+
})
151+
152+
return ret
153+
}

internal/diff/load.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ func Diff(oldTarget, newTarget string, options internal.Options) error {
3939
return errors.New("analyze mode is different")
4040
}
4141

42+
diff := newDiffResult(newResult, oldResult)
43+
44+
// todo: add json printer and text printer
45+
_ = diff
46+
4247
return nil
4348
}
4449

internal/diff/result.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ type commonSection struct {
2525
KnownSize int64 `json:"known_size"`
2626
}
2727

28+
func (c commonSection) UnknownSize() int64 {
29+
return c.FileSize - c.KnownSize
30+
}
31+
2832
func fromResult(r *result.Result) *commonResult {
2933
c := commonResult{
3034
Size: int64(r.Size),

0 commit comments

Comments
 (0)