go-spf13-viper

Configures layered Go application settings with viper precedence, env binding, and hot reload.

1|2|Updated Nov 25, 2017
One-click install
npx skills add https://github.com/asarchami/dotfiles --skill go-spf13-viper-asarchami
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: go-spf13-viper
Source: https://github.com/asarchami/dotfiles/tree/main/dot_config/opencode/skills/go/go-spf13-viper
Command: npx skills add https://github.com/asarchami/dotfiles --skill go-spf13-viper-asarchami

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill requires github.com/spf13/viper, github.com/spf13/pflag, github.com/mitchellh/mapstructure, github.com/fsnotify/fsnotify, and includes references (resource) components.

What problem does it solve? Go applications often read configuration from flags, environment variables, files, and defaults simultaneously, and keys silently resolve from the wrong layer. This Skill guides correct use of spf13/viper so every key resolves predictably, missing config files do not crash the app, and tests stay isolated. ## Core Features & Use Cases - Precedence pipeline discipline: Walk the fixed order (Set > flag > env > file > KV > default) so you always know which layer supplies each key. - Env and flag binding: Wire SetEnvPrefix, SetEnvKeyReplacer, and AutomaticEnv together, and bind cobra flags with BindPFlag before Execute(). - Struct unmarshaling and reload: Decode into structs with mapstructure tags and DecodeHooks, and handle WatchConfig hot reload including the atomic-rename trap. - Use Case: You are building a CLI where --port, MYAPP_PORT, and config.yaml all define a port. This Skill shows how to bind all three so the flag wins when set, env wins otherwise, and a missing file never crashes startup. ## Quick Start Ask the assistant to wire viper configuration for a Go CLI with env prefix MYAPP, a YAML config file, and a bound port flag.

Frequently Asked Questions about go-spf13-viper

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I bind environment variables to viper config keys in Go?

Call SetEnvPrefix, SetEnvKeyReplacer with a dot-to-underscore replacer, and AutomaticEnv together before reading values. Without the replacer, nested keys like database.host resolve to MYAPP_DATABASE.HOST and never match a real env var.

What is the viper config precedence order?

Viper resolves keys in a fixed order: explicit Set, bound pflag, environment variable, config file, remote KV, then default. The order cannot be reordered, so a flag or env var always shadows a config file value.

Why does viper not find my config file without crashing?

Use errors.As with viper.ConfigFileNotFoundError after ReadInConfig and only propagate other errors. A missing file is a normal state when flags and env vars supply the configuration, while corrupt files should still fail loudly.

Does viper WatchConfig detect editor saves?

Not reliably. Editors like vim save via atomic rename, which replaces the watched inode so the fsnotify callback may not fire. Test reload with direct writes like os.WriteFile or appending to the file instead of editor saves.

How do I test viper config without flaky global state?

Create a fresh viper.New() instance per test instead of using the global viper functions, and inject *viper.Viper into your application code. Combine with t.Setenv to test env binding without polluting other tests.

When should I use UnmarshalKey instead of viper Sub?

Prefer UnmarshalKey("database", &cfg) because it decodes a subtree directly without the nil check that Sub requires when the key is missing. Always tag struct fields with mapstructure tags so nested and underscore-named keys decode correctly.