Skip to content

v2.1.0

Choose a tag to compare

@andreimerlescu andreimerlescu released this 09 Apr 01:17
· 18 commits to main since this release
6a8eb43

What's Changed

  • Fix type errors, comment accuracy, test hygiene, and harvest normalization by @andreimerlescu in #19

v2.0.15

New Features

  • Alias Support — Register alternate flag names for any fig using
    figs.WithAlias(name, alias). Aliases are fully integrated with validators,
    callbacks, rules, getters, and setters — anything that works on the canonical
    name works identically on the alias.

    figs := figtree.Grow()
    figs.NewString("verbose", "false", "enable verbose output")
    figs.WithAlias("verbose", "v")
    figs.Parse() // accepts both -verbose and -v
    
    figs.StoreString("v", "true")       // store via alias
    *figs.String("verbose")             // "true" — canonical reflects alias store
    *figs.String("v")                   // "true" — alias reflects alias store
  • WithValidators() — Register multiple validators against a fig in a
    single call instead of chaining repeated WithValidator() calls.

    figs.WithValidators("host",
        figtree.AssureStringNotEmpty,
        figtree.AssureStringHasPrefix("https://"),
        figtree.AssureStringLengthLessThan(253),
    )
  • Problems() — Inspect non-fatal registration errors accumulated during
    tree construction (e.g. duplicate aliases, missing fig names). Available on
    the Divine interface without requiring a type assertion.

    if problems := figs.Problems(); len(problems) > 0 {
        for _, p := range problems {
            log.Println("figtree:", p)
        }
    }

Bug Fixes

  • AssureBoolTrue / AssureBoolFalse — Both previously returned
    ErrInvalidType{tString, value} on non-bool input. Fixed to correctly return
    ErrInvalidType{tBool, value}.

  • AssureListMinLength — Error message previously said "list is empty"
    even when the list was non-empty but shorter than the required minimum. Now
    correctly reports the required minimum and the actual length.

  • StoreMap with =-containing values — Map values containing =
    characters (e.g. URLs with query strings) were silently truncated during
    persistence. Fixed by using SplitN(..., 2) to preserve the full value.

  • Recall() channel capacity — With() computed a normalized buffer size
    (chBuf) for the initial mutations channel but stored the raw opts.Harvest
    in tree.harvest. Since Recall() uses tree.harvest to size the new
    channel, a zero or negative Harvest would silently create an unbuffered
    channel after a Curse()/Recall() cycle. Fixed by storing the normalized
    value.

  • Deadlock in Store() — Store() held tree.mu while sending on
    mutationsCh. If the channel buffer was full, the send would block
    indefinitely, stalling all concurrent tree operations. Fixed by releasing
    tree.mu before the channel send and re-acquiring after.

  • MutagenesisOfFig() — Was acquiring an exclusive write lock (Lock())
    for a read-only operation. Changed to RLock()/RUnlock().

Test Coverage

  • 317 tests passing across all platforms (Ubuntu, macOS, Windows) on Go 1.23
    and 1.24.
  • New tests covering alias idempotency, alias conflict detection, validator
    registration via alias, storing through an alias, concurrent pollinate reads
    under alias resolution, Recall() channel capacity after Curse(), and
    map values containing separator characters.

Full Changelog: v2.0.14...v2.1.0