summaryrefslogtreecommitdiff
path: root/internal/apply/apply.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/apply/apply.go')
-rw-r--r--internal/apply/apply.go12
1 files changed, 10 insertions, 2 deletions
diff --git a/internal/apply/apply.go b/internal/apply/apply.go
index 684641e..a93aad4 100644
--- a/internal/apply/apply.go
+++ b/internal/apply/apply.go
@@ -7,6 +7,7 @@
package apply
import (
+ "context"
"errors"
"fmt"
"os"
@@ -44,7 +45,7 @@ type StepResult struct {
// marking the rest skipped. It never touches a file whose size or mtime no
// longer matches what the plan recorded. It is ChainLogged with no done.
func Chain(c plan.Chain) []StepResult {
- results, _ := ChainLogged(c, nil)
+ results, _ := ChainLogged(context.Background(), c, nil)
return results
}
@@ -58,11 +59,18 @@ func Chain(c plan.Chain) []StepResult {
// planned destination was taken since planning, stops the chain too: every
// later step was planned against the name the file did not get, and must
// not act on whatever is at that path (review M3).
-func ChainLogged(c plan.Chain, done func(i int, sr StepResult) error) ([]StepResult, error) {
+//
+// Once ctx is cancelled (an interrupt), the step already under way finishes
+// and every later step is skipped as "interrupted": an interrupt stops after
+// the current step, not after the file's whole chain (spec ยง11).
+func ChainLogged(ctx context.Context, c plan.Chain, done func(i int, sr StepResult) error) ([]StepResult, error) {
results := make([]StepResult, len(c.Steps))
stopWhy := ""
for i, step := range c.Steps {
+ if stopWhy == "" && ctx.Err() != nil {
+ stopWhy = "interrupted"
+ }
switch {
case stopWhy != "":
results[i] = StepResult{Step: step, Status: "skipped", Detail: stopWhy}