aboutsummaryrefslogtreecommitdiff
path: root/internal/engine/apply.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/engine/apply.go')
-rw-r--r--internal/engine/apply.go24
1 files changed, 23 insertions, 1 deletions
diff --git a/internal/engine/apply.go b/internal/engine/apply.go
index 09f3aab..cc87f30 100644
--- a/internal/engine/apply.go
+++ b/internal/engine/apply.go
@@ -113,7 +113,10 @@ func (e *Engine) applyFile(dirName string, c plan.Chain, approved bool, j *journ
// Each step is logged the moment it has run (review M9), not after the
// whole chain: a run killed mid-chain must leave what it did undoable.
results, err := apply.ChainLogged(c, func(i int, sr apply.StepResult) error {
- return e.logStep(j, run, dirName, rel, i+1, c.Steps[i], sr)
+ if err := e.logStep(j, run, dirName, rel, i+1, c.Steps[i], sr); err != nil {
+ return unloggedStep(rel, c.Steps[i], sr, err)
+ }
+ return nil
})
if err != nil {
return FileResult{}, err
@@ -121,6 +124,25 @@ func (e *Engine) applyFile(dirName string, c plan.Chain, approved bool, j *journ
return FileResult{File: c.File, Steps: results}, nil
}
+// unloggedStep is the error for a step whose log entry could not be written
+// (re-review N1). A step that ran is named with where its file is now:
+// undo cannot see it, so the user must be told where to look.
+func unloggedStep(rel string, step plan.Step, sr apply.StepResult, err error) error {
+ if sr.Status != "ok" {
+ return fmt.Errorf("%s: step %s (%s) could not be logged: %w", rel, actionName(step.Kind), sr.Status, err)
+ }
+ var where string
+ switch {
+ case step.Kind == plan.Copy:
+ where = "a copy is at " + xdg.Abbrev(sr.Dst)
+ case sr.Dst != "":
+ where = "the file is now at " + xdg.Abbrev(sr.Dst)
+ default:
+ where = "the file is deleted for good"
+ }
+ return fmt.Errorf("%s: %s ran but could not be logged, so undo cannot see it (%s): %w", rel, actionName(step.Kind), where, err)
+}
+
// tallyFile updates result's Applied/Failed/Declined counters from one
// file's step outcomes. The three are not mutually exclusive: a chain that
// ran one step ok and then failed on the next counts toward both Applied