snapshot of eee7b5cfc0776c68816d7fdaa8af9d7a0e0da2e6 Annotations about the code that implements koment.

internal/store/context.go

1 package store
2
3 import (
4 "fmt"
5 "regexp"
6 "strings"
7 )
8
9 // GitContext is what was true when an annotation was written. It is written
10 // once and never rewritten: reanchor changes where an annotation aims, not
11 // what it witnessed. ADR 0014.
12 type GitContext struct {
13 Commit string `yaml:"commit"`
14 Path string `yaml:"path"`
15 Line int `yaml:"line,omitempty"`
16 EndLine int `yaml:"end_line,omitempty"`
17 }
18
19 var fullCommitSHA = regexp.MustCompile(`^[0-9a-f]{40}$|^[0-9a-f]{64}$`)
20
21 func (g GitContext) Validate() error {
22 if !fullCommitSHA.MatchString(g.Commit) {
23 return fmt.Errorf("git.commit %q is not a full SHA; an abbreviated one stops being unique as history grows", g.Commit)
24 }
25 if _, err := validSourcePath(g.Path); err != nil {
26 return fmt.Errorf("git.path: %w", err)
27 }
28 switch {
29 case g.Line < 0 || g.EndLine < 0:
30 return fmt.Errorf("git.line %d-%d is not a line range", g.Line, g.EndLine)
31 case g.EndLine != 0 && g.Line == 0:
32 return fmt.Errorf("git.end_line %d given without a start line", g.EndLine)
33 case g.EndLine != 0 && g.EndLine < g.Line:
34 return fmt.Errorf("git.end_line %d is before git.line %d", g.EndLine, g.Line)
35 }
36 return nil
37 }
38
39 // AuthorKind separates a person from an agent, because an agent weighing an
40 // annotation needs to know whether another agent wrote it.
41 type AuthorKind string
42
43 const (
44 AuthorHuman AuthorKind = "human"
45 AuthorAgent AuthorKind = "agent"
46 AuthorUnknown AuthorKind = "unknown"
47 )
48
49 // IdentitySource records how much an identity is worth. Git config asserts an
50 // identity; it does not prove one.
51 type IdentitySource string
52
53 const (
54 FromGitConfig IdentitySource = "git-config"
55 FromSession IdentitySource = "session"
56 FromExplicit IdentitySource = "explicit"
57 FromMigration IdentitySource = "migration"
58 FromOIDCProxy IdentitySource = "oidc-proxy"
59 FromScopedAgent IdentitySource = "bearer-credential"
60 )
61
62 // Author is a claim, not a proof, unless Verified says otherwise. ADR 0015.
63 type Author struct {
64 Name string `yaml:"name"`
65 Email string `yaml:"email,omitempty"`
66 Kind AuthorKind `yaml:"kind"`
67 Source IdentitySource `yaml:"source"`
68 Account string `yaml:"account,omitempty"`
69 Verified string `yaml:"verified,omitempty"`
70 }
71
72 func (a Author) Validate() error {
73 if strings.TrimSpace(a.Name) == "" {
74 return fmt.Errorf("author has no name")
75 }
76 switch a.Kind {
77 case AuthorHuman, AuthorAgent, AuthorUnknown:
78 default:
79 return fmt.Errorf("author kind %q, want one of %s, %s, %s", a.Kind, AuthorHuman, AuthorAgent, AuthorUnknown)
80 }
81 switch a.Source {
82 case FromGitConfig, FromSession, FromExplicit, FromMigration, FromOIDCProxy, FromScopedAgent:
83 default:
84 return fmt.Errorf("author source %q is unknown", a.Source)
85 }
86 if a.Kind == AuthorUnknown && a.Source != FromMigration {
87 return fmt.Errorf("unknown author must have migration as its source")
88 }
89 if a.Kind != AuthorUnknown && a.Source == FromMigration {
90 return fmt.Errorf("migration source requires an unknown author")
91 }
92 return nil
93 }
94
95 // IsProven reports whether the identity was verified by some mechanism. An
96 // unverified identity must not be rendered as though it were checked.
97 func (a Author) IsProven() bool { return a.Verified != "" }

Find an annotation

Search file paths, rationale, kinds, and authors.

moveEnter openEsc close