directive

package
v0.0.16 Latest Latest
Warning

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

Go to latest
Published: Jun 30, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package directive scans for the clover: keyword and parses the key=value grammar (quote-on-demand) into an ordered Directive. Pure.

Index

Constants

This section is empty.

Variables

View Source
var ErrUnknownKey = errors.New("unknown key")

ErrUnknownKey is the sentinel a Directive.CheckKeys failure wraps, so a caller can tell an unknown-key rejection apart from other validation errors and treat it accordingly - lint rejects it, run downgrades it to a skip.

Functions

func CommonKeys

func CommonKeys() []string

CommonKeys returns the provider-agnostic directive vocabulary in sorted order - every key valid on any marker regardless of provider. It exposes the same set [CheckKeys] validates against, so a caller (the sidecar schema's drift guard) can enumerate the vocabulary without reaching into the unexported map.

func Render

func Render(d Directive) string

Render serializes a directive to its canonical text: the keyword, then each pair as key=value separated by single spaces. A value is quoted only when it must be - when it contains whitespace, or when its first character (a quote or a slash) would otherwise re-trigger quoted or /regex/ parsing - and a value that is already a complete /regex/ is left bare because it self-delimits. This makes Render the exact inverse of Parse, so format is idempotent.

func RenderYAML

func RenderYAML(d Directive, providerKeys []string) *yaml.Node

RenderYAML serializes a directive to a YAML mapping node in canonical key order (so provider: leads), reusing the one Reorder the text codec calls and canonicalizing tags identically. Consecutive repeated keys collapse into a single key with a sequence value. Scalar quoting is left to the YAML encoder.

func RenderYAMLList

func RenderYAMLList(entries []*yaml.Node) ([]byte, error)

RenderYAMLList serializes entry mapping nodes (each from RenderYAML) as a YAML sequence document - the sidecar file's top-level shape. It is the codec's document writer, shared by annotate's generation and format's re-emit so both lay down byte-identical canonical output for the same entries.

Types

type Directive

type Directive struct {
	Pairs []KV
}

Directive is a parsed clover: directive: its key/value pairs in source order. Order is preserved (a slice, not a map) because keys repeat - include and exclude may appear several times - and because format mode reorders the pairs into a canonical sequence, which it can only do from the original. Parsing is purely syntactic: keys are not validated and values are not interpreted here; that is the provider's and the rule's job downstream.

func CanonicalizeTags

func CanonicalizeTags(d Directive) Directive

CanonicalizeTags returns d with its tags value lowercased and de-duplicated, preserving order. Tag matching is case-insensitive, so this is the canonical form format settles a tags value into; an absent tags key is unchanged.

func Parse

func Parse(body string) (Directive, bool, error)

Parse reads a comment body, scans for the clover: keyword, and parses the directive that follows. found is false when the body carries no keyword (the common case for most lines), in which case there is no error. A keyword followed by malformed text - an unterminated quoted or /regex/ value, or an empty key - yields found=true and an error so callers can surface it.

The keyword must lead the comment (after optional whitespace), so an incidental "clover:" inside prose is not mistaken for a directive.

func ParseYAML

func ParseYAML(node *yaml.Node) (Directive, error)

ParseYAML decodes one YAML mapping node into a Directive. Each key maps to a directive key; a scalar value becomes one pair. A sequence value is accepted for a repeatable key (include, exclude), expanding to one pair per item, and for a CSV key (tags), joining the items into one comma-separated value. Source order is not preserved: canonical order is imposed on emit by RenderYAML, never on parse. A non-mapping node, or a sequence on a key that is neither repeatable nor CSV, is a hard error.

func Reorder

func Reorder(d Directive, providerKeys []string) Directive

Reorder returns the directive with its pairs sorted into canonical order: the leading common keys, then providerKeys (the provider's own, in the order it declares them), then the locator keys, then the trailing common keys. Repeated keys (include, exclude) keep their relative order, and any key in none of the zones is kept after the known keys in its original position, so nothing is ever dropped.

func (Directive) All

func (d Directive) All(key string) []string

All returns every value for key, in order - for repeatable keys like include and exclude.

func (Directive) Bool

func (d Directive) Bool(key string) (bool, error)

Bool interprets the first value for key as a boolean. An absent key is false with no error; a present key must be exactly true or false, so a typo like skip=yes is rejected rather than silently treated as false.

func (Directive) CSV

func (d Directive) CSV(key string) []string

CSV interprets key's values as comma-separated lists, flattening repeats and splitting each value on commas, with surrounding whitespace trimmed and empty items dropped. Order is preserved; an absent key yields nil. It backs keys like tags that carry several labels (tags=prod,ci).

func (Directive) CheckKeys

func (d Directive) CheckKeys(providerKeys []string) error

CheckKeys returns an error naming the first key outside the common vocabulary and providerKeys (the resolved provider's own keys), with the closest known key suggested when one is near. It returns nil when every key is known. Both lint/run validation and format share it, so the rejection reads identically wherever a stale or mistyped key surfaces.

func (Directive) CheckKeysSidecar

func (d Directive) CheckKeysSidecar(providerKeys []string) error

CheckKeysSidecar validates a sidecar entry's keys, permitting jq in addition to the common vocabulary and providerKeys. jq is a locator key that only a sidecar may carry (an inline directive still rejects it via Directive.CheckKeys), so the two paths diverge only by that one key.

func (Directive) Duration

func (d Directive) Duration(key string) (time.Duration, error)

Duration interprets the first value for key as a human duration (e.g. 2w3d, 72h, 30m). An absent key is zero with no error; a present unparseable value is rejected. Day, week, and year units are supported beyond the standard library's hours-and-below.

func (Directive) FirstUnknownKey

func (d Directive) FirstUnknownKey(providerKeys []string) (string, string, bool)

FirstUnknownKey returns the first directive key that is neither in the common vocabulary nor among providerKeys (the resolved provider's own keys), together with the closest known key as a suggestion (empty when none is near enough) and found true. When every key is known it returns "", "", false. Keys are checked in written order so the reported one is stable.

func (Directive) Get

func (d Directive) Get(key string) (string, bool)

Get returns the value of the first pair with the given key.

func (Directive) Has

func (d Directive) Has(key string) bool

Has reports whether key is present at all.

func (Directive) Int

func (d Directive) Int(key string) (int, error)

Int interprets the first value for key as an integer. An absent key is zero with no error; a present non-integer value is rejected. Range checks (e.g. a key that must be non-negative) belong to the validating caller.

func (Directive) PruneUnknownKeys

func (d Directive) PruneUnknownKeys(providerKeys []string) (Directive, []string)

PruneUnknownKeys returns the directive with every key outside the common vocabulary and providerKeys removed, plus the removed keys in written order. The directive is returned unchanged (and removed is nil) when all keys are known, so a caller can tell a prune happened. It backs `format --prune`, stripping stale annotations a default format would instead reject.

type IgnoreScope

type IgnoreScope int

IgnoreScope is the reach of a clover:ignore control comment.

const (
	// IgnoreNone means the comment is not an ignore control (an ordinary
	// directive, or no directive at all).
	IgnoreNone IgnoreScope = iota
	// IgnoreNextLine ignores a directive on the line immediately following.
	IgnoreNextLine
	// IgnoreBlockStart begins a region ignored until IgnoreBlockEnd.
	IgnoreBlockStart
	// IgnoreBlockEnd ends a region begun by IgnoreBlockStart.
	IgnoreBlockEnd
	// IgnoreFile ignores every directive in the file.
	IgnoreFile
)

func ParseIgnore

func ParseIgnore(body string) IgnoreScope

ParseIgnore classifies a comment body as a clover:ignore control, returning IgnoreNone when it is an ordinary directive. Only the first token is matched, so a trailing explanation is allowed (clover:ignore-file why...), while an ordinary clover: directive or a real key like clover:ignored=true is left alone.

type KV

type KV struct {
	Key   string
	Value string
}

KV is one key/value pair from a directive, in the order written.

Jump to

Keyboard shortcuts

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