exlab_wizard.readme.generator#
README generator. Backend Spec §10 / §11.4.
Renders README.md (YAML front matter + Markdown prose body) and the
readme_fields.json cache file from a fully-resolved
ReadmeContext.
The generator is the single producer for both files. The four field layers (core / template / config / custom) are merged here and validated before any bytes hit the disk: an out-of-bound or missing required field raises before a partial README can be written.
Validation gates (User Interaction Spec §2 + Backend Spec §10.3):
labelnon-empty after trim,<= LABEL_MAX_LENGTH.operatornon-empty after trim.objectivenon-empty after trim,<= OBJECTIVE_MAX_LENGTH.every
required: truetemplate field has a value.every
required: trueconfig field has a value.field ids are unique across the template + config layers.
custom field labels do not collide with the four-layer set’s ids.
core field ids (
label,operator,objective) are not redeclared by the template or config layer (raisesTemplateCoreFieldRedeclaredError).every typed field value matches its declared type (string / text / choice / date / boolean).
Output format follows §10.7: a YAML front matter block delimited by
--- lines at the top of the file followed by a Markdown prose body.
The front matter is emitted via yaml.safe_dump(..., sort_keys=False)
so the document order matches the spec example exactly.
The companion readme_fields.json is written at
<dst>/.exlab-wizard/readme_fields.json using the typed
ReadmeFieldsJson Struct via
msgspec.json.encode (§11.4 contract: every cache file goes through
msgspec).
Classes
|
Mandatory core fields (User Interaction Spec §2). |
|
An ad-hoc user-added field. |
|
Inputs to |
Renders |
|
|
Auto-populated, non-editable system fields. |
|
Field declaration from a template's |
- class exlab_wizard.readme.generator.CoreFields(label, operator, objective)[source]#
Bases:
objectMandatory core fields (User Interaction Spec §2).
All three are non-empty (after trim) when the controller hands the context to
ReadmeGenerator; the generator re-validates so a misuse never lets a malformed README onto disk.
- class exlab_wizard.readme.generator.CustomField(label, value)[source]#
Bases:
objectAn ad-hoc user-added field. Backend Spec §10.4.
Custom fields are plain string key-value pairs (no type selection) and their order in the output mirrors the order the user added them.
- class exlab_wizard.readme.generator.ReadmeContext(level, core, template_fields, config_fields, custom_fields, system, template_field_decls=<factory>, config_field_decls=<factory>)[source]#
Bases:
objectInputs to
ReadmeGenerator. Composed by the controller.The controller pre-merges the four layers into the dicts below so the generator does not need to know about the merge order; the generator’s job is to validate, render, and persist.
- Parameters:
level (
CreationLevel)core (
CoreFields)custom_fields (
list[CustomField])system (
SystemFields)template_field_decls (
list[TemplateFieldDecl])config_field_decls (
list[TemplateFieldDecl])
- config_field_decls: list[TemplateFieldDecl]#
- core: CoreFields#
- custom_fields: list[CustomField]#
- level: CreationLevel#
- system: SystemFields#
- template_field_decls: list[TemplateFieldDecl]#
- class exlab_wizard.readme.generator.ReadmeGenerator[source]#
Bases:
objectRenders
README.md+readme_fields.json. Backend Spec §10.- async generate(dst, ctx)[source]#
Validate
ctx, write both files, return(readme, cache).The destination directory
dstmust already exist (the controller creates it during the directory-render phase). The.exlab-wizard/cache directory is created on demand.Both files are written via
asyncio.to_threadso the asyncio event loop is never blocked on disk syscalls. The two writes share a single timestamp (ctx.system.created) so thegenerated_atandcreatedfields agree.- Parameters:
dst (
Path)ctx (
ReadmeContext)
- Return type:
- class exlab_wizard.readme.generator.SystemFields(created, created_by, equipment, template, project, run, run_kind)[source]#
Bases:
objectAuto-populated, non-editable system fields. Backend Spec §10.6.
- Parameters:
- class exlab_wizard.readme.generator.TemplateFieldDecl(id, label, type, required=False, default='', options=None, hint=None)[source]#
Bases:
objectField declaration from a template’s
_exlab_readme.fieldslist or fromconfig.yamlreadme.defaults. Backend Spec §10.3.The same shape covers both layers: the controller knows which list it came from and packs the matching
ReadmeContextslot.- Parameters:
- type: FieldType#