Repository navigation
v0.1.3
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 (directories0700, files0640). Previously this required wiring up aDirresource by hand withWithSourceGlobplus 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 withDependsOn.LinkIfExists— create a symlink only when its target currently exists; otherwise ensure the link is absent. No more writing existence checks yourself.SymlinkMap— declare manyname → targetsymlinks under a parent directory in one call.GitGlobal— setgit config --globalkey/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. alldemo_*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
Taskcalls to the new struct-basedDemotype, demonstrating the recommended registration style and the new helpers (InstallFile,SyncDir,LinkIfExists) in practice. - More consistent path handling: helpers like
SyncDir,InstallFile, andLinkIfExistsresolve~and~/...prefixes for you via theExpand/Homepath 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.gocovers the new helpers: path expansion and~resolution,And/Orpredicate logic,Aggregate,EnsureDir,LinkIfExists/SymlinkMap,SyncDir/InstallFile, andGitGlobal(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 oldRegister()example did), you can keep doing so, but the new preferred style isRegisterMethodson a struct. Theapi.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.gonow exposes methods on aDemostruct instead of package-leveldemo*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.