diff options
Diffstat (limited to 'cmd/krino')
| -rw-r--r-- | cmd/krino/sort.go | 7 | ||||
| -rw-r--r-- | cmd/krino/undo.go | 59 |
2 files changed, 25 insertions, 41 deletions
diff --git a/cmd/krino/sort.go b/cmd/krino/sort.go index 4c0a0d8..54d5574 100644 --- a/cmd/krino/sort.go +++ b/cmd/krino/sort.go @@ -104,6 +104,13 @@ func cmdSort(g *globals, names []string, stdout, stderr io.Writer) int { fmt.Fprintf(stderr, "krino: %v\n", err) return 1 } + // Sorting opens the log before the first directory, as it always has: + // the run id is fixed for every directory, and a failure to open is + // reported before anything is planned. + if err := sess.OpenLog(); err != nil { + fmt.Fprintf(stderr, "krino: %v\n", err) + return 1 + } defer func() { if cerr := sess.Close(); cerr != nil { fmt.Fprintf(stderr, "krino: %v\n", cerr) diff --git a/cmd/krino/undo.go b/cmd/krino/undo.go index ecab2f3..5a7db4b 100644 --- a/cmd/krino/undo.go +++ b/cmd/krino/undo.go @@ -15,9 +15,7 @@ import ( "golang.org/x/term" - "krino/internal/config" "krino/internal/engine" - "krino/internal/journal" "krino/internal/lock" "krino/internal/xdg" ) @@ -113,7 +111,18 @@ func cmdUndo(g *globals, args []string, stdout, stderr io.Writer) int { // PlanUndo only reads the log; nothing is touched yet (spec ยง10), which // is what makes it safe to call before any lock is taken. - up, err := e.PlanUndo(runID) + sess, err := e.NewSession(g.dry) + if err != nil { + fmt.Fprintf(stderr, "krino: %v\n", err) + return 1 + } + defer func() { + if cerr := sess.Close(); cerr != nil { + fmt.Fprintf(stderr, "krino: %v\n", cerr) + } + }() + + up, err := sess.PlanUndo(runID) if err != nil { fmt.Fprintf(stderr, "krino: %v\n", err) return 1 @@ -137,7 +146,7 @@ func cmdUndo(g *globals, args []string, stdout, stderr io.Writer) int { // right after acquisition. var locks []*lock.Lock if !g.dry { - locks, err = acquireUndoLocks(ctx, e.Config, undoDirNames(up.Files), !g.yes) + locks, err = sess.LockDirs(ctx, undoDirNames(up.Files), !g.yes) if err != nil { if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { return 130 @@ -197,26 +206,12 @@ func cmdUndo(g *globals, args []string, stdout, stderr io.Writer) int { // Ruling 2 (Task 7), carried over: journal.Open creates the state // directory and the log file as a side effect of merely being called, - // so it is opened only once we know something will actually be + // so the session opens it only now, when something will actually be // applied - never for -n (returned above), and not merely because -y - // or a review session ran, unlike cmdSort's own eager-open (which opens - // before it knows whether anything is actionable, a difference forced - // by cmdSort not yet having a plan to inspect at that point in its - // flow; undo already does, so it opens later, and never opens if - // undoActionableCount was 0 or the user chose [s]/[q] above). - j, err := journal.Open(e.Config.LogFile()) - if err != nil { - fmt.Fprintf(stderr, "krino: %v\n", err) - return 1 - } - defer func() { - if cerr := j.Close(); cerr != nil { - fmt.Fprintf(stderr, "krino: %v\n", cerr) - } - }() - run := journal.NewRunID(e.Now()) - - res, aerr := e.ApplyUndo(ctx, toApply, j, run) + // or a review session ran, unlike cmdSort, which opens before it knows + // whether anything is actionable (a difference forced by cmdSort not + // yet having a plan to inspect at that point in its flow). + res, aerr := sess.ApplyUndo(ctx, toApply) if aerr != nil { if errors.Is(aerr, context.Canceled) || errors.Is(aerr, context.DeadlineExceeded) { // Interrupted mid-apply: the ctx.Err() check below turns this @@ -269,24 +264,6 @@ func undoDirNames(files []engine.UndoFile) []string { return out } -// acquireUndoLocks takes the lock for every name in dirs, in order, -// mirroring cmdSort's per-directory lock.Acquire call. If any acquisition -// fails - held with wait false, or ctx cancelled while waiting - every lock -// already taken is released before returning, so a partial lock set is -// never left held while the caller reports the error and stops. -func acquireUndoLocks(ctx context.Context, cfg *config.Config, dirs []string, wait bool) ([]*lock.Lock, error) { - locks := make([]*lock.Lock, 0, len(dirs)) - for _, name := range dirs { - l, err := lock.Acquire(ctx, cfg.LockFile(name), wait) - if err != nil { - releaseUndoLocks(locks) - return nil, fmt.Errorf("%s: %w", name, err) - } - locks = append(locks, l) - } - return locks, nil -} - // releaseUndoLocks releases every lock in locks and returns any release // errors, one lock's failure never stopping the rest from being released - // the same "release on every path" guarantee cmdSort gives its own single |
