What’s New in goopt v2
goopt v2 is a major update focused on providing powerful, out-of-the-box solutions for building professional, robust, and user-friendly command-line applications.
New Major Features
Runtime Shell Completion (Replaces the static generator)
Shell completion is now computed at runtime by the live parser instead of being
baked into a large static script. goopt installs a tiny stub that forwards each <TAB>
back to your program, and the parser answers from its one true model.
- Cannot drift: completion offers exactly what the parser accepts — inherited flags on subcommands included. There is no second command-tree model to keep in sync.
- Dynamic values: compute a flag’s candidates at completion time (git branches, files,
service data) with
WithCompleter— impossible with a static script. - Smaller surface: one forwarding stub + one formatter per shell, instead of a full completion script generator per shell.
- Breaking change: the static
GenerateCompletion/GetCompletionDataAPI has been removed. Migration is small (add oneHandleCompletionline, swap toGenerateCompletionStub, moveAcceptedValues→WithCompleter). - ➡️ Read the Shell Completion Guide · Migrating from static completion
Validators Drive Completion (and are now an interface)
A validator can now supply its own completion candidates, so a value-restricting validator also powers shell completion — one declaration, no chance of the validated set and the completed set drifting apart.
validation.IsOneOfboth validates and completes:WithValidators(validation.IsOneOf("a","b"))rejects anything outside the set and offers it on<TAB>. Any validator implementingEnumerable(Candidates() []string) does the same.- Breaking change:
validation.Validatoris now an interface (Validate(string) error), and the validator setters (WithValidator(s),SetValidators,AddFlagValidators,SetFlagValidators,WithFlagValidators) take it. Built-in validators andvalidation.Custom(...)are unchanged; a bare inlinefunc(string) errormust be wrapped invalidation.Custom(...), and[]validation.ValidatorFuncbecomes[]validation.Validator. - Automated migration: the
goopt-migrate-v2codegen tool does the wrapping and slice-rename for you:go install github.com/napalu/goopt/v2/cmd/goopt-migrate-v2@latest goopt-migrate-v2 -d . -r --dry-run # preview; drop --dry-run to apply(Distinct binary from the v1→v2
goopt-migratetool, so both can be installed.) - ➡️ Migration tool details · see the
v2/migrationpackage README
A Powerful Validation Engine (Replaces accepted)
The old accepted tag has been deprecated in favor of a completely new validation engine that is more powerful, composable, and easier to use.
- Directly in Struct Tags: Define complex validation rules right where you define your flag.
- Composable Logic: Chain built-in validators (
email,port,range) or combine them with logical operators (oneof,all,not). - Custom Validators: Easily write and integrate your own domain-specific validation logic.
- Clearer Syntax: The new
validatorstag uses a more intuitive parenthesis-based syntax (e.g.,validators:"minlength(5)"). - ➡️ Read the Validation Guide
Flag Contracts (Relational Constraints)
Where validators check a single value, contracts declare constraints between flags —
mutual exclusion, co-requirement, and conditional requirement — declaratively, replacing
hand-written RequiredIf callbacks for the common cases.
- Five primitives:
mutex(at most one),exactlyone(exactly one),conflicts,requires, andrequiredOn(required when another flag/command is present). - All three paradigms: struct tags (
contract:"mutex(format)"), option funcs (WithMutex), or programmatic accessors (AddFlagContracts/SetFlagContracts/GetFlagContracts). - Friendly, translated errors: user-facing messages name the flags actually typed and ship in every built-in locale; misspelled group names are caught as developer-facing construction errors.
- ➡️ Read the Contracts Guide
Command Execution Hooks
Manage the entire lifecycle of your commands with pre- and post-execution hooks. This is perfect for handling cross-cutting concerns without cluttering your command logic.
- Use cases: Authentication checks, database connection management, logging, metrics, and resource cleanup.
- Flexible scope: Apply hooks globally to all commands or target specific commands.
- ➡️ Read the Execution Hooks Guide
Advanced Help & Version Systems
The help and version systems are now fully automatic and highly configurable.
- Auto-Help:
--helpand-hflags are now provided by default, with an adaptive display style that suits your CLI’s complexity. - Interactive Help: Users can now query the help system with commands like
myapp --help --search "database". - Intelligent Suggestions: Automatic “did you mean?” suggestions for mistyped commands and flags with customizable distance thresholds.
- Auto-Version: Enable a
--versionflag with a single line of configuration, with support for dynamic build-time variables. - ➡️ See the Help System Guide and Version Support Guide
Architectural Improvements
Enhanced Internationalization (i18n)
The i18n system has been significantly enhanced with new features for true global application support.
- Layered Bundles: A clearer separation between the default system bundle and your application’s user bundle.
- Runtime-Switchable Names: New
nameKeytag allows translating flag and command names, not just descriptions. Users can interact with your CLI using commands and flags in their native language. - Context-Aware Suggestions: The “did you mean?” system intelligently detects whether users are typing in the canonical or translated language and shows suggestions accordingly.
- JIT Translation Registry: Just-In-Time building of translation mappings optimizes startup time by constructing name-to-flag/command mappings only when needed.
- Auto-Language Detection: Sophisticated language detection from command-line flags, environment variables, and (optionally) system locale settings.
- RTL Language Support: Automatic right-to-left layout detection and formatting for languages like Arabic and Hebrew.
- Locale-Aware Formatting: Numbers and dates are automatically formatted according to the user’s locale (e.g., 1,000 vs 1.000 vs 1’000).
- Regional Variants: Full support for regional language variants like Swiss German (de-CH) or Canadian French (fr-CA).
- Smart Error Formatting: Validation errors intelligently format numbers based on format specifiers (%d vs %s).
- Naming Consistency Warnings: New warning system helps maintain consistent naming conventions across translations and canonical names.
- Extended Language Support: Easy addition of new languages through locale packages or runtime loading.
- Improved Tooling: The
goopt-i18n-gentool is more powerful than ever, with a “360° workflow” to automate adding i18n to existing projects. - ➡️ Read the i18n Guide
Hierarchical Flag Inheritance
Flag handling is now fully hierarchical and more predictable.
- Parent-child flag resolution: Flags defined on parent commands are available to all children.
- Clear precedence rules: Command-specific flags correctly override inherited flags.
- ➡️ See the Flag Inheritance Guide
API Cleanup
The public API has been modernized and simplified.
- Deprecated methods from v1 have been removed.
- Naming has been made more consistent throughout the library.
- Error handling at initialization is more robust with the introduction of
NewArgE.
Breaking Changes
For a complete list of breaking changes and instructions on how to update your code from v1, please see the Migration Guide.