From a373af0658e0dc9668d2f7b77c4b4a0525a6d2a0 Mon Sep 17 00:00:00 2001 From: Jonathan Bernard Date: Fri, 22 Jul 2022 10:23:53 -0500 Subject: [PATCH] Add support for filtering based on property exclusion. For example, allow commands like: # exclude issues from context "abc" pit list -C abc # exclude issues delegated to John Doe pit list -P "delgated-to:John Doe" --- pit.nimble | 2 +- src/pit.nim | 31 +++++++++++++++++++++++++++++++ src/pitpkg/cliconstants.nim | 19 +++++++++++++++---- src/pitpkg/private/libpit.nim | 10 +++++++++- 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/pit.nimble b/pit.nimble index 60aa17d..2e788f6 100644 --- a/pit.nimble +++ b/pit.nimble @@ -1,6 +1,6 @@ # Package -version = "4.18.2" +version = "4.19.0" author = "Jonathan Bernard" description = "Personal issue tracker." license = "MIT" diff --git a/src/pit.nim b/src/pit.nim index bb5b65d..5fe9c84 100644 --- a/src/pit.nim +++ b/src/pit.nim @@ -167,6 +167,16 @@ proc parsePropertiesOption(propsOpt: string): TableRef[string, string] = if pair.len == 1: result[pair[0]] = "true" else: result[pair[0]] = pair[1] +proc parseExclPropertiesOption(propsOpt: string): TableRef[string, seq[string]] = + result = newTable[string, seq[string]]() + for propText in propsOpt.split(";"): + let pair = propText.split(":", 1) + let val = + if pair.len == 1: "true" + else: pair[1] + if result.hasKey(pair[0]): result[pair[0]].add(val) + else: result[pair[0]] = @[val] + proc sameDay(a, b: DateTime): bool = result = a.year == b.year and a.yearday == b.yearday @@ -290,6 +300,7 @@ when isMainModule: trace "context initiated" var propertiesOption = none(TableRef[string,string]) + var exclPropsOption = none(TableRef[string,seq[string]]) var tagsOption = none(seq[string]) if args["--properties"] or args["--context"]: @@ -302,6 +313,20 @@ when isMainModule: propertiesOption = some(props) + if args["--excl-properties"] or args["--excl-context"]: + + var exclProps = + if args["--excl-properties"]: + parseExclPropertiesOption($args["--excl-properties"]) + else: newTable[string,seq[string]]() + + if args["--excl-context"]: + if not exclProps.hasKey("context"): exclProps["context"] = @[] + let exclContexts = split($args["--excl-context"], ",") + exclProps["context"] = exclProps["context"].concat(exclContexts) + + exclPropsOption = some(exclProps) + if args["--tags"]: tagsOption = some(($args["--tags"]).split(",").mapIt(it.strip)) ## Actual command runners @@ -449,6 +474,11 @@ when isMainModule: filter.properties = propertiesOption.get filterOption = some(filter) + # Add property exclusions (if given) + if exclPropsOption.isSome: + filter.exclProperties = exclPropsOption.get + filterOption = some(filter) + # If they supplied text matches, add that to the filter. if args["--match"]: filter.summaryMatch = some(re("(?i)" & $args["--match"])) @@ -473,6 +503,7 @@ when isMainModule: filter.properties["context"] == "all": filter.properties.del("context") + filter.exclProperties.del("context") var listContexts = false var statesOption = none(seq[IssueState]) diff --git a/src/pitpkg/cliconstants.nim b/src/pitpkg/cliconstants.nim index 4053556..5b75da2 100644 --- a/src/pitpkg/cliconstants.nim +++ b/src/pitpkg/cliconstants.nim @@ -1,4 +1,4 @@ -const PIT_VERSION* = "4.18.2" +const PIT_VERSION* = "4.19.0" const USAGE* = """Usage: pit ( new | add) [] [options] @@ -25,7 +25,18 @@ Options: a filter to the issues listed, only allowing those which have all of the given properties. - -c, --context Shorthand for '-p context:' + -P, --excl-properties + When used with the list command, exclude issues + that contain properties with the given value. This + parameter is formatted the same as the --properties + parameter: "key:val;key:val" + + -c, --context Shorthand for '-p context:' + + -C, --excl-context Don't show issues from the given context(s). + Multiple contexts can be excluded using a ',' to + separate names. For example: -C ctx1,ctx2 + Shorthand for '-P context:' -g, --tags Specify tags for an issue. @@ -48,7 +59,7 @@ Options: -y, --yes Automatically answer "yes" to any prompts. - -C, --config Location of the config file (defaults to $HOME/.pitrc) + --config Location of the config file (defaults to $HOME/.pitrc) -E, --echo-args Echo arguments (for debug purposes). @@ -155,4 +166,4 @@ Issue Properties: If present, expected to be a comma-delimited list of text tags. The -g option is a short-hand for '-p tags:'. -""" \ No newline at end of file +""" diff --git a/src/pitpkg/private/libpit.nim b/src/pitpkg/private/libpit.nim index ef6ecb6..9c46af7 100644 --- a/src/pitpkg/private/libpit.nim +++ b/src/pitpkg/private/libpit.nim @@ -24,6 +24,7 @@ type fullMatch*, summaryMatch*: Option[Regex] hasTags*: seq[string] properties*: TableRef[string, string] + exclProperties*: TableRef[string, seq[string]] PitConfig* = ref object tasksDir*: string @@ -114,7 +115,8 @@ proc initFilter*(): IssueFilter = fullMatch: none(Regex), summaryMatch: none(Regex), hasTags: @[], - properties: newTable[string, string]()) + properties: newTable[string, string](), + exclProperties: newTable[string,seq[string]]()) proc propsFilter*(props: TableRef[string, string]): IssueFilter = if isNil(props): @@ -347,6 +349,12 @@ proc filter*(issues: seq[Issue], filter: IssueFilter): seq[Issue] = for k,v in filter.properties: result = result.filterIt(it.hasProp(k) and it[k] == v) + for k,v in filter.exclProperties: + result = result.filter(proc (iss: Issue): bool = + not iss.hasProp(k) or + not v.anyIt(it == iss[k]) + ) + if filter.completedRange.isSome: let range = filter.completedRange.get result = result.filterIt(