Documentation
¶
Overview ¶
Package fingerprint records the state a sync reconciled, so the next sync can tell whether anything changed.
New digests the state into a Fingerprint; Fingerprinter is the seam that generates, reads and writes one, with FileFingerprinter keeping the record in a file. The package knows nothing about projects: callers describe their state as Params.
Index ¶
Examples ¶
Constants ¶
const FileName = ".gotools.fingerprint"
FileName is the record's file inside the directory a FileFingerprinter is built for.
Variables ¶
var ErrNone = errors.New("no fingerprint recorded")
ErrNone is returned by Read when nothing has been written.
Functions ¶
func FileDigest ¶
FileDigest is the hex SHA-256 of the file at path.
Types ¶
type File ¶
type File struct {
Path string // where it is, as the caller names it
Digest string // hex SHA-256 of its content
}
File is one file a fingerprint covers, by what it holds.
type FileFingerprinter ¶
type FileFingerprinter struct {
// contains filtered or unexported fields
}
FileFingerprinter is the Fingerprinter that generates with New and keeps the record in one file.
func NewFile ¶
func NewFile(dir string) FileFingerprinter
NewFile returns a Fingerprinter that records in FileName inside dir. It touches nothing until Write.
func (FileFingerprinter) Generate ¶
func (FileFingerprinter) Generate(params Params) Fingerprint
Generate implements Fingerprinter.
func (FileFingerprinter) Read ¶
func (f FileFingerprinter) Read() (Fingerprint, error)
Read implements Fingerprinter.
func (FileFingerprinter) Write ¶
func (f FileFingerprinter) Write(fp Fingerprint) error
Write implements Fingerprinter. The record is written to a temporary file and renamed, so a reader never sees a partial one.
type Fingerprint ¶
type Fingerprint struct {
Digest string // hex SHA-256 of the tool list and the files
Strategy string
GoVersion string
ModulePrefix string
}
Fingerprint is a deterministic digest of Params. Any change to the state yields a different value. It is comparable: two fingerprints are equal when every field is.
func New ¶
func New(params Params) Fingerprint
New digests params. The result does not depend on the order of params.Tools or params.Files.
func Parse ¶
func Parse(s string) (Fingerprint, error)
Parse reads the form String writes.
Example ¶
The recorded form is digest|strategy|go version|module prefix.
package main
import (
"fmt"
"github.com/piusalfred/gotools/internal/fingerprint"
)
func main() {
f, err := fingerprint.Parse("abc123|split|1.27|github.com/acme/tools\n")
fmt.Println(f.Strategy, f.GoVersion, f.ModulePrefix, err)
fmt.Println(f)
}
Output: split 1.27 github.com/acme/tools <nil> abc123|split|1.27|github.com/acme/tools
func (Fingerprint) String ¶
func (f Fingerprint) String() string
String is the recorded form: digest|strategy|go version|module prefix.
type Fingerprinter ¶
type Fingerprinter interface {
// Generate is the fingerprint of params. It is deterministic and does not
// depend on the order of params.Tools.
Generate(params Params) Fingerprint
// Read is the fingerprint last written, or ErrNone. Any other error means
// the record is unreadable or malformed; callers treat that as "does not
// match".
Read() (Fingerprint, error)
// Write records f atomically.
Write(f Fingerprint) error
}
Fingerprinter generates and records a fingerprint.
Example ¶
A sync generates the fingerprint of the state it is about to reconcile and compares it with the recorded one. A match means nothing changed.
package main
import (
"fmt"
"os"
"github.com/piusalfred/gotools/internal/fingerprint"
)
func main() {
dir, _ := os.MkdirTemp("", "fingerprint-example")
defer os.RemoveAll(dir)
var fp fingerprint.Fingerprinter = fingerprint.NewFile(dir)
params := fingerprint.Params{
Tools: []fingerprint.Tool{{Name: "gofumpt", Source: "go", Package: "mvdan.cc/gofumpt", Version: "v0.9.2"}},
Strategy: "split",
GoVersion: "1.27",
}
_, err := fp.Read()
fmt.Println("before the first sync:", err)
// ... reconcile the tools, then record the state ...
if err := fp.Write(fp.Generate(params)); err != nil {
fmt.Println(err)
}
recorded, _ := fp.Read()
fmt.Println("unchanged:", recorded == fp.Generate(params))
params.Tools[0].Version = "v0.9.3"
fmt.Println("after an upgrade:", recorded == fp.Generate(params))
}
Output: before the first sync: no fingerprint recorded unchanged: true after an upgrade: false