Repository: VKCOM/noverify
Pull request #566 (2020-07-07 13:06:11)

baseline: store LinterVersion inside a profile
Signed-off-by: Iskander Sharipov <quasilyte@gmail.com>


Patch:
diff --git a/main.go b/main.go
index 64830f9..bc09e72 100644
--- a/main.go
+++ b/main.go
@@ -27,5 +27,7 @@ func main() {
 	// You can register your own rules here, see src/linter/custom.go
 
 	printVersion()
-	cmd.Main(nil)
+	cmd.Main(&cmd.MainConfig{
+		LinterVersion: BuildCommit,
+	})
 }
diff --git a/src/baseline/baseline.go b/src/baseline/baseline.go
index f30d70c..faf1e58 100644
--- a/src/baseline/baseline.go
+++ b/src/baseline/baseline.go
@@ -18,10 +18,13 @@ import (
 //
 // Versions log:
 // 1 - initial version.
-const profileVersion = 1
+// 2 - added Profile.LinterVersion field.
+const profileVersion = 2
 
 // Profile is a project-wide suppression profile (baseline file).
 type Profile struct {
+	LinterVersion string
+
 	Files map[string]FileProfile
 }
 
@@ -107,7 +110,11 @@ func ReadProfile(r io.Reader) (*Profile, error) {
 		}
 	}
 
-	return &Profile{Files: files}, nil
+	result := &Profile{
+		LinterVersion: p.LinterVersion,
+		Files:         files,
+	}
+	return result, nil
 }
 
 // WriteProfile writes a given suppression profile to w.
@@ -161,9 +168,10 @@ func WriteProfile(w io.Writer, p *Profile, stats *Stats) error {
 	enc := json.NewEncoder(w)
 	enc.SetIndent("", "\t")
 	return enc.Encode(jsonProfile{
-		Version: profileVersion,
-		Stats:   stats,
-		Files:   files,
+		LinterVersion: p.LinterVersion,
+		Version:       profileVersion,
+		Stats:         stats,
+		Files:         files,
 	})
 }
 
@@ -207,9 +215,10 @@ func ReportHash(fields HashFields) uint64 {
 // jsonProfile is a Profile representation that is used for JSON encoding/decoding.
 // Using slices instead of maps guarantees the stable output as well as makes it more compact.
 type jsonProfile struct {
-	Version int
-	Stats   *Stats
-	Files   []jsonFileProfile
+	LinterVersion string
+	Version       int
+	Stats         *Stats
+	Files         []jsonFileProfile
 }
 
 // jsonFileProfile is a FileProfile representation that is used for JSON encoding/decoding.
diff --git a/src/cmd/conf.go b/src/cmd/conf.go
index 694cae1..ae85c0e 100644
--- a/src/cmd/conf.go
+++ b/src/cmd/conf.go
@@ -24,4 +24,6 @@ type MainConfig struct {
 	//
 	// If false is returned, the given report will not be reported.
 	BeforeReport func(*linter.Report) bool
+
+	LinterVersion string
 }
diff --git a/src/cmd/main.go b/src/cmd/main.go
index d5c993d..985903d 100644
--- a/src/cmd/main.go
+++ b/src/cmd/main.go
@@ -227,7 +227,10 @@ func createBaseline(l *linterRunner, cfg *MainConfig, reports []*linter.Report)
 		files[filename] = f
 	}
 
-	profile := &baseline.Profile{Files: files}
+	profile := &baseline.Profile{
+		LinterVersion: cfg.LinterVersion,
+		Files:         files,
+	}
 	return baseline.WriteProfile(l.outputFp, profile, &stats)
 }
 


Test patch:
diff --git a/src/baseline/baseline_test.go b/src/baseline/baseline_test.go
index bdcf2f6..4c3fc94 100644
--- a/src/baseline/baseline_test.go
+++ b/src/baseline/baseline_test.go
@@ -50,16 +50,20 @@ func TestWriteReadBaseline(t *testing.T) {
 			Reports:  makeReports(filename, testFieldsList),
 		}
 	}
-	makeProfile := func(files ...FileProfile) *Profile {
+	makeProfile := func(linterVersion string, files ...FileProfile) *Profile {
 		m := make(map[string]FileProfile, len(files))
 		for _, f := range files {
 			m[f.Filename] = f
 		}
-		return &Profile{Files: m}
+		return &Profile{
+			LinterVersion: linterVersion,
+			Files:         m,
+		}
 	}
 
 	const expectedOutput = `{
-	"Version": 1,
+	"LinterVersion": "3cfde307d8fbb5acd13d3c346b442172c4433dcb",
+	"Version": 2,
 	"Stats": {
 		"CountTotal": 0,
 		"CountPerCheck": null
@@ -143,7 +147,7 @@ func TestWriteReadBaseline(t *testing.T) {
 		},
 	})
 
-	x := makeProfile(f1, f2)
+	x := makeProfile("3cfde307d8fbb5acd13d3c346b442172c4433dcb", f1, f2)
 
 	// Run test more than once to verify that the output is stable.
 	for i := 0; i < 10; i++ {
@@ -180,12 +184,12 @@ func TestWriteReadBaseline(t *testing.T) {
 		}
 		files[i] = makeFileProfile(fmt.Sprintf("file%d.php", i), fieldsList)
 	}
-	bigProfile := makeProfile(files...)
+	bigProfile := makeProfile("3cfde307d8fbb5acd13d3c346b442172c4433dcb", files...)
 	var buf bytes.Buffer
 	if err := WriteProfile(&buf, bigProfile, &Stats{}); err != nil {
 		t.Fatalf("encoding big profile: %v", err)
 	}
-	expectedSize := 15535
+	expectedSize := 15597
 	if expectedSize != buf.Len() {
 		t.Fatalf("big profile size differs:\nhave: %d\nwant: %d", buf.Len(), expectedSize)
 	}