docs(sdk): document Coords scope normalisation and accept-both contract
Adds a doc comment to ModFile.Coords explaining the leading-@ trim and a note on ModPlugin.Scope clarifying that consumers should trim "@" before comparing. Locks in the contract with a test asserting both call shapes produce the same display string. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
7af42c1c83
commit
20a7b35e50
@ -13,7 +13,11 @@ type ModFile struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ModPlugin struct {
|
type ModPlugin struct {
|
||||||
Name string `toml:"name"`
|
Name string `toml:"name"`
|
||||||
|
// Scope is the plugin owner namespace as it appears in plugin.mod. It may
|
||||||
|
// include the leading "@" (e.g. "@themes") or omit it (e.g. "themes") —
|
||||||
|
// both forms are accepted. Consumers comparing scopes should trim the "@"
|
||||||
|
// before comparing; use ModFile.Coords() for a normalised display string.
|
||||||
Scope string `toml:"scope"`
|
Scope string `toml:"scope"`
|
||||||
Version string `toml:"version"`
|
Version string `toml:"version"`
|
||||||
Kind string `toml:"kind,omitempty"`
|
Kind string `toml:"kind,omitempty"`
|
||||||
@ -37,6 +41,13 @@ func ParseModFull(b []byte) (*ModFile, error) {
|
|||||||
return &m, nil
|
return &m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Coords returns the canonical display coordinate for the plugin in the form
|
||||||
|
// "@scope/name@version" (or "name@version" when no scope is set).
|
||||||
|
//
|
||||||
|
// The leading "@" on m.Plugin.Scope is intentionally trimmed before
|
||||||
|
// re-prefixing so that authors may write either "@themes" or "themes" in
|
||||||
|
// plugin.mod and get the same output. Callers that need the raw scope as
|
||||||
|
// written should read m.Plugin.Scope directly.
|
||||||
func (m *ModFile) Coords() string {
|
func (m *ModFile) Coords() string {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@ -100,6 +100,20 @@ version = "0.1.0"
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCoords_AcceptsScopeWithOrWithoutAt(t *testing.T) {
|
||||||
|
want := "@themes/foo@1.0.0"
|
||||||
|
|
||||||
|
withAt := &ModFile{Plugin: ModPlugin{Name: "foo", Scope: "@themes", Version: "1.0.0"}}
|
||||||
|
if got := withAt.Coords(); got != want {
|
||||||
|
t.Errorf("Coords() with leading @ = %q, want %q", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
withoutAt := &ModFile{Plugin: ModPlugin{Name: "foo", Scope: "themes", Version: "1.0.0"}}
|
||||||
|
if got := withoutAt.Coords(); got != want {
|
||||||
|
t.Errorf("Coords() without leading @ = %q, want %q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseModFull_RequiresAndCompat(t *testing.T) {
|
func TestParseModFull_RequiresAndCompat(t *testing.T) {
|
||||||
src := []byte(`
|
src := []byte(`
|
||||||
[plugin]
|
[plugin]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user