Skip to content

v0.1.3

Choose a tag to compare

@snonux snonux released this 17 Sep 05:35
· 617 commits to main since this release

Release v0.1.3

I'll generate the release notes based on the commits and code changes provided.

Highlights

This release is all about making gonf easier to use and more capable. The biggest change is a new set of convenience helpers in the api package that collapse common configuration patterns into single, readable function calls. On top of that, task definitions now support a cleaner struct-based registration style, and directory/file syncing gets proper one-liners.

Features

New high-level helpers

A collection of new functions in the api package removes boilerplate for the most common configuration tasks:

  • SyncDir — copy every file matching a glob into a destination directory in one call, with sensible default permissions (directories 0700, files 0640). Previously this required wiring up a Dir resource by hand with WithSourceGlob plus explicit mode options.
  • InstallFile — copy a single source file to a destination with a safe default mode (0640), again in a single call.
  • EnsureDir — register a directory only if it doesn't already exist, so existing directories (including symlinks to directories) are left untouched. Safe to use with DependsOn.
  • LinkIfExists — create a symlink only when its target currently exists; otherwise ensure the link is absent. No more writing existence checks yourself.
  • SymlinkMap — declare many name → target symlinks under a parent directory in one call.
  • GitGlobal — set git config --global key/value pairs idempotently, skipping any value that already matches.
  • Aggregate — register a single task that runs every other task whose name matches a pattern (e.g. all demo_* tasks). Replaces the previous hand-written "run everything" wrapper.

Composable predicates

New And and Or helpers let you combine conditional predicates (like ProfileIs) when deciding whether a task or resource should apply. This makes profile- and OS-specific configuration much less repetitive.

Struct-based task registration

Tasks can now be declared as methods on a struct and registered all at once via RegisterMethods with an optional name prefix (e.g. demo_). Each method automatically gets a description from a paired Desc<Name> method. This replaces the older pattern of manually calling Task(...) for each demo and keeps task names, descriptions, and bodies together in one place.

Improvements

  • Cleaner example wiring: the example task set was refactored from individual Task calls to the new struct-based Demo type, demonstrating the recommended registration style and the new helpers (InstallFile, SyncDir, LinkIfExists) in practice.
  • More consistent path handling: helpers like SyncDir, InstallFile, and LinkIfExists resolve ~ and ~/... prefixes for you via the Expand/Home path utilities, so home-relative paths just work.
  • Less boilerplate for the user: the options pattern was made more generic, and dot-imports in the example code reduce repetitive qualification.

Tests

  • A new api/helpers_test.go covers the new helpers: path expansion and ~ resolution, And/Or predicate logic, Aggregate, EnsureDir, LinkIfExists/SymlinkMap, SyncDir/InstallFile, and GitGlobal (in dry-run mode). This gives the new convenience layer solid coverage from the start.

Breaking changes

  • Task registration style: if you were defining tasks by calling Task(...) directly (as the old Register() example did), you can keep doing so, but the new preferred style is RegisterMethods on a struct. The api.Register-style examples have been updated; migrate your task declarations to the struct pattern to match the current examples.
  • Example file layout: the demo code in examples/examples.go now exposes methods on a Demo struct instead of package-level demo* functions. External code that imported those functions will need updating.

No changes to the core resource semantics or on-disk behavior were introduced in this release.