74 lines
2.1 KiB
Go
74 lines
2.1 KiB
Go
package session
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
// DetectExternalChanges compares the current workspace state against the
|
|
// EndManifest recorded in .ctask/last-session-summary.json.
|
|
//
|
|
// Returns (nil, nil) if no summary exists (pre-v0.4 workspace or first
|
|
// session ever) — callers should treat this as "silently skip the warning".
|
|
//
|
|
// Returns a non-nil diff with empty slices when nothing changed outside a
|
|
// ctask session.
|
|
func DetectExternalChanges(wsDir string) (*ManifestDiff, error) {
|
|
summary, err := ReadSummary(SummaryPath(wsDir))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if summary == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
previous := &Manifest{
|
|
CapturedAt: summary.EndedAt,
|
|
Files: append([]FileEntry{}, summary.EndManifest...),
|
|
}
|
|
current, err := CaptureManifest(wsDir)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return DiffManifests(previous, current), nil
|
|
}
|
|
|
|
// FormatStaleWarning renders the Layer-3 warning shown when the workspace
|
|
// was modified outside a ctask session since the last session ended.
|
|
func FormatStaleWarning(summary *SessionSummary, diff *ManifestDiff) string {
|
|
var b strings.Builder
|
|
b.WriteString("[ctask] Workspace modified since last session ended:\n\n")
|
|
fmt.Fprintf(&b, " Last session: %s (%s, %s)\n\n",
|
|
summary.EndedAt.Local().Format("2006-01-02 15:04"),
|
|
summary.Hostname, summary.Agent)
|
|
b.WriteString(" Modified since then:\n")
|
|
|
|
lines := append([]string{}, diff.Modified...)
|
|
sort.Strings(lines)
|
|
for _, f := range lines {
|
|
fmt.Fprintf(&b, " %s (modified)\n", f)
|
|
}
|
|
added := append([]string{}, diff.Added...)
|
|
sort.Strings(added)
|
|
for _, f := range added {
|
|
fmt.Fprintf(&b, " %s (new file)\n", f)
|
|
}
|
|
deleted := append([]string{}, diff.Deleted...)
|
|
sort.Strings(deleted)
|
|
for _, f := range deleted {
|
|
fmt.Fprintf(&b, " %s (deleted)\n", f)
|
|
}
|
|
b.WriteString("\n These changes were not made during a ctask session.\n")
|
|
b.WriteString(" Review before continuing? [Y/n] ")
|
|
return b.String()
|
|
}
|
|
|
|
// HasChanges returns true if diff reports any added/modified/deleted entries.
|
|
func HasChanges(d *ManifestDiff) bool {
|
|
if d == nil {
|
|
return false
|
|
}
|
|
return len(d.Added) > 0 || len(d.Modified) > 0 || len(d.Deleted) > 0
|
|
}
|