Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion klog/app/cli/args/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ type FilterArgs struct {
// General filters:
Tags []klog.Tag `name:"tag" placeholder:"TAG" group:"Filter Flags:" help:"Entries that match these tags (either in the record summary or the entry summary). You can omit the leading '#'."`
Filter string `name:"filter" placeholder:"EXPR" group:"Filter Flags:" help:"Entries that match this filter expression. Run 'klog info --filtering' to learn how expressions works."`

hasPartialRecordsWithShouldTotal bool // Field only for internal use
}

func (args *FilterArgs) ApplyFilter(now gotime.Time, rs []klog.Record) ([]klog.Record, app.Error) {
Expand Down Expand Up @@ -125,7 +127,10 @@ func (args *FilterArgs) ApplyFilter(now gotime.Time, rs []klog.Record) ([]klog.R

// Apply filters, if applicable:
if len(predicates) > 0 {
rs = filter.Filter(filter.And{Predicates: predicates}, rs)
hprws := false
rs, hprws = filter.Filter(filter.And{Predicates: predicates}, rs)
args.hasPartialRecordsWithShouldTotal = hprws

}
return rs, nil
}
10 changes: 10 additions & 0 deletions klog/app/cli/args/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ type DiffArgs struct {
Diff bool `name:"diff" short:"d" help:"Show difference between actual and should-total time."`
}

// GetWarning returns a warning if the user applied entry-level filtering (partial
// records) *and* requested to compute the should-total diff, as that may yield
// nonsensical results.
func (args *DiffArgs) GetWarning(filterArgs FilterArgs) service.UsageWarning {
if args.Diff && filterArgs.hasPartialRecordsWithShouldTotal {
return service.DiffEntryFilteringWarning
}
return service.UsageWarning{}
}

type NoStyleArgs struct {
NoStyle bool `name:"no-style" help:"Do not style or colour the values."`
}
Expand Down
8 changes: 5 additions & 3 deletions klog/app/cli/args/now.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ func (args *NowArgs) HadOpenRange() bool {
return args.hadOpenRange
}

func (args *NowArgs) GetNowWarnings() []string {
// GetWarning warns the user that they specified the --now flag but there actually
// weren’t any closable ranges in the data.
func (args *NowArgs) GetWarning() service.UsageWarning {
if args.Now && !args.hadOpenRange {
return []string{"You specified --now, but there was no open-ended time range"}
return service.PointlessNowWarning
}
return nil
return service.UsageWarning{}
}
13 changes: 9 additions & 4 deletions klog/app/cli/args/warn.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,24 @@ type WarnArgs struct {
NoWarn bool `name:"no-warn" help:"Suppress warnings about potential mistakes or logical errors."`
}

func (args *WarnArgs) PrintWarnings(ctx app.Context, records []klog.Record, additionalWarnings []string) {
func (args *WarnArgs) PrintWarnings(ctx app.Context, records []klog.Record, additionalWarnings []service.UsageWarning) {
styler, _ := ctx.Serialise()
warnings := args.GatherWarnings(ctx, records, additionalWarnings)
for _, w := range warnings {
ctx.Print(prettify.PrettifyWarning(w, styler))
}
}

func (args *WarnArgs) GatherWarnings(ctx app.Context, records []klog.Record, additionalWarnings []string) []string {
func (args *WarnArgs) GatherWarnings(ctx app.Context, records []klog.Record, additionalWarnings []service.UsageWarning) []string {
if args.NoWarn {
return nil
}
disabledCheckers := ctx.Config().NoWarnings.UnwrapOr(service.NewDisabledCheckers())
dataWarnings := service.CheckForWarnings(ctx.Now(), records, disabledCheckers)
return append(dataWarnings, additionalWarnings...)
warnings := service.CheckForWarnings(ctx.Now(), records, disabledCheckers)
for _, warn := range additionalWarnings {
if warn != (service.UsageWarning{}) && !disabledCheckers[warn.Name] {
warnings = append(warnings, warn.Message)
}
}
return warnings
}
3 changes: 2 additions & 1 deletion klog/app/cli/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/jotaen/klog/klog/app"
"github.com/jotaen/klog/klog/app/cli/args"
"github.com/jotaen/klog/klog/parser/json"
"github.com/jotaen/klog/klog/service"
)

type Json struct {
Expand Down Expand Up @@ -50,7 +51,7 @@ func (opt *Json) Run(ctx app.Context) app.Error {
return fErr
}
records = opt.ApplySort(records)
warnings := opt.GatherWarnings(ctx, records, opt.GetNowWarnings())
warnings := opt.GatherWarnings(ctx, records, []service.UsageWarning{opt.GetWarning()})
ctx.Print(json.ToJson(records, nil, warnings, opt.Pretty) + "\n")
return nil
}
5 changes: 3 additions & 2 deletions klog/app/cli/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ type Print struct {
func (opt *Print) Help() string {
return `
Outputs data on the terminal, by default with syntax-highlighting turned on.
Note that the output doesn’t resemble the file byte by byte, but the command may apply some minor clean-ups of the formatting.
Note that the output doesn’t resemble the file verbatim, but it may apply some minor formatting.

If run with filter flags, it only outputs those entries that match the filter clauses. E.g., when filtering for a tag that only appears particular entries, it will exclude all other entries from that record.

If run with filter flags, it only outputs those entries that match the filter clauses.
You can optionally also sort the records, or print out the total times for each record and entry.
`
}
Expand Down
2 changes: 1 addition & 1 deletion klog/app/cli/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func (opt *Report) Run(ctx app.Context) app.Error {
}

table.Collect(ctx.Print)
opt.WarnArgs.PrintWarnings(ctx, records, opt.GetNowWarnings())
opt.WarnArgs.PrintWarnings(ctx, records, []service.UsageWarning{opt.NowArgs.GetWarning(), opt.DiffArgs.GetWarning(opt.FilterArgs)})
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion klog/app/cli/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,6 @@ func (opt *Tags) Run(ctx app.Context) app.Error {
}
}
table.Collect(ctx.Print)
opt.WarnArgs.PrintWarnings(ctx, records, opt.GetNowWarnings())
opt.WarnArgs.PrintWarnings(ctx, records, []service.UsageWarning{opt.NowArgs.GetWarning()})
return nil
}
2 changes: 1 addition & 1 deletion klog/app/cli/today.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func handle(opt *Today, ctx app.Context) app.Error {
}
}
table.Collect(ctx.Print)
opt.WarnArgs.PrintWarnings(ctx, records, opt.GetNowWarnings())
opt.WarnArgs.PrintWarnings(ctx, records, []service.UsageWarning{opt.NowArgs.GetWarning()})
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion klog/app/cli/total.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@ func (opt *Total) Run(ctx app.Context) app.Error {
return "s"
}()))

opt.WarnArgs.PrintWarnings(ctx, records, opt.GetNowWarnings())
opt.WarnArgs.PrintWarnings(ctx, records, []service.UsageWarning{opt.NowArgs.GetWarning(), opt.DiffArgs.GetWarning(opt.FilterArgs)})
return nil
}
9 changes: 8 additions & 1 deletion klog/app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,14 @@ var CONFIG_FILE_ENTRIES = []ConfigFileEntries[any]{
Name: "no_warnings",
Help: Help{
Summary: "Whether klog should suppress certain warnings when processing files.",
Value: "The config property must be one (or several comma-separated) of: `UNCLOSED_OPEN_RANGE` (for unclosed open ranges in past records), `FUTURE_ENTRIES` (for records/entries in the future), `OVERLAPPING_RANGES` (for time ranges that overlap), `MORE_THAN_24H` (if there is a record with more than 24h total). Multiple values must be separated by a comma, e.g.: `UNCLOSED_OPEN_RANGE, MORE_THAN_24H`.",
Value: "The config property must be one or several (comma-separated) of: " +
"`UNCLOSED_OPEN_RANGE` (for unclosed open ranges in past records), " +
"`FUTURE_ENTRIES` (for records/entries in the future), " +
"`OVERLAPPING_RANGES` (for time ranges that overlap), " +
"`MORE_THAN_24H` (if there is a record with more than 24h total), " +
"`POINTLESS_NOW` (when using --now without any open ranges), " +
"`ENTRY_FILTERED_DIFFING` (when combining --diff and entry-level filtering). " +
"Multiple values must be separated by a comma, e.g.: `UNCLOSED_OPEN_RANGE, MORE_THAN_24H`.",
Default: "If absent/empty, klog prints all available warnings.",
},
read: func(value string, config *Config) error {
Expand Down
35 changes: 24 additions & 11 deletions klog/service/filter/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,33 @@ import (
"github.com/jotaen/klog/klog"
)

func Filter(p Predicate, rs []klog.Record) []klog.Record {
// Filter goes through a list of records and only keeps those that match the
// given predicate. The records may be returned partially, keeping only those
// entries that match the predicate.
// The second return value indicates whether there are partial records with a
// should-total set, as this may yield nonsensical results in a subsequent evaluation.
func Filter(p Predicate, rs []klog.Record) ([]klog.Record, bool) {
var res []klog.Record
hasPartialRecordsWithShouldTotal := false
for _, r := range rs {
var es []klog.Entry
for i, e := range r.Entries() {
if p.Matches(queriedEntry{r, r.Entries()[i]}) {
es = append(es, e)
if len(r.Entries()) == 0 && p.MatchesEmptyRecord(r) {
res = append(res, r)
} else {
var es []klog.Entry
for i, e := range r.Entries() {
if p.Matches(r, r.Entries()[i]) {
es = append(es, e)
}
}
if len(es) == 0 {
continue
}
if len(es) != len(r.Entries()) && r.ShouldTotal() != nil {
hasPartialRecordsWithShouldTotal = true
}
r.SetEntries(es)
res = append(res, r)
}
if len(es) == 0 {
continue
}
r.SetEntries(es)
res = append(res, r)
}
return res
return res, hasPartialRecordsWithShouldTotal
}
Loading