feat: status command + windows toast notifications
- status: read-only report of deployed/repository revision, pending changes, skipped items (with reasons), unrecognized local items, binary version; --json machine-readable; exit 1 when local modifications block repository updates (headless drift checks) - sync/status share a read-only prepare() front half - notify package: windows toast via PowerShell script (go-toast mechanism, zero deps, build-tag gated), noop on linux/macos; cross-compile verified - toast fires exactly once per sync with warnings, never for routine syncs; notification failures are logged and never fail the sync (fail-open)
This commit is contained in:
+25
-6
@@ -15,11 +15,19 @@ type SyncOptions struct {
|
||||
ConfigPath string
|
||||
}
|
||||
|
||||
// Sync pulls the work repository, plans the sync as a pure function over
|
||||
// (inventory, manifest, disk facts) and executes the plan. Validation and
|
||||
// hashing happen before the first mutation; unreachable repositories fail
|
||||
// cleanly with the previous state intact.
|
||||
func Sync(opts SyncOptions, stdout io.Writer) (*SyncReport, error) {
|
||||
// prepared is everything sync and status share: the pulled repository, the
|
||||
// planned action list, and the local state — before any mutation.
|
||||
type prepared struct {
|
||||
paths StatePaths
|
||||
pull *PullResult
|
||||
manifest *Manifest
|
||||
items []PlannedItem
|
||||
plan []PlanEntry
|
||||
}
|
||||
|
||||
// prepare pulls, inventories, hashes and plans — the complete read-only
|
||||
// front half of a client run.
|
||||
func prepare(opts SyncOptions) (*prepared, error) {
|
||||
cfg, err := LoadClientConfig(opts.ConfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -71,8 +79,19 @@ func Sync(opts SyncOptions, stdout io.Writer) (*SyncReport, error) {
|
||||
return nil, fmt.Errorf("refusing unsafe deploy path %q", e.DstPath)
|
||||
}
|
||||
}
|
||||
return &prepared{paths: paths, pull: pull, manifest: manifest, items: items, plan: plan}, nil
|
||||
}
|
||||
|
||||
return ExecutePlan(pull.Tree, plan, manifest, paths, pull.Rev, stdout)
|
||||
// Sync pulls the work repository, plans the sync as a pure function over
|
||||
// (inventory, manifest, disk facts) and executes the plan. Validation and
|
||||
// hashing happen before the first mutation; unreachable repositories fail
|
||||
// cleanly with the previous state intact.
|
||||
func Sync(opts SyncOptions, stdout io.Writer) (*SyncReport, error) {
|
||||
p, err := prepare(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ExecutePlan(p.pull.Tree, p.plan, p.manifest, p.paths, p.pull.Rev, stdout)
|
||||
}
|
||||
|
||||
// safePath rejects destinations that escape the user's home directory.
|
||||
|
||||
Reference in New Issue
Block a user