소스 검색

Document logic behind basic diff

Ben Tranter 8 년 전
부모
커밋
a3d22ae9c7
1개의 변경된 파일40개의 추가작업 그리고 7개의 파일을 삭제
  1. 40 7
      pkg/components/dashdiffs/formatter_basic.go

+ 40 - 7
pkg/components/dashdiffs/formatter_basic.go

@@ -71,6 +71,8 @@ func NewBasicFormatter(left interface{}) *BasicFormatter {
 	}
 }
 
+// Format takes the diff of two JSON documents, and returns the difference
+// between them summarized in an HTML document.
 func (b *BasicFormatter) Format(d diff.Diff) ([]byte, error) {
 	// calling jsonDiff.Format(d) populates the JSON diff's "Lines" value,
 	// which we use to compute the basic dif
@@ -90,23 +92,40 @@ func (b *BasicFormatter) Format(d diff.Diff) ([]byte, error) {
 	return buf.Bytes(), nil
 }
 
-// Basic is V2 of the basic diff
+// Basic transforms a slice of JSONLines into a slice of BasicBlocks.
 func (b *BasicDiff) Basic(lines []*JSONLine) []*BasicBlock {
 	// init an array you can append to for the basic "blocks"
 	blocks := make([]*BasicBlock, 0)
 
-	// iterate through each line
 	for _, line := range lines {
-		// TODO: this condition needs an explaination? what does it mean?
+		// In order to produce distinct "blocks" when rendering the basic diff,
+		// we need a way to distinguish between differnt sections of data.
+		// To do this, we consider the value(s) of each top-level JSON key to
+		// represent a distinct block for Grafana's JSON data structure, so
+		// we perform this check to see if we've entered a new "block". If we
+		// have, we simply append the existing block to the array of blocks.
 		if b.LastIndent == 2 && line.Indent == 1 && line.Change == ChangeNil {
 			if b.Block != nil {
 				blocks = append(blocks, b.Block)
 			}
 		}
 
+		// Record the last indent level at each pass in case we need to
+		// check for a change in depth inside the JSON data structures.
 		b.LastIndent = line.Indent
 
 		// TODO: why special handling for indent 2?
+		// Here we
+		// If the line's indentation is at level 1, then we know it's a top
+		// level key in the JSON document. As mentioned earlier, we treat these
+		// specially as they indicate their values belong to distinct blocks.
+		//
+		// At level 1, we only record single-line changes, ie, the "added",
+		// "deleted", "old" or "new" cases, since we know those values aren't
+		// arrays or maps. We only handle these cases at level 2 or deeper,
+		// since for those we either output a "change" or "summary". This is
+		// done for formatting reasons only, so we have logical "blocks" to
+		// display.
 		if line.Indent == 1 {
 			switch line.Change {
 			case ChangeNil:
@@ -139,17 +158,31 @@ func (b *BasicDiff) Basic(lines []*JSONLine) []*BasicBlock {
 				b.Block.New = line.Val
 				b.Block.LineEnd = line.LineNum
 
-				// then write out the change
+				// For every "old" change there is a corresponding "new", which
+				// is why we wait until we detect the "new" change before
+				// appending the change.
 				blocks = append(blocks, b.Block)
 			default:
 				// ok
 			}
 		}
 
-		// TODO: why special handling for indent > 2 ?
-		// Other Lines
+		// Here is where we handle changes for all types, appending each change
+		// to the current block based on the value.
+		//
+		// Values which only occupy a single line in JSON (like a string or
+		// int, for example) are treated as "Basic Changes" that we append to
+		// the current block as soon as they're detected.
+		//
+		// Values which occupy multiple lines (either slices or maps) are
+		// treated as "Basic Summaries". When we detect the "ChangeNil" type,
+		// we know we've encountered one of these types, so we record the
+		// starting position as well the type of the change, and stop
+		// performing comparisons until we find the end of that change. Upon
+		// finding the change, we append it to the current block, and begin
+		// performing comparisons again.
 		if line.Indent > 1 {
-			// Ensure single line change
+			// Ensure a single line change
 			if line.Key != "" && line.Val != nil && !b.writing {
 				switch line.Change {
 				case ChangeAdded, ChangeDeleted: