Documentation
¶
Overview ¶
Package block holds the data model shared by every docsync stage: a defined Block, a Reference to one, and the closed-set constants (kind, carrier, stability, change class) that the ledger, findings, and JSON contract use.
Why a separate package with no behaviour: the scanner produces these, the matcher compares them, the ledger serialises them, the renderer reads them. If each stage defined its own struct there would be four lossy conversions. Keeping the model here and dependency-free means every stage, and every plugin, speaks the same shape.
Index ¶
- Constants
- Variables
- func Crosses(a, b Position) bool
- func Flags(st Stability, classes []Class) bool
- func SecretAddress(s string) bool
- type Block
- func (b Block) Env() string
- func (b Block) From() string
- func (b Block) IsLocal() bool
- func (b Block) IsRunnable() bool
- func (b Block) IsSecret() bool
- func (b Block) IsTruth() bool
- func (b Block) Owner() string
- func (b *Block) SetContent(content string)
- func (b *Block) SetContentHashed(content, hashed string)
- func (b Block) Stability() Stability
- func (b Block) Tags() []string
- type Carrier
- type Class
- type Kind
- type Position
- type Reference
- type Region
- type Stability
- type ValueType
Constants ¶
const ( KeyID = "id" KeyOwner = "owner" KeyTags = "tags" KeyStability = "stability" KeySpan = "span" KeyPick = "pick" KeyType = "type" KeyFile = "file" KeyLocal = "local" KeyEnv = "env" KeySecret = "secret" KeySource = "source" KeyFrom = "from" KeyTruth = "truth" KeySync = "sync" KeyRunnable = "runnable" KeyDeprecate = "deprecated" KeySunset = "sunset" KeyDesc = "desc" KeyDoc = "doc" // KeyRepo is set by a workspace merge, never written by an author: the // repository a merged block was published from. KeyRepo = "repo" // KeyBranch is set by a workspace merge for blocks published from a // non-default branch (§9.2 `branch=`, Part VII "Ids and branches"). KeyBranch = "branch" )
Directive keys read by the core. Verbs may define more; these are the ones that change how a block is matched, hashed, or reported.
const DefaultStability = StabilityStable
DefaultStability applies when a def has no `stability=`.
const TrueValue = "true"
TrueValue is the only spelling of a boolean key (`secret=true`). Anything else is false; the spec does not infer booleans from shape (§9.1).
Variables ¶
var CarrierValues = []Carrier{CarrierComment, CarrierBareLine, CarrierLink, CarrierBlock}
CarrierValues is the canonical order.
var ClassValues = []Class{ClassRenamed, ClassMoved, ClassSignature, ClassType, ClassBody, ClassComment, ClassWhitespace, ClassValue, ClassUnknown}
ClassValues is the canonical order.
var KeyValues = []string{KeyID, KeyOwner, KeyTags, KeyStability, KeySpan, KeyPick, KeyType, KeyFile, KeyLocal, KeyEnv, KeySecret, KeySource, KeyFrom, KeyTruth, KeySync, KeyRunnable, KeyDeprecate, KeySunset, KeyDesc, KeyDoc}
KeyValues lists the core-recognised def keys so a linter can warn on unknown ones without hardcoding the list twice.
var KindValues = []Kind{KindFunc, KindType, KindConst, KindStatement, KindKey, KindLine, KindSpan, KindSection, KindParagraph, KindLinkText, KindElement, KindFile}
KindValues is the canonical order for enumeration.
var StabilityValues = []Stability{StabilityFrozen, StabilityStable, StabilityAPI, StabilityVolatile}
StabilityValues is the canonical order.
var ValueTypeValues = []ValueType{TypeURL, TypeEmail, TypeInt, TypeFloat, TypePercent, TypeSemver, TypeDate, TypeDuration, TypeHost, TypeOpRef}
ValueTypeValues is the canonical order, for messages and docs.
Functions ¶
func Crosses ¶ added in v0.1.3
Crosses reports two extents in one file that overlap without either one containing the other. Nesting is legitimate -- a method in a class, a subsection in a section -- but crossing blocks each hold part of the other, so an edit that concerns one flags both. A position with no extent (Start 0: remote, local, unbound) crosses nothing.
func Flags ¶
Flags reports whether a change with the given classes should flag prose under a stability policy. This is the single place the §20 table lives.
Invariant: ClassWhitespace never flags under any policy, and ClassMoved alone never flags (a move is absorbed by the ledger), so a change whose only classes are those two is silent everywhere except `frozen`, where a move is still silent but any other touch is an error. dsself:def id=flags-zfrzu4vz owner=@docsync stability=stable
func SecretAddress ¶
SecretAddress reports text that holds a secret's address rather than its value, and so is safe to show.
Why it exists: the spec promises the tool "never stores, renders, or logs a value" and calls an address "safe to hash and render". Nothing enforced the difference, so `secret=true` on a line holding a real credential -- or any line in a `[secret] paths` file, which holds values by definition -- was printed by render, facts, context, read and export alike. A bare uppercase name is deliberately NOT treated as an address: an AWS access key id is uppercase too, and the spec already asks for `source=` on a bare env name.
Types ¶
type Block ¶
type Block struct {
// ID is the full `prefix-suffix` id from the def.
ID string `json:"id"`
// Kind is decided by the extractor that bound the def.
Kind Kind `json:"kind"`
// Symbol is the human name of what was bound: `Store.SaveSession`,
// `auth.port`, a heading title, or "" when the host has no symbols.
Symbol string `json:"symbol,omitempty"`
// Pos is where the block's content lives, not where the directive sits;
// the directive line is DirectivePos.
Pos Position `json:"pos"`
// DirectivePos is the line(s) the `ds:def` occupied, including any
// continuation lines. Renderers strip these; hashes exclude them.
DirectivePos Position `json:"directive_pos"`
// Carrier is how the def was written.
Carrier Carrier `json:"carrier"`
// Content is the bound text with the directive lines removed. For a fact
// it is the single picked line. It is kept so `read`, `context`, and the
// classifier have the body without re-reading the file.
Content string `json:"-"`
// Hash is textnorm.Hash(Content). Stored in full; displayed short.
Hash string `json:"hash"`
// Args holds every key from the def directive, verbatim, so verbs and
// policies can read `owner`, `stability`, `env`, `from`, and so on. The
// well-known ones are exposed by methods; unknown keys are preserved for
// forward compatibility (§7).
Args map[string]string `json:"args,omitempty"`
}
Block is one defined unit: the target of a `ds:def`. Everything the ledger stores about a definition is here; verbs read their own keys from Args.
func (*Block) SetContent ¶
SetContent stores the body and recomputes the hash. It is the only way the hash should be set so Content and Hash can never disagree.
func (*Block) SetContentHashed ¶
SetContentHashed stores content but hashes hashed instead: grammar tiers hash the token stream so a formatter's whitespace never counts as a change (Part VII "What changed"), while Content stays the source as written for rendering. hashed goes through the same normalisation, so a tier that passes content itself gets exactly SetContent.
type Carrier ¶
type Carrier string
Carrier says where a directive sat: which comment syntax or link form. Verbs restrict which carriers they accept (§9.9), and findings report it so a remedy can say "the link on line 13" versus "the comment on line 13".
const ( CarrierComment Carrier = "comment" // a host-language comment: // # -- /* */ <!-- --> CarrierBareLine Carrier = "bareline" // a bare `ds:...` line in a file with no comment syntax CarrierLink Carrier = "link" // a markdown link target `ds:verb?k=v` CarrierBlock Carrier = "block" // an html comment on its own line in markdown, i.e. block position )
type Class ¶
type Class string
Class is one classified difference between two versions of a block (§20). A change carries one or more classes.
const ( ClassRenamed Class = "renamed" // symbol name changed ClassMoved Class = "moved" // file or line range changed, body identical ClassSignature Class = "signature" // parameters or return types changed ClassType Class = "type" // a type's shape changed: fields, variants ClassBody Class = "body" // statements changed, signature unchanged ClassComment Class = "comment" // comment lines only ClassWhitespace Class = "whitespace" // formatting only; never reported ClassValue Class = "value" // for facts: the picked value changed // ClassUnknown says the two versions differ but the older body was not // available to classify (§20). It is not a guess at what changed: it is // the honest statement that the difference is real and undescribed. It // arises when a citation drifted from a hash whose body is not in the // body store — pruned, never stored, or withheld because the block is // secret. It must never be substituted for ClassBody, because `api` // blocks do not flag on ClassBody and a silently-dropped signature // change is a wrong `ok`. ClassUnknown Class = "unknown" )
type Kind ¶
type Kind string
Kind says what a defined block is. It is decided by the extractor tier that bound the directive (docs/SPEC.md §7.1, §10) and stored in the ledger.
const ( KindFunc Kind = "func" // a function or method from a grammar tier KindType Kind = "type" // a type, class, struct, interface, enum KindConst Kind = "const" // a const or var declaration KindStatement Kind = "stmt" // a statement, e.g. a SQL statement KindKey Kind = "key" // a key in a structured file (yaml, toml, json, ini, env) KindLine Kind = "line" // a single line in a grammarless file KindSpan Kind = "span" // a line range in a grammarless file KindSection Kind = "section" // a markdown heading and its section KindParagraph Kind = "paragraph" // a markdown paragraph KindLinkText Kind = "linktext" // the text of an inline markdown def link, i.e. a fact KindElement Kind = "element" // an html/xml element KindFile Kind = "file" // a whole file, from pick=file on an asset )
type Position ¶
Position locates a directive or a block in a file. Lines are 1-based and inclusive; a single line has Start == End. File is repo-relative with `/` separators.
type Reference ¶
type Reference struct {
// Verb is the directive verb, e.g. "block".
Verb string `json:"verb"`
// ID is the referenced id, or "" for verbs that do not point at a def
// (`table`, `claim`, `url`, and `run cmd=`).
ID string `json:"id,omitempty"`
// Pos is the line the reference sits on. For a link it is the line of the
// enclosing sentence, which is what findings attach to.
Pos Position `json:"pos"`
// Carrier is link, comment, or block position.
Carrier Carrier `json:"carrier"`
// Sentence is the enclosing sentence, list item, or table cell (§18), or
// "" for block-position references, which have no prose around them.
Sentence string `json:"sentence,omitempty"`
// SentenceHash is textnorm.Hash(Sentence), what an ack is recorded against.
SentenceHash string `json:"sentence_hash,omitempty"`
// Args holds every key from the directive verbatim.
Args map[string]string `json:"args,omitempty"`
// Region is the repo-mode fence that follows a block-position
// reference (§9.2 include.mode = repo), or nil in build mode.
Region *Region `json:"region,omitempty"`
}
Reference is one use of a defined id: a `ds:block`, `ds:cfg`, `ds:run`, or any other referring verb, wherever it sat.
func (Reference) Directive ¶
Directive reconstructs the parsed directive for a reference, for verbs that want the typed accessors.
func (*Reference) SetSentence ¶
SetSentence stores the enclosing prose and its hash together.
type Region ¶
type Region struct {
Start int `json:"start"`
End int `json:"end"`
Hash string `json:"hash"`
Text string `json:"-"`
}
Region is a rendered copy kept in the document between a block-position directive and its closer `<!-- /ds:block hash=… -->`. Hash is the short block hash the copy was rendered from; Text is the copy itself.
type Stability ¶
type Stability string
Stability is the `stability=` key on a def: which change classes flag prose (§20). The zero value is not valid; DefaultStability is the spec default.
const ( StabilityFrozen Stability = "frozen" // any class but whitespace flags, and is an error on its own StabilityStable Stability = "stable" // default: any class but whitespace and comment flags StabilityAPI Stability = "api" // only signature, type, renamed, value flag StabilityVolatile Stability = "volatile" // nothing flags )
func ParseStability ¶
ParseStability validates a `stability=` value.
type ValueType ¶ added in v0.1.3
type ValueType string
ValueType is a def's declared `type=` (§9.1, §11): what shape its value must have. A scan checks the picked value against it, so a fact that stops being the thing its sentences say it is -- a port that became a word, a version that lost its patch number -- is a finding, not a silent pass. Before, type= was accepted and checked nothing (bug 54).
const ( TypeURL ValueType = "url" TypeEmail ValueType = "email" TypeInt ValueType = "int" TypeFloat ValueType = "float" TypePercent ValueType = "percent" TypeSemver ValueType = "semver" TypeDate ValueType = "date" TypeDuration ValueType = "duration" TypeHost ValueType = "host" TypeOpRef ValueType = "opref" )
The value types, as §9.1 lists them. `url` also decides rendering: an inline def of that type becomes a link.