Repository: VKCOM/noverify
Pull request #574 (2020-07-13 19:39:14)

baseline: store creation date inside the profile
This makes it easier to figure out which profile is older
or newer (especially if the linter version string is identical).

Signed-off-by: Iskander Sharipov <quasilyte@gmail.com>

quasilyte: Changed to UNIX time.

Patch:
diff --git a/src/baseline/baseline.go b/src/baseline/baseline.go
index 43c7c85..99176ac 100644
--- a/src/baseline/baseline.go
+++ b/src/baseline/baseline.go
@@ -19,12 +19,17 @@ import (
 // Versions log:
 // 1 - initial version.
 // 2 - added Profile.LinterVersion field.
-const profileVersion = 2
+// 3 - added Profile.CreatedAt field.
+const profileVersion = 3
 
 // Profile is a project-wide suppression profile (baseline file).
 type Profile struct {
 	LinterVersion string
 
+	// CreatedAt is a Unix time that represents the moment at which
+	// this profile was generated.
+	CreatedAt int64
+
 	Files map[string]FileProfile
 }
 
@@ -112,6 +117,7 @@ func ReadProfile(r io.Reader) (*Profile, *Stats, error) {
 
 	result := &Profile{
 		LinterVersion: p.LinterVersion,
+		CreatedAt:     p.CreatedAt,
 		Files:         files,
 	}
 	return result, p.Stats, nil
@@ -169,6 +175,7 @@ func WriteProfile(w io.Writer, p *Profile, stats *Stats) error {
 	enc.SetIndent("", "\t")
 	return enc.Encode(jsonProfile{
 		LinterVersion: p.LinterVersion,
+		CreatedAt:     p.CreatedAt,
 		Version:       profileVersion,
 		Stats:         stats,
 		Files:         files,
@@ -216,6 +223,7 @@ func ReportHash(fields HashFields) uint64 {
 // Using slices instead of maps guarantees the stable output as well as makes it more compact.
 type jsonProfile struct {
 	LinterVersion string
+	CreatedAt     int64
 	Version       int
 	Stats         *Stats
 	Files         []jsonFileProfile
diff --git a/src/cmd/main.go b/src/cmd/main.go
index 9c35793..0b1ca2a 100644
--- a/src/cmd/main.go
+++ b/src/cmd/main.go
@@ -13,6 +13,7 @@ import (
 	"runtime/pprof"
 	"strings"
 	"sync/atomic"
+	"time"
 
 	"github.com/VKCOM/noverify/src/baseline"
 	"github.com/VKCOM/noverify/src/cmd/stubs"
@@ -230,6 +231,7 @@ func createBaseline(l *linterRunner, cfg *MainConfig, reports []*linter.Report)
 
 	profile := &baseline.Profile{
 		LinterVersion: cfg.LinterVersion,
+		CreatedAt:     time.Now().Unix(),
 		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 21946f1..d7a51c0 100644
--- a/src/baseline/baseline_test.go
+++ b/src/baseline/baseline_test.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"fmt"
 	"testing"
+	"time"
 
 	"github.com/google/go-cmp/cmp"
 )
@@ -57,13 +58,15 @@ func TestWriteReadBaseline(t *testing.T) {
 		}
 		return &Profile{
 			LinterVersion: linterVersion,
+			CreatedAt:     time.Date(2020, 7, 13, 20, 58, 30, 0, time.UTC).Unix(),
 			Files:         m,
 		}
 	}
 
 	const expectedOutput = `{
 	"LinterVersion": "3cfde307d8fbb5acd13d3c346b442172c4433dcb",
-	"Version": 2,
+	"CreatedAt": 1594673910,
+	"Version": 3,
 	"Stats": {
 		"CountTotal": 0,
 		"CountPerCheck": null
@@ -189,7 +192,7 @@ func TestWriteReadBaseline(t *testing.T) {
 	if err := WriteProfile(&buf, bigProfile, &Stats{}); err != nil {
 		t.Fatalf("encoding big profile: %v", err)
 	}
-	expectedSize := 15597
+	expectedSize := 15623
 	if expectedSize != buf.Len() {
 		t.Fatalf("big profile size differs:\nhave: %d\nwant: %d", buf.Len(), expectedSize)
 	}