From 390d2be26b7e1c81f253f55b327664e0d982b67d Mon Sep 17 00:00:00 2001 From: Jan Heuermann Date: Sat, 2 Mar 2024 16:50:43 +0100 Subject: [PATCH] Add flag for auto-appending tags when pausing --- klog/app/cli/pause.go | 20 +++-- klog/parser/reconciling/pause_open_range.go | 13 +++- .../reconciling/pause_open_range_test.go | 73 +++++++++++++++---- klog/summary.go | 14 ++++ klog/summary_test.go | 23 ++++++ 5 files changed, 118 insertions(+), 25 deletions(-) diff --git a/klog/app/cli/pause.go b/klog/app/cli/pause.go index 822c22f6..4c22fd1b 100644 --- a/klog/app/cli/pause.go +++ b/klog/app/cli/pause.go @@ -13,8 +13,9 @@ import ( ) type Pause struct { - Summary klog.EntrySummary `name:"summary" short:"s" placeholder:"TEXT" help:"Summary text for the pause entry"` - Extend bool `name:"extend" short:"e" help:"Extend latest pause, instead of adding a new pause entry"` + Summary klog.EntrySummary `name:"summary" short:"s" placeholder:"TEXT" help:"Summary text for the pause entry"` + NoAppendTags bool `name:"no-tags" help:"Do not automatically take over (append) tags from open range"` + Extend bool `name:"extend" short:"e" help:"Extend latest pause, instead of adding a new pause entry"` util.OutputFileArgs util.NoStyleArgs util.WarnArgs @@ -24,11 +25,20 @@ func (opt *Pause) Help() string { return `Creates a pause entry for a record with an open time range. The command is blocking – it keeps updating the pause entry until the process is exited. (The file will be written into once per minute.) + +If the open range in the record contains tags, then these will automatically be taken over and appended to the pause entry. ` } func (opt *Pause) Run(ctx app.Context) app.Error { opt.NoStyleArgs.Apply(&ctx) + if opt.Extend && opt.Summary != nil { + return app.NewError( + "Illegal flag combination", + "It’s not possible to combine --extend with --summary", + nil, + ) + } today := klog.NewDateFromGo(ctx.Now()) doReconcile := func(reconcile reconciling.Reconcile) (*reconciling.Result, app.Error) { return ctx.ReconcileFile( @@ -47,9 +57,9 @@ func (opt *Pause) Run(ctx app.Context) app.Error { // - With `--extend`, find a pause and append the summary lastResult, err := doReconcile(func(reconciler *reconciling.Reconciler) error { if opt.Extend { - return reconciler.ExtendPause(klog.NewDuration(0, 0), opt.Summary) + return reconciler.ExtendPause(klog.NewDuration(0, 0)) } - return reconciler.AppendPause(opt.Summary) + return reconciler.AppendPause(opt.Summary, !opt.NoAppendTags) }) if err != nil { return err @@ -73,7 +83,7 @@ func (opt *Pause) Run(ctx app.Context) app.Error { if uncapturedIncrement > 0 { lastResult, err = doReconcile(func(reconciler *reconciling.Reconciler) error { // Don’t add the summary here, as we already appended it in the initial run. - return reconciler.ExtendPause(klog.NewDuration(0, -1*uncapturedIncrement), nil) + return reconciler.ExtendPause(klog.NewDuration(0, -1*uncapturedIncrement)) }) minsCaptured += uncapturedIncrement if err != nil { diff --git a/klog/parser/reconciling/pause_open_range.go b/klog/parser/reconciling/pause_open_range.go index 2423bd75..1fd44a03 100644 --- a/klog/parser/reconciling/pause_open_range.go +++ b/klog/parser/reconciling/pause_open_range.go @@ -8,8 +8,9 @@ import ( ) // AppendPause adds a new pause entry to a record that contains an open range. -func (r *Reconciler) AppendPause(summary klog.EntrySummary) error { - if r.findOpenRangeIndex() == -1 { +func (r *Reconciler) AppendPause(summary klog.EntrySummary, appendTags bool) error { + openEntryI := r.findOpenRangeIndex() + if openEntryI == -1 { return errors.New("No open time range found") } entryValue := "-0m" @@ -20,11 +21,16 @@ func (r *Reconciler) AppendPause(summary klog.EntrySummary) error { entryValue += " " } summary[0] = entryValue + summary[0] + if appendTags { + openEntry := r.Record.Entries()[openEntryI] + appendableTags := strings.Join(openEntry.Summary().Tags().ToStrings(), " ") + summary = summary.Append(appendableTags) + } return r.AppendEntry(summary) } // ExtendPause extends an existing pause entry. -func (r *Reconciler) ExtendPause(increment klog.Duration, additionalSummary klog.EntrySummary) error { +func (r *Reconciler) ExtendPause(increment klog.Duration) error { if r.findOpenRangeIndex() == -1 { return errors.New("No open time range found") } @@ -50,6 +56,5 @@ func (r *Reconciler) ExtendPause(increment klog.Duration, additionalSummary klog r.lines[pauseLineIndex].Text = strings.Replace(r.lines[pauseLineIndex].Text, value, extendedPause.ToString(), 1) } - r.concatenateSummary(pauseEntryI, pauseLineIndex, additionalSummary) return nil } diff --git a/klog/parser/reconciling/pause_open_range_test.go b/klog/parser/reconciling/pause_open_range_test.go index a7537132..5b2af7af 100644 --- a/klog/parser/reconciling/pause_open_range_test.go +++ b/klog/parser/reconciling/pause_open_range_test.go @@ -16,7 +16,7 @@ func TestReconcilerAppendingPauseAddsNewEntry(t *testing.T) { rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.AppendPause(nil) + err := reconciler.AppendPause(nil, false) require.Nil(t, err) result := assertResult(t, reconciler) @@ -35,7 +35,7 @@ func TestReconcilerAppendingPauseWithSummary(t *testing.T) { rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.AppendPause(klog.Ɀ_EntrySummary_("Lunch break")) + err := reconciler.AppendPause(klog.Ɀ_EntrySummary_("Lunch break"), false) require.Nil(t, err) result := assertResult(t, reconciler) @@ -46,6 +46,48 @@ func TestReconcilerAppendingPauseWithSummary(t *testing.T) { `, result.AllSerialised) } +func TestReconcilerAppendingPauseTakesOverTags(t *testing.T) { + original := ` +2010-04-27 + 3:00pm - ? Did some #work + and also #misc other #things + and then more #work (redundant tag) +` + rs, bs, _ := parser.NewSerialParser().Parse(original) + reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) + require.NotNil(t, reconciler) + err := reconciler.AppendPause(nil, true) + require.Nil(t, err) + + result := assertResult(t, reconciler) + assert.Equal(t, ` +2010-04-27 + 3:00pm - ? Did some #work + and also #misc other #things + and then more #work (redundant tag) + -0m #misc #things #work +`, result.AllSerialised) +} + +func TestReconcilerAppendingPauseTakesOverTagsAndConcatsWithSummary(t *testing.T) { + original := ` +2010-04-27 + 3:00pm - ? Did some #work +` + rs, bs, _ := parser.NewSerialParser().Parse(original) + reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) + require.NotNil(t, reconciler) + err := reconciler.AppendPause(klog.Ɀ_EntrySummary_("Lunch break"), true) + require.Nil(t, err) + + result := assertResult(t, reconciler) + assert.Equal(t, ` +2010-04-27 + 3:00pm - ? Did some #work + -0m Lunch break #work +`, result.AllSerialised) +} + func TestReconcilerAppendingPauseWithMultilineSummary(t *testing.T) { original := ` 2010-04-27 @@ -54,7 +96,7 @@ func TestReconcilerAppendingPauseWithMultilineSummary(t *testing.T) { rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.AppendPause(klog.Ɀ_EntrySummary_("Lunch", "break")) + err := reconciler.AppendPause(klog.Ɀ_EntrySummary_("Lunch", "break"), false) require.Nil(t, err) result := assertResult(t, reconciler) @@ -75,7 +117,7 @@ func TestReconcilerAppendPauseWithUTF8Summary(t *testing.T) { rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.AppendPause(klog.Ɀ_EntrySummary_("午休")) + err := reconciler.AppendPause(klog.Ɀ_EntrySummary_("午休"), false) require.Nil(t, err) result := assertResult(t, reconciler) @@ -95,7 +137,7 @@ func TestReconcilerAppendingPauseFailsIfThereIsNoOpenRange(t *testing.T) { rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.AppendPause(nil) + err := reconciler.AppendPause(nil, false) require.Error(t, err) } @@ -110,7 +152,7 @@ Foo rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.ExtendPause(klog.NewDuration(0, -3), nil) + err := reconciler.ExtendPause(klog.NewDuration(0, -3)) require.Nil(t, err) result := assertResult(t, reconciler) @@ -134,7 +176,7 @@ Foo rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.ExtendPause(klog.NewDuration(0, -3), klog.Ɀ_EntrySummary_("and more break")) + err := reconciler.ExtendPause(klog.NewDuration(0, -3)) require.Nil(t, err) result := assertResult(t, reconciler) @@ -143,7 +185,7 @@ Foo Foo 3:00 - ? I desperately need a break! - -4m Lunch break and more break + -4m Lunch break `, result.AllSerialised) } @@ -158,7 +200,7 @@ Foo rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.ExtendPause(klog.NewDuration(-1, 0), klog.Ɀ_EntrySummary_("", "and more break")) + err := reconciler.ExtendPause(klog.NewDuration(-1, 0)) require.Nil(t, err) result := assertResult(t, reconciler) @@ -168,7 +210,6 @@ Foo 3:00 - ? I desperately need a break! -2h Lunch break - and more break `, result.AllSerialised) } @@ -184,7 +225,7 @@ Foo rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.ExtendPause(klog.NewDuration(-1, 0), klog.Ɀ_EntrySummary_("and more break")) + err := reconciler.ExtendPause(klog.NewDuration(-1, 0)) require.Nil(t, err) result := assertResult(t, reconciler) @@ -194,7 +235,7 @@ Foo 3:00 - ? I desperately need a break! -2h Lunch - break and more break + break `, result.AllSerialised) } @@ -210,7 +251,7 @@ Foo rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.ExtendPause(klog.NewDuration(-2, -51), nil) + err := reconciler.ExtendPause(klog.NewDuration(-2, -51)) require.Nil(t, err) result := assertResult(t, reconciler) @@ -235,7 +276,7 @@ Foo rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.ExtendPause(klog.NewDuration(0, 0), nil) + err := reconciler.ExtendPause(klog.NewDuration(0, 0)) require.Nil(t, err) result := assertResult(t, reconciler) @@ -257,7 +298,7 @@ func TestReconcilerExtendingPauseFailsIfThereIsNoOpenRange(t *testing.T) { rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.ExtendPause(klog.NewDuration(2, 0), nil) + err := reconciler.ExtendPause(klog.NewDuration(2, 0)) require.Error(t, err) } @@ -270,6 +311,6 @@ func TestReconcilerDoesNotExtendNonNegativeDurations(t *testing.T) { rs, bs, _ := parser.NewSerialParser().Parse(original) reconciler := NewReconcilerAtRecord(klog.Ɀ_Date_(2010, 4, 27))(rs, bs) require.NotNil(t, reconciler) - err := reconciler.ExtendPause(klog.NewDuration(0, -10), nil) + err := reconciler.ExtendPause(klog.NewDuration(0, -10)) require.Error(t, err) } diff --git a/klog/summary.go b/klog/summary.go index a617cd4c..bb0e1683 100644 --- a/klog/summary.go +++ b/klog/summary.go @@ -86,3 +86,17 @@ func (s EntrySummary) Equals(summary EntrySummary) bool { } return RecordSummary(s).Equals(RecordSummary(summary)) } + +// Append appends a text to an entry summary +func (s EntrySummary) Append(appendableText string) EntrySummary { + if len(s) == 0 { + return []string{appendableText} + } + delimiter := "" + lastLine := s[len(s)-1] + if len(lastLine) > 0 { + delimiter = " " + } + s[len(s)-1] = lastLine + delimiter + appendableText + return s +} diff --git a/klog/summary_test.go b/klog/summary_test.go index 7e814eb8..145f606f 100644 --- a/klog/summary_test.go +++ b/klog/summary_test.go @@ -195,3 +195,26 @@ func TestRecognisesAllTags(t *testing.T) { entrySummary, _ := NewEntrySummary("Hello #world, I feel #great #TODAY") assert.Equal(t, entrySummary.Tags().ToStrings(), []string{"#great", "#today", "#world"}) } + +func TestAppendsToEntrySummary(t *testing.T) { + t.Run("append empty to empty", func(t *testing.T) { + e := Ɀ_EntrySummary_().Append("") + assert.Equal(t, []string{""}, e.Lines()) + }) + t.Run("append non-empty to zero", func(t *testing.T) { + e := Ɀ_EntrySummary_().Append("foo") + assert.Equal(t, []string{"foo"}, e.Lines()) + }) + t.Run("append non-empty to empty", func(t *testing.T) { + e := Ɀ_EntrySummary_("").Append("foo") + assert.Equal(t, []string{"foo"}, e.Lines()) + }) + t.Run("append non-empty to existing", func(t *testing.T) { + e := Ɀ_EntrySummary_("hello").Append("foo") + assert.Equal(t, []string{"hello foo"}, e.Lines()) + }) + t.Run("append non-empty to multiline", func(t *testing.T) { + e := Ɀ_EntrySummary_("hello", "world").Append("foo") + assert.Equal(t, []string{"hello", "world foo"}, e.Lines()) + }) +}