property

package
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Jun 18, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package property parses and represents SpecScore Property artifacts.

A Property is a single markdown file at `spec/features/**/<slug>.property.md` whose YAML frontmatter declares a reusable, named business field — its `data_type` and a `checks` mapping. See `spec/features/property/README.md` in the meta-spec for the full artifact contract and `spec/features/cli/property/README.md` in this repo for the CLI's implementation contract.

This package provides discovery and parsing utilities only. The lint rules that enforce the schema live in `pkg/lint`.

Index

Constants

This section is empty.

Variables

View Source
var CheckKeyApplicability = map[string]map[string]bool{
	"required":    {"string": true, "integer": true, "number": true, "boolean": true, "date": true, "datetime": true, "object": true, "array": true, "ref": true},
	"enum":        {"string": true, "integer": true, "number": true, "boolean": true, "date": true, "datetime": true, "object": true, "array": true, "ref": true},
	"min":         {"integer": true, "number": true, "date": true, "datetime": true},
	"max":         {"integer": true, "number": true, "date": true, "datetime": true},
	"min_length":  {"string": true, "array": true},
	"max_length":  {"string": true, "array": true},
	"pattern":     {"string": true},
	"trim":        {"string": true},
	"lowercase":   {"string": true},
	"uppercase":   {"string": true},
	"items":       {"array": true},
	"json_schema": {"object": true},
	"entity_ref":  {"ref": true},
}

CheckKeyApplicability is the (check-key → applicable data_types) matrix from [property#req:checks-shape]. The `property-checks-shape` lint rule uses this to validate (data_type, check) pairs; keys NOT present here are "unknown" and reported at severity `warning`.

View Source
var LegalDataTypes = map[string]bool{
	"string":   true,
	"integer":  true,
	"number":   true,
	"boolean":  true,
	"date":     true,
	"datetime": true,
	"object":   true,
	"array":    true,
	"ref":      true,
}

LegalDataTypes mirrors the upstream enumeration in [property#req:data-type-values]. The parser surfaces the raw `data_type` string from frontmatter; lint compares against this map.

Functions

func ValidateSlug

func ValidateSlug(slug string) error

ValidateSlug returns nil if slug matches `[a-z0-9]+(-[a-z0-9]+)*`.

func Walk

func Walk(specRoot string, fn func(*Doc) error) error

Walk combines Discover and Parse: it discovers every property file under `<specRoot>/features/` and invokes `fn` with the parsed Doc for each one, in slug-sorted order.

Walk returns the first non-nil error from `fn` and stops iterating. I/O or parse errors abort with a wrapped error; callers that want to continue past a single bad file MUST handle the error inside `fn` and return nil. A missing `<specRoot>/features/` directory is a no-op.

Types

type Discovered

type Discovered struct {
	Slug string
	Path string // path to the *.property.md file
}

Discovered is a summary of a Property file found during discovery.

func Discover

func Discover(specRoot string) ([]Discovered, error)

Discover walks `<specRoot>/features/**/*.property.md` and returns every property file found, sorted alphabetically by slug.

Discovery scope mirrors [cli/property#req:discovery-scope]:

  • Hidden directories (any path segment starting with `.`) MUST be skipped.
  • Reserved underscore-prefixed directories (e.g., `_tests/`) MUST be skipped.
  • A missing `<specRoot>/features/` directory yields ([], nil) — Discover is not responsible for surfacing project-shape errors.

`specRoot` is the absolute path to the project's `spec/` directory (the caller resolves this from `specscore.yaml`); the function appends `features/` internally to match the meta-spec's property-location glob.

type Doc

type Doc struct {
	Path           string
	Slug           string // derived from filename; the contract id
	RawLines       []string
	Title          string // full title line content after `# `
	TitleName      string // the `<id>` portion after `Property: `
	TitleLine      int    // 1-based
	HasTitle       bool
	Frontmatter    *Frontmatter
	FmRaw          *yaml.Node // raw mapping node — used by `id`-rewrite autofix
	Sections       []Section
	SectionByTitle map[string]*Section
}

Doc is a parsed Property artifact. Parse is resilient — Doc is non-nil even for malformed files; Frontmatter and FmRaw may be nil when the frontmatter block is missing or not the first block in the file.

func Parse

func Parse(path string) (*Doc, error)

Parse reads a property file and returns its parsed representation.

Parse is resilient: a non-nil *Doc is returned for every readable file, even when the frontmatter is missing, not first, or malformed. Callers (lint rules) MUST inspect Doc.Frontmatter / Doc.HasTitle / etc. to decide what is a violation. The only path that returns (nil, err) is an I/O failure opening or reading the file.

`Path` and `Slug` are always populated. `RawLines` is preserved byte- for-byte so the managed-section rewriter can edit specific line ranges without losing surrounding content. `FmRaw` is preserved as a `yaml.Node` so the `id`-rewrite autofix can round-trip frontmatter without losing comments or key order.

type Frontmatter

type Frontmatter struct {
	Kind        string         // MUST equal "property" — lint checks
	ID          string         // MUST equal Doc.Slug — lint checks
	DataType    string         // one of LegalDataTypes — lint checks
	Description string         // OPTIONAL but RECOMMENDED
	Checks      map[string]any // the raw mapping; MAY be empty but key MUST exist
}

Frontmatter mirrors [property#req:frontmatter-required-fields]. The parser fills these fields from a decoded YAML map; lint MUST verify required-ness and value legality (the parser surfaces values raw).

type Section

type Section struct {
	Title     string
	StartLine int // 1-based line number of the `##` heading
	EndLine   int // 1-based line number of the last line of the section
	Body      string
	Items     []string // lines starting with "- "
}

Section captures a single `## <title>` heading and its body.

Jump to

Keyboard shortcuts

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