Skip to content

Commit 67f3d61

Browse files
committed
Make the JSON output more comprehensive
Instead of just a jumble of values, structure the JSON output as a map from a symbol name to a structure containing * A prose description of the quantity * The quantity's value * The quantity's units * The prefixes that should be use along with the units ("metric" or "binary") * The "reference value" against which the actual value is compared to determine the level of concern * The level of concern, as a floating-point number * The OID and description of the Git object in question (when applicable)
1 parent ee87869 commit 67f3d61

File tree

3 files changed

+142
-40
lines changed

3 files changed

+142
-40
lines changed

counts/human.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ var Binary = Humaner{
4646
},
4747
}
4848

49+
func (h *Humaner) Name() string {
50+
return h.name
51+
}
52+
4953
// Format n, aligned, in `len(unit) + 10` or fewer characters (except
5054
// for extremely large numbers).
5155
func (h *Humaner) FormatNumber(n uint64, unit string) (string, string) {

git-sizer.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package main
22

33
import (
4-
"encoding/json"
54
"errors"
65
"fmt"
76
"io"
@@ -167,11 +166,11 @@ func mainImplementation() error {
167166
}
168167

169168
if jsonOutput {
170-
s, err := json.MarshalIndent(historySize, "", " ")
169+
j, err := sizes.JSONString(historySize.Contents(), threshold, nameStyle)
171170
if err != nil {
172171
return fmt.Errorf("could not convert %v to json: %s", historySize, err)
173172
}
174-
fmt.Printf("%s\n", s)
173+
fmt.Printf("%s\n", j)
175174
} else {
176175
io.WriteString(os.Stdout, sizes.TableString(historySize.Contents(), threshold, nameStyle))
177176
}

sizes/output.go

Lines changed: 136 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package sizes
22

33
import (
44
"bytes"
5+
"encoding/json"
56
"fmt"
67
"strconv"
78

@@ -72,6 +73,7 @@ const (
7273
// Zero or more lines in the tabular output.
7374
type tableContents interface {
7475
Emit(t *table)
76+
CollectItems(items map[string]*item)
7577
}
7678

7779
// A section of lines in the tabular output, consisting of a header
@@ -98,31 +100,43 @@ func (s *section) Emit(t *table) {
98100
}
99101
}
100102

103+
func (s *section) CollectItems(items map[string]*item) {
104+
for _, c := range s.contents {
105+
c.CollectItems(items)
106+
}
107+
}
108+
101109
// A line containing data in the tabular output.
102110
type item struct {
103-
name string
104-
path *Path
105-
value counts.Humanable
106-
humaner counts.Humaner
107-
unit string
108-
scale float64
111+
symbol string
112+
name string
113+
description string
114+
path *Path
115+
value counts.Humanable
116+
humaner counts.Humaner
117+
unit string
118+
scale float64
109119
}
110120

111121
func newItem(
122+
symbol string,
112123
name string,
124+
description string,
113125
path *Path,
114126
value counts.Humanable,
115127
humaner counts.Humaner,
116128
unit string,
117129
scale float64,
118130
) *item {
119131
return &item{
120-
name: name,
121-
path: path,
122-
value: value,
123-
humaner: humaner,
124-
unit: unit,
125-
scale: scale,
132+
symbol: symbol,
133+
name: name,
134+
description: description,
135+
path: path,
136+
value: value,
137+
humaner: humaner,
138+
unit: unit,
139+
scale: scale,
126140
}
127141
}
128142

@@ -170,6 +184,40 @@ func (l *item) levelOfConcern(threshold Threshold) (string, bool) {
170184
return stars[:int(alert)], true
171185
}
172186

187+
func (i *item) CollectItems(items map[string]*item) {
188+
items[i.symbol] = i
189+
}
190+
191+
func (i *item) MarshalJSON() ([]byte, error) {
192+
// How we want to emit an item as JSON.
193+
value, _ := i.value.ToUint64()
194+
195+
stat := struct {
196+
Description string
197+
Value uint64
198+
Unit string
199+
Prefixes string
200+
ReferenceValue float64
201+
LevelOfConcern float64
202+
ObjectName string `json:",omitempty"`
203+
ObjectDescription string `json:",omitempty"`
204+
}{
205+
Description: i.description,
206+
Value: value,
207+
Unit: i.unit,
208+
Prefixes: i.humaner.Name(),
209+
ReferenceValue: i.scale,
210+
LevelOfConcern: float64(value) / i.scale,
211+
}
212+
213+
if i.path != nil && i.path.OID != git.NullOID {
214+
stat.ObjectName = i.path.OID.String()
215+
stat.ObjectDescription = i.path.Path()
216+
}
217+
218+
return json.Marshal(stat)
219+
}
220+
173221
type Threshold float64
174222

175223
// Methods to implement pflag.Value:
@@ -373,6 +421,13 @@ func (t *table) formatRow(
373421
)
374422
}
375423

424+
func JSONString(contents tableContents, threshold Threshold, nameStyle NameStyle) (string, error) {
425+
items := make(map[string]*item)
426+
contents.CollectItems(items)
427+
j, err := json.MarshalIndent(items, "", " ")
428+
return string(j), err
429+
}
430+
376431
func (s HistorySize) Contents() tableContents {
377432
S := newSection
378433
I := newItem
@@ -384,65 +439,109 @@ func (s HistorySize) Contents() tableContents {
384439
"Overall repository size",
385440
S(
386441
"Commits",
387-
I("Count", nil, s.UniqueCommitCount, metric, "", 500e3),
388-
I("Total size", nil, s.UniqueCommitSize, binary, "B", 250e6),
442+
I("uniqueCommitCount", "Count",
443+
"The total number of distinct commit objects",
444+
nil, s.UniqueCommitCount, metric, "", 500e3),
445+
I("uniqueCommitSize", "Total size",
446+
"The total size of all commit objects",
447+
nil, s.UniqueCommitSize, binary, "B", 250e6),
389448
),
390449

391450
S(
392451
"Trees",
393-
I("Count", nil, s.UniqueTreeCount, metric, "", 1.5e6),
394-
I("Total size", nil, s.UniqueTreeSize, binary, "B", 2e9),
395-
I("Total tree entries", nil, s.UniqueTreeEntries, metric, "", 50e6),
452+
I("uniqueTreeCount", "Count",
453+
"The total number of distinct tree objects",
454+
nil, s.UniqueTreeCount, metric, "", 1.5e6),
455+
I("uniqueTreeSize", "Total size",
456+
"The total size of all distinct tree objects",
457+
nil, s.UniqueTreeSize, binary, "B", 2e9),
458+
I("uniqueTreeEntries", "Total tree entries",
459+
"The total number of entries in all distinct tree objects",
460+
nil, s.UniqueTreeEntries, metric, "", 50e6),
396461
),
397462

398463
S(
399464
"Blobs",
400-
I("Count", nil, s.UniqueBlobCount, metric, "", 1.5e6),
401-
I("Total size", nil, s.UniqueBlobSize, binary, "B", 10e9),
465+
I("uniqueBlobCount", "Count",
466+
"The total number of distinct blob objects",
467+
nil, s.UniqueBlobCount, metric, "", 1.5e6),
468+
I("uniqueBlobSize", "Total size",
469+
"The total size of all distinct blob objects",
470+
nil, s.UniqueBlobSize, binary, "B", 10e9),
402471
),
403472

404473
S(
405474
"Annotated tags",
406-
I("Count", nil, s.UniqueTagCount, metric, "", 25e3),
475+
I("uniqueTagCount", "Count",
476+
"The total number of annotated tags",
477+
nil, s.UniqueTagCount, metric, "", 25e3),
407478
),
408479

409480
S(
410481
"References",
411-
I("Count", nil, s.ReferenceCount, metric, "", 25e3),
482+
I("referenceCount", "Count",
483+
"The total number of references",
484+
nil, s.ReferenceCount, metric, "", 25e3),
412485
),
413486
),
414487

415488
S("Biggest objects",
416489
S("Commits",
417-
I("Maximum size", s.MaxCommitSizeCommit, s.MaxCommitSize, binary, "B", 50e3),
418-
I("Maximum parents", s.MaxParentCountCommit, s.MaxParentCount, metric, "", 10),
490+
I("maxCommitSize", "Maximum size",
491+
"The size of the largest single commit",
492+
s.MaxCommitSizeCommit, s.MaxCommitSize, binary, "B", 50e3),
493+
I("maxCommitParentCount", "Maximum parents",
494+
"The most parents of any single commit",
495+
s.MaxParentCountCommit, s.MaxParentCount, metric, "", 10),
419496
),
420497

421498
S("Trees",
422-
I("Maximum entries", s.MaxTreeEntriesTree, s.MaxTreeEntries, metric, "", 1000),
499+
I("maxTreeEntries", "Maximum entries",
500+
"The most entries in any single tree",
501+
s.MaxTreeEntriesTree, s.MaxTreeEntries, metric, "", 1000),
423502
),
424503

425504
S("Blobs",
426-
I("Maximum size", s.MaxBlobSizeBlob, s.MaxBlobSize, binary, "B", 10e6),
505+
I("maxBlobSize", "Maximum size",
506+
"The size of the largest blob object",
507+
s.MaxBlobSizeBlob, s.MaxBlobSize, binary, "B", 10e6),
427508
),
428509
),
429510

430511
S("History structure",
431-
I("Maximum history depth", nil, s.MaxHistoryDepth, metric, "", 500e3),
432-
I("Maximum tag depth", s.MaxTagDepthTag, s.MaxTagDepth, metric, "", 1.001),
512+
I("maxHistoryDepth", "Maximum history depth",
513+
"The longest chain of commits in history",
514+
nil, s.MaxHistoryDepth, metric, "", 500e3),
515+
I("maxTagDepth", "Maximum tag depth",
516+
"The longest chain of annotated tags pointing at one another",
517+
s.MaxTagDepthTag, s.MaxTagDepth, metric, "", 1.001),
433518
),
434519

435520
S("Biggest checkouts",
436-
I("Number of directories", s.MaxExpandedTreeCountTree, s.MaxExpandedTreeCount, metric, "", 2000),
437-
I("Maximum path depth", s.MaxPathDepthTree, s.MaxPathDepth, metric, "", 10),
438-
I("Maximum path length", s.MaxPathLengthTree, s.MaxPathLength, binary, "B", 100),
439-
440-
I("Number of files", s.MaxExpandedBlobCountTree, s.MaxExpandedBlobCount, metric, "", 50e3),
441-
I("Total size of files", s.MaxExpandedBlobSizeTree, s.MaxExpandedBlobSize, binary, "B", 1e9),
442-
443-
I("Number of symlinks", s.MaxExpandedLinkCountTree, s.MaxExpandedLinkCount, metric, "", 25e3),
444-
445-
I("Number of submodules", s.MaxExpandedSubmoduleCountTree, s.MaxExpandedSubmoduleCount, metric, "", 100),
521+
I("maxCheckoutTreeCount", "Number of directories",
522+
"The number of directories in the largest checkout",
523+
s.MaxExpandedTreeCountTree, s.MaxExpandedTreeCount, metric, "", 2000),
524+
I("maxCheckoutPathDepth", "Maximum path depth",
525+
"The maximum path depth in any checkout",
526+
s.MaxPathDepthTree, s.MaxPathDepth, metric, "", 10),
527+
I("maxCheckoutPathLength", "Maximum path length",
528+
"The maximum path length in any checkout",
529+
s.MaxPathLengthTree, s.MaxPathLength, binary, "B", 100),
530+
531+
I("maxCheckoutBlobCount", "Number of files",
532+
"The maximum number of files in any checkout",
533+
s.MaxExpandedBlobCountTree, s.MaxExpandedBlobCount, metric, "", 50e3),
534+
I("maxCheckoutBlobSize", "Total size of files",
535+
"The maximum sum of file sizes in any checkout",
536+
s.MaxExpandedBlobSizeTree, s.MaxExpandedBlobSize, binary, "B", 1e9),
537+
538+
I("maxCheckoutLinkCount", "Number of symlinks",
539+
"The maximum number of symlinks in any checkout",
540+
s.MaxExpandedLinkCountTree, s.MaxExpandedLinkCount, metric, "", 25e3),
541+
542+
I("maxCheckoutSubmoduleCount", "Number of submodules",
543+
"The maximum number of submodules in any checkout",
544+
s.MaxExpandedSubmoduleCountTree, s.MaxExpandedSubmoduleCount, metric, "", 100),
446545
),
447546
)
448547
}

0 commit comments

Comments
 (0)