themecmd

package
v0.11.0 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package themecmd holds the shared logic behind the `keryx theme` subcommands (list/show/add/edit/rm). The subcommand packages are thin wrappers that extract flags/args and call these functions; the catalog logic itself lives in internal/theme.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Add

func Add(ctx context.Context, p *props.Props, keyword, from string, set []string) error

Add creates or clones a theme and persists it.

func Arg

func Arg(args []string, usage string) (string, error)

Arg returns the first positional (the theme keyword) or a usage error.

func DefinedIn added in v0.9.0

func DefinedIn(ctx context.Context, p *props.Props, keyword string, scope Scope) bool

DefinedIn reports whether a scope contributes any part of a theme. Exported for callers that need to reason about scope without resolving the theme itself.

func Edit

func Edit(ctx context.Context, p *props.Props, keyword string, set []string) error

Edit applies --set changes to an existing theme.

The theme is FOUND in the merged catalog — so an inherited library theme can be edited from inside a project, which forks it into the project file — but the write goes through [scoped], like add and rm.

This was the last mutation persisting the MERGED catalog to the LAYERED store, which is two faults at once. Outside a project that store has no writable layer, so `theme edit` failed with `no writable layer for change: themes` for any user-library theme (reproduced on the released binary; it predates 0047). And inside a project it would fork every inherited theme into the committed config, which is precisely what `theme rm` was fixed for.

func List

func List(ctx context.Context, p *props.Props) error

List prints the catalog: one flat list, because there is one (spec 0047 D4).

func Migrate added in v0.9.0

func Migrate(ctx context.Context, p *props.Props, dryRun bool, chosenDefault string) error

Migrate moves every theme in the legacy user config into the user theme library, and removes it from the legacy file.

The library is written FIRST and the legacy entries dropped only once that succeeded — the same ordering as promotion, and for the same reason: a failure between the two leaves a duplicate, which is recoverable, rather than nothing.

Themes already present in the library are not overwritten. A theme that was promoted from a project after the legacy copy was written is the NEWER one, and silently replacing it with a stale duplicate would undo deliberate work.

func Pin added in v0.9.0

func Pin(ctx context.Context, p *props.Props, keyword string) error

Pin copies a USER theme into the project's committed config, so a build that has no user config — CI — resolves it too (spec 0046 Q2). It is the mirror of Promote, and the project's declared dependency on a style.

It copies from the USER layer specifically, not from the resolved catalog. Once a theme is pinned it exists in both layers and the project's copy WINS, so copying the resolved theme would write the project's own version back over itself — a no-op dressed as a refresh.

func Promote added in v0.9.0

func Promote(ctx context.Context, p *props.Props, keyword string) error

Promote copies a PROJECT theme into the user library, so every project can use it. Authoring happens against a real reel, in a project; without this the theme is stranded there (spec 0046 §3.4).

It copies rather than moves: the project keeps its committed definition, which is what CI reads (D3).

func Remove

func Remove(ctx context.Context, p *props.Props, keyword string) error

Remove deletes a theme.

func Show

func Show(ctx context.Context, p *props.Props, keyword string) error

Show prints one theme's full definition.

func Use added in v0.9.0

func Use(ctx context.Context, p *props.Props, keyword string, scope Scope) error

Types

type MigrateResult added in v0.9.0

type MigrateResult struct {
	Moved    []string `json:"moved"`
	From     string   `json:"from"`
	To       string   `json:"to"`
	DryRun   bool     `json:"dry_run"`
	Defaults bool     `json:"defaults_moved"`
	// Flat describes the 0047 flattening applied to the library after the move.
	Flat *theme.FlatSummary `json:"flat,omitempty"`
	// Project describes the same flattening applied to the PROJECT's .keryx.yaml,
	// when run inside one. Nil when there is no project, or nothing to flatten.
	//
	// The project file needs it as much as the library does: since 0047 a nested
	// catalog is refused outright, and a project committing one would make every
	// generation in that repo fail with a message pointing at this command. A fix
	// the fix cannot reach is not a fix.
	Project     *theme.FlatSummary `json:"project,omitempty"`
	ProjectFile string             `json:"project_file,omitempty"`
}

MigrateResult reports what a migration did (or would do, when a dry run).

type Scope added in v0.9.0

type Scope string

Use makes an existing theme the catalog default, so commands resolve to it when --theme is omitted.

The write lands wherever the rest of the theme edits land — the config system routes it to the highest-precedence writable layer, which is the project's .keryx.yaml inside a project and the user config outside one. That is deliberate: writing anywhere else would leave the edit shadowed by a layer that still wins, which reads as a write that silently did nothing. The command reports the file so the scope is never a guess. Scope selects which config file a default is written to. Empty lets the config system route it — to the layer where the key already wins, which is what makes the value you set the value you read back.

const (
	// ScopeProject pins the write to the project's .keryx.yaml, so the default
	// travels with the repo and reaches CI.
	ScopeProject Scope = "project"
	// ScopeUser pins the write to the user config, so it applies across projects.
	ScopeUser Scope = "user"
)

func ScopeOfTheme added in v0.9.0

func ScopeOfTheme(ctx context.Context, p *props.Props, keyword string) Scope

ScopeOfTheme reports which config scope a theme is defined in, or "" when it is not defined at all. This is the provenance `theme list` shows and `promote` checks: "where does this come from?" was previously unanswerable, and it is the question you ask before editing or promoting a theme (spec 0046 §3.4).

Jump to

Keyboard shortcuts

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