# kiosk Plugin manifests and the plugin registry contract: generates and checks each plugin's plugin.yaml from its own sources. `import "git.golem15.com/golem15/summercms/modules/kiosk"` **Name:** A beach kiosk where every plugin on the shelf carries its label; the label is printed from what is in the box, never written by hand. ## Overview A plugin describes itself in `plugin.yaml`, committed next to its `plugin.go`. The file is generated: `summer plugin:manifest` runs `kiosk.Write`, which reads the plugin's sources and never runs its code. The ID and the required plugins come from what `ID()` and `Requires()` in `plugin.go` return, the module path and the version minimums from `go.mod`, the package import path from the directory, and the name and description from the README's H1 and the paragraph after it (the standard README structure). The registry on summercms.io reads the same file from every tagged release, and `summer build` bakes its name and description into the application. WinterCMS keeps this data in a plugin's `Plugin.php` `pluginDetails()` and in `composer.json`; here it is derived once, so the copy in the repository cannot drift from the code. ## Features - One `plugin.yaml` per plugin package directory, so a repository with a nested plugin carries two files. - A schema version (`kiosk.SchemaVersion`) and a fixed header line (`kiosk.Header`); a manifest with a newer schema is refused with a hint to update summer. - Go-style minimums: `framework` is the `go.mod` require of `kiosk.FrameworkModule`, and each required plugin gets the version its module is required at. - Name and description overrides (`--name`, `--description`) stored in an `overrides:` block that regeneration keeps. - `kiosk.Check` regenerates in memory and returns a `kiosk.StaleError` when the committed file is missing or differs, which `summer plugin:manifest --check` turns into exit status 1. ## Usage ```go path, warnings, err := kiosk.Write(ctx, "plugins/acme/blog", kiosk.DeriveOptions{}) if err != nil { return err } for _, w := range warnings { log.Println(w) } fmt.Println("wrote", path) if err := kiosk.Check(ctx, "plugins/acme/blog"); err != nil { var stale *kiosk.StaleError if errors.As(err, &stale) { fmt.Printf("expected:\n%s", stale.Want) } return err } ``` ## API reference | Identifier | Description | |------------|-------------| | `kiosk.FileName` | The manifest file name, `plugin.yaml`. | | `kiosk.SchemaVersion` | The newest schema this package reads, and the one it writes. | | `kiosk.FrameworkModule` | The framework module path; its `go.mod` require is the plugin's framework minimum. | | `kiosk.Header` | The comment line every generated `plugin.yaml` starts with. | | `kiosk.Manifest` | One `plugin.yaml`: `Schema`, `ID`, `Module`, `Package`, `Name`, `Description`, `Framework`, `Requires`, `Overrides`, written in that order. | | `kiosk.Requires` | Required plugin ID to minimum version; marshals sorted by ID. An empty minimum means the plugin ships in the same module or its module is not a `go.mod` require. | | `kiosk.Requires.MarshalYAML` | Emits the map as a mapping sorted by ID. | | `kiosk.Overrides` | The persisted `--name` and `--description` values. | | `kiosk.Marshal` | The `plugin.yaml` bytes: the header line, then the fields. | | `kiosk.Parse` | Reads `plugin.yaml` bytes; unknown fields are ignored, a newer schema is an error. | | `kiosk.DeriveOptions` | Override changes for `kiosk.Derive`: nil keeps the persisted value, a pointer to `""` clears it. | | `kiosk.Derive` | Builds the manifest of a plugin directory from its sources and returns it with warnings. | | `kiosk.Generate` | `kiosk.Derive` plus `kiosk.Marshal`: the bytes `kiosk.Write` would write. | | `kiosk.Write` | Generates and writes `