|
6 | 6 | "errors" |
7 | 7 | "fmt" |
8 | 8 | "io" |
9 | | - "math" |
| 9 | + "strconv" |
10 | 10 | "strings" |
11 | 11 |
|
12 | 12 | "github.com/go-git/go-git/v5/plumbing" |
@@ -234,69 +234,56 @@ func (fileStats FileStats) String() string { |
234 | 234 | return printStat(fileStats) |
235 | 235 | } |
236 | 236 |
|
| 237 | +// printStat prints the stats of changes in content of files. |
| 238 | +// Original implementation: https://github.com/git/git/blob/1a87c842ece327d03d08096395969aca5e0a6996/diff.c#L2615 |
| 239 | +// Parts of the output: |
| 240 | +// <pad><filename><pad>|<pad><changeNumber><pad><+++/---><newline> |
| 241 | +// example: " main.go | 10 +++++++--- " |
237 | 242 | func printStat(fileStats []FileStat) string { |
238 | | - padLength := float64(len(" ")) |
239 | | - newlineLength := float64(len("\n")) |
240 | | - separatorLength := float64(len("|")) |
241 | | - // Soft line length limit. The text length calculation below excludes |
242 | | - // length of the change number. Adding that would take it closer to 80, |
243 | | - // but probably not more than 80, until it's a huge number. |
244 | | - lineLength := 72.0 |
245 | | - |
246 | | - // Get the longest filename and longest total change. |
247 | | - var longestLength float64 |
248 | | - var longestTotalChange float64 |
249 | | - for _, fs := range fileStats { |
250 | | - if int(longestLength) < len(fs.Name) { |
251 | | - longestLength = float64(len(fs.Name)) |
252 | | - } |
253 | | - totalChange := fs.Addition + fs.Deletion |
254 | | - if int(longestTotalChange) < totalChange { |
255 | | - longestTotalChange = float64(totalChange) |
256 | | - } |
257 | | - } |
258 | | - |
259 | | - // Parts of the output: |
260 | | - // <pad><filename><pad>|<pad><changeNumber><pad><+++/---><newline> |
261 | | - // example: " main.go | 10 +++++++--- " |
262 | | - |
263 | | - // <pad><filename><pad> |
264 | | - leftTextLength := padLength + longestLength + padLength |
265 | | - |
266 | | - // <pad><number><pad><+++++/-----><newline> |
267 | | - // Excluding number length here. |
268 | | - rightTextLength := padLength + padLength + newlineLength |
| 243 | + maxGraphWidth := uint(53) |
| 244 | + maxNameLen := 0 |
| 245 | + maxChangeLen := 0 |
269 | 246 |
|
270 | | - totalTextArea := leftTextLength + separatorLength + rightTextLength |
271 | | - heightOfHistogram := lineLength - totalTextArea |
| 247 | + scaleLinear := func(it, width, max uint) uint { |
| 248 | + if it == 0 || max == 0 { |
| 249 | + return 0 |
| 250 | + } |
272 | 251 |
|
273 | | - // Scale the histogram. |
274 | | - var scaleFactor float64 |
275 | | - if longestTotalChange > heightOfHistogram { |
276 | | - // Scale down to heightOfHistogram. |
277 | | - scaleFactor = longestTotalChange / heightOfHistogram |
278 | | - } else { |
279 | | - scaleFactor = 1.0 |
| 252 | + return 1 + (it * (width - 1) / max) |
280 | 253 | } |
281 | 254 |
|
282 | | - finalOutput := "" |
283 | 255 | for _, fs := range fileStats { |
284 | | - addn := float64(fs.Addition) |
285 | | - deln := float64(fs.Deletion) |
286 | | - addc := int(math.Floor(addn/scaleFactor)) |
287 | | - delc := int(math.Floor(deln/scaleFactor)) |
288 | | - if addc < 0 { |
289 | | - addc = 0 |
| 256 | + if len(fs.Name) > maxNameLen { |
| 257 | + maxNameLen = len(fs.Name) |
290 | 258 | } |
291 | | - if delc < 0 { |
292 | | - delc = 0 |
| 259 | + |
| 260 | + changes := strconv.Itoa(fs.Addition + fs.Deletion) |
| 261 | + if len(changes) > maxChangeLen { |
| 262 | + maxChangeLen = len(changes) |
293 | 263 | } |
294 | | - adds := strings.Repeat("+", addc) |
295 | | - dels := strings.Repeat("-", delc) |
296 | | - finalOutput += fmt.Sprintf(" %s | %d %s%s\n", fs.Name, (fs.Addition + fs.Deletion), adds, dels) |
297 | 264 | } |
298 | 265 |
|
299 | | - return finalOutput |
| 266 | + result := "" |
| 267 | + for _, fs := range fileStats { |
| 268 | + add := uint(fs.Addition) |
| 269 | + del := uint(fs.Deletion) |
| 270 | + np := maxNameLen - len(fs.Name) |
| 271 | + cp := maxChangeLen - len(strconv.Itoa(fs.Addition+fs.Deletion)) |
| 272 | + |
| 273 | + total := add + del |
| 274 | + if total > maxGraphWidth { |
| 275 | + add = scaleLinear(add, maxGraphWidth, total) |
| 276 | + del = scaleLinear(del, maxGraphWidth, total) |
| 277 | + } |
| 278 | + |
| 279 | + adds := strings.Repeat("+", int(add)) |
| 280 | + dels := strings.Repeat("-", int(del)) |
| 281 | + namePad := strings.Repeat(" ", np) |
| 282 | + changePad := strings.Repeat(" ", cp) |
| 283 | + |
| 284 | + result += fmt.Sprintf(" %s%s | %s%d %s%s\n", fs.Name, namePad, changePad, total, adds, dels) |
| 285 | + } |
| 286 | + return result |
300 | 287 | } |
301 | 288 |
|
302 | 289 | func getFileStatsFromFilePatches(filePatches []fdiff.FilePatch) FileStats { |
|
0 commit comments