sidecar

package
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package sidecar carries the format-agnostic logic for YAML sidecar files: the <target>.clover.yaml (or .yml) that holds update rules for a target that cannot host an inline clover: comment, strict JSON being the canonical case. It owns the discovery rule (which names are sidecars and which target they govern), decoding a sidecar document into one directive per entry, and the find line-locator that resolves an entry to the single target line it rewrites. It depends only on directive and pattern, never on scan, so scan can import it without a cycle and remain the sole builder of scan.File.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Locate

func Locate(lines []string, d directive.Directive) (int, error)

Locate resolves a sidecar entry's target line within lines via its locator. An entry must carry find or jq (neither present is a hard error). jq resolves the line by JSON path - robust against a duplicated version string or reordered keys - and a composing find then refines the region within that line at rewrite time; find alone scans for the single line whose content matches a glob or /regex/.

func Names

func Names(target string) []string

Names returns the candidate sidecar file names for target, in precedence order (.yaml before .yml), so a caller can probe for an existing sidecar or resolve which one wins when both are present.

func Refresh

func Refresh(
	data []byte,
	lines []string,
	keysFor func(provider string) []string,
	refresh func(line int, d directive.Directive) (directive.Directive, bool),
	fresh []directive.Directive,
) ([]byte, error)

Refresh re-emits a sidecar with selected entries patched in place. Each entry is parsed and located via its own locator; for one that locates, refresh may return a replacement directive (re-rendered in canonical order, carrying the entry's comments across - including any note on its keys). An entry that does not parse or does not locate is kept verbatim - so a force pass never deletes an unresolvable or hand-written entry it cannot reproduce - and the document's comments survive. The fresh entries are appended. lines is the located target's content, the source the locators resolve against.

func Render

func Render(entries []directive.Directive, keysFor func(provider string) []string) ([]byte, error)

Render serializes directive entries as a canonical YAML sidecar document. Each entry is rendered in canonical key order via the shared codec; keysFor supplies an entry's provider keys, kept a callback so this format-agnostic package never depends on the provider registry. It is the writer annotate generates new sidecars with - and the canonical form format re-emits toward.

func Schema

func Schema() []byte

Schema returns the embedded sidecar JSON schema document.

func SchemaURL

func SchemaURL() string

SchemaURL returns the schema's published location, read from its own $id so the document is the single source of truth for the URL a docs modeline points at.

func Target

func Target(name string) (string, bool)

Target reports the target file name a sidecar name governs: name with the .clover.yaml / .clover.yml suffix removed. ok is false when name is not a sidecar name, or when removing the suffix leaves an empty base - the bare .clover.yaml / .clover.yml configs, which are config, never sidecars.

Types

type Canonical

type Canonical struct {
	Content []byte
	Pruned  []string
	Changed bool
}

Canonical is the outcome of re-emitting a sidecar: the canonical bytes, the unknown keys a prune removed, and whether the bytes differ from the input.

func Canonicalize

func Canonicalize(
	data []byte,
	keysFor func(provider string) []string,
	prune bool,
) (Canonical, error)

Canonicalize re-emits a sidecar in canonical form: each entry's keys are reordered and its tags normalized, while every comment survives (the entry node is rebuilt in place and [carryComments] re-homes its own head, line, and foot comments plus any note on an individual key or value, and the document's own comments are kept by re-marshaling the parsed tree). With prune set, an entry's unknown keys are stripped; without it, an unknown key is rejected with an error so a stale key cannot pass a format gate. A structurally broken sidecar - one that does not parse, or whose entry is malformed - is left untouched (Changed false, no error): lint owns those diagnostics, not format.

type Entry

type Entry struct {
	Directive directive.Directive
	Line      int
	Err       error
}

Entry is one sidecar list item: its directive, the 1-based source line it was written on (for diagnostics), and any error from decoding that single entry.

func Entries

func Entries(data []byte) ([]Entry, error)

Entries decodes a sidecar document into one entry per top-level list item. The document must be a YAML sequence; each item is decoded with directive.ParseYAML, and a single malformed item is reported in its own Entry.Err rather than failing the whole document. A document that is not a sequence is a hard error.

type Leaf

type Leaf struct {
	Key   string
	Value string
	Line  int
	JQ    string
}

Leaf is a string-valued scalar in a JSON document, the unit annotate proposes a sidecar entry from: the object key that holds it (the last path segment, empty for array elements), its value, the 0-based line it sits on, and a jq expression that resolves uniquely to that line. Only leaves whose locator round-trips - jq resolves back to the leaf's own line, and nowhere else - are returned, so a generated locator is robust by construction.

func Leaves

func Leaves(source []byte) ([]Leaf, error)

Leaves enumerates the string-valued scalars in a JSON document, each paired with a verified jq locator, in line order. It is the recognition half of annotate's sidecar generation: the caller decides which leaves name a trackable reference. Source that does not parse as JSON yields an error, since only a JSON target carries a jq-locatable structure. A leaf whose locator the resolver would point elsewhere is dropped - an earlier member of a duplicated key, or a leaf below a shadowed duplicate ancestor.

A single position-aware descent records every string scalar's path and byte offset at once, so the cost is linear in the document size rather than the per-leaf re-parse-and-re-walk a naive enumeration would pay.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL