feat: config settings grouped under ui, values, storage and providers

icons, sourcesView, collapseGroups, loadDelay and expiryWarningDays move
under ui; revealTimeout, hideOnBlur and clipboardClear under values;
cache and history under storage; timeout under providers. share is now
sharing, in the config and in a repo's .lazysecrets.yaml.
This commit is contained in:
keb committed 2026-10-13 19:49:39 +02:00
1 parent b47733e543
commit 46c702a27c
14 files changed
+142 -115

No files matched your search

+60 -45
View File
@@ -19,38 +19,18 @@ import (
)
type Config struct {
Icons *bool `yaml:"icons"`
ClipboardClear *time.Duration `yaml:"clipboardClear"`
// RevealTimeout hides a revealed value after this long; 0s never.
// Defaults to 60s.
RevealTimeout *time.Duration `yaml:"revealTimeout"`
// ExpiryWarningDays marks secrets, keys and certificates expiring
// within this many days; 0 marks only expired ones. Defaults to 30.
ExpiryWarningDays *int `yaml:"expiryWarningDays"`
// HideOnBlur hides a revealed value when the terminal loses focus.
// Defaults to true.
HideOnBlur *bool `yaml:"hideOnBlur"`
Timeout time.Duration `yaml:"timeout"`
// LoadDelay is how long the cursor must rest on a row before its
// contents load; 0s loads at once. Defaults to 150ms.
LoadDelay *time.Duration `yaml:"loadDelay"`
// SourcesView is "grouped" (default) or "flat"; ` + "`" + ` toggles it.
SourcesView string `yaml:"sourcesView"`
// History counts uses of items for the Recent list; defaults to true.
History *bool `yaml:"history"`
UI UI `yaml:"ui"`
// Values keeps revealed and copied values from lingering.
Values Values `yaml:"values"`
// Storage is what's kept between runs.
Storage Storage `yaml:"storage"`
// Updates sets how lazysecrets looks for newer releases.
Updates Updates `yaml:"updates"`
// Cache keeps what was loaded (never values) between runs, so lists
// show at once and refresh in the background; defaults to true.
Cache *bool `yaml:"cache"`
// CollapseGroups starts the Sources pane with its groups folded;
// defaults to true.
CollapseGroups *bool `yaml:"collapseGroups"`
Providers Providers `yaml:"providers"`
Updates Updates `yaml:"updates"`
Providers Providers `yaml:"providers"`
// LinkHandler sets how lazysecrets:// links open; see linkhandler.
LinkHandler LinkHandler `yaml:"linkHandler"`
// Share sets how env files are shared; see package share.
Share Share `yaml:"share"`
// Sharing sets how env files are shared; see package share.
Sharing Sharing `yaml:"sharing"`
// CustomCommands run shell commands on the selected item; see
// package commands.
CustomCommands []commands.Command `yaml:"customCommands"`
@@ -62,6 +42,39 @@ type Config struct {
Theme map[string][]string `yaml:"theme"`
}
type UI struct {
Icons *bool `yaml:"icons"`
// SourcesView is "grouped" (default) or "flat"; ` + "`" + ` toggles it.
SourcesView string `yaml:"sourcesView"`
// CollapseGroups starts the Sources pane with its groups folded;
// defaults to true.
CollapseGroups *bool `yaml:"collapseGroups"`
// LoadDelay is how long the cursor must rest on a row before its
// contents load; 0s loads at once. Defaults to 150ms.
LoadDelay *time.Duration `yaml:"loadDelay"`
// ExpiryWarningDays marks secrets, keys and certificates expiring
// within this many days; 0 marks only expired ones. Defaults to 30.
ExpiryWarningDays *int `yaml:"expiryWarningDays"`
}
type Values struct {
// RevealTimeout hides a revealed value after this long; 0s never.
// Defaults to 60s.
RevealTimeout *time.Duration `yaml:"revealTimeout"`
// HideOnBlur hides a revealed value when the terminal loses focus.
// Defaults to true.
HideOnBlur *bool `yaml:"hideOnBlur"`
ClipboardClear *time.Duration `yaml:"clipboardClear"`
}
type Storage struct {
// Cache keeps what was loaded (never values) between runs, so lists
// show at once and refresh in the background; defaults to true.
Cache *bool `yaml:"cache"`
// History counts uses of items for the Recent list; defaults to true.
History *bool `yaml:"history"`
}
type Updates struct {
// AutoCheck looks for a newer release in the background at startup,
// at most once per AutoCheckInterval; defaults to true. U and
@@ -92,7 +105,7 @@ type LinkHandler struct {
Prompt *bool `yaml:"prompt"`
}
type Share struct {
type Sharing struct {
// Key is the secret whose value encrypts shared files (its
// lazysecrets:// link, Key Vault URL or reference), for repos whose
// .lazysecrets.yaml doesn't name one.
@@ -110,9 +123,11 @@ type KeyRules struct {
}
type Providers struct {
Azure Azure `yaml:"azure"`
Databricks Databricks `yaml:"databricks"`
Repos Repos `yaml:"repos"`
// Timeout bounds each backend request; defaults to 30s.
Timeout time.Duration `yaml:"timeout"`
Azure Azure `yaml:"azure"`
Databricks Databricks `yaml:"databricks"`
Repos Repos `yaml:"repos"`
}
// Repos are git repositories' secret files (SOPS, .env). Inside a repo,
@@ -229,19 +244,19 @@ func decodeInto(c *Config, path string) error {
}
func (c Config) validate(path string) error {
if v := c.SourcesView; v != "" && v != "grouped" && v != "flat" {
return fmt.Errorf("%s: sourcesView: %q is not grouped or flat", path, v)
if v := c.UI.SourcesView; v != "" && v != "grouped" && v != "flat" {
return fmt.Errorf("%s: ui.sourcesView: %q is not grouped or flat", path, v)
}
for _, cmd := range c.CustomCommands {
if err := cmd.Validate(); err != nil {
return fmt.Errorf("%s: %w", path, err)
}
}
if d := c.ExpiryWarningDays; d != nil && *d < 0 {
return fmt.Errorf("%s: expiryWarningDays: %d is negative", path, *d)
if d := c.UI.ExpiryWarningDays; d != nil && *d < 0 {
return fmt.Errorf("%s: ui.expiryWarningDays: %d is negative", path, *d)
}
if d := c.LoadDelay; d != nil && (*d < 0 || *d > 5*time.Second) {
return fmt.Errorf("%s: loadDelay: %s is not between 0s and 5s", path, *d)
if d := c.UI.LoadDelay; d != nil && (*d < 0 || *d > 5*time.Second) {
return fmt.Errorf("%s: ui.loadDelay: %s is not between 0s and 5s", path, *d)
}
if d := c.Updates.AutoCheckInterval; d != nil && *d <= 0 {
return fmt.Errorf("%s: updates.autoCheckInterval: %s is not positive (autoCheck: false turns it off)", path, *d)
@@ -251,16 +266,16 @@ func (c Config) validate(path string) error {
return fmt.Errorf("%s: updates.updateSources[%d]: %q is not an https:// repository address, like %s", path, i, r, update.GitHubRepo)
}
}
if k := c.Share.Key; k != "" {
if k := c.Sharing.Key; k != "" {
if _, err := share.ParseKey(k); err != nil {
return fmt.Errorf("%s: share.key: %w", path, err)
return fmt.Errorf("%s: sharing.key: %w", path, err)
}
}
if n := c.Share.KeyRules.MinLength; n != 0 && n < 16 {
return fmt.Errorf("%s: share.keyRules.minLength: %d is under 16", path, n)
if n := c.Sharing.KeyRules.MinLength; n != 0 && n < 16 {
return fmt.Errorf("%s: sharing.keyRules.minLength: %d is under 16", path, n)
}
if n := c.Share.KeyRules.MinClasses; n < 0 || n > 4 {
return fmt.Errorf("%s: share.keyRules.minClasses: %d is not between 1 and 4", path, n)
if n := c.Sharing.KeyRules.MinClasses; n < 0 || n > 4 {
return fmt.Errorf("%s: sharing.keyRules.minClasses: %d is not between 1 and 4", path, n)
}
for i, v := range c.Providers.Azure.Vaults {
if !strings.HasPrefix(v, "https://") {