ent list: add filtering based on tags
This commit is contained in:
parent
28db7669f4
commit
9d4409c008
3 changed files with 50 additions and 0 deletions
|
|
@ -34,6 +34,10 @@ enum Commands {
|
||||||
/// "assignee": Comma-separated list of assignees to list.
|
/// "assignee": Comma-separated list of assignees to list.
|
||||||
/// Defaults to all assignees if not set.
|
/// Defaults to all assignees if not set.
|
||||||
///
|
///
|
||||||
|
/// "tag": Comma-separated list of tags to include or exclude
|
||||||
|
/// (if prefixed with "-"). If omitted, defaults to including
|
||||||
|
/// all tags and excluding none.
|
||||||
|
///
|
||||||
#[arg(default_value_t = String::from("state=New,Backlog,Blocked,InProgress"))]
|
#[arg(default_value_t = String::from("state=New,Backlog,Blocked,InProgress"))]
|
||||||
filter: String,
|
filter: String,
|
||||||
},
|
},
|
||||||
|
|
@ -187,6 +191,17 @@ fn handle_command(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if filter.include_tags.len() > 0 {
|
||||||
|
if !issue.has_any_tag(&filter.include_tags) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if filter.exclude_tags.len() > 0 {
|
||||||
|
if issue.has_any_tag(&filter.exclude_tags) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This issue passed all the filters, include it in list.
|
// This issue passed all the filters, include it in list.
|
||||||
uuids_by_state
|
uuids_by_state
|
||||||
.entry(issue.state.clone())
|
.entry(issue.state.clone())
|
||||||
|
|
|
||||||
14
src/issue.rs
14
src/issue.rs
|
|
@ -347,6 +347,20 @@ impl Issue {
|
||||||
))?;
|
))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_tag(&self, tag: &str) -> bool {
|
||||||
|
let tag_string = String::from(tag);
|
||||||
|
self.tags.iter().position(|x| x == &tag_string).is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_any_tag(&self, tags: &std::collections::HashSet<&str>) -> bool {
|
||||||
|
for tag in tags.iter() {
|
||||||
|
if self.has_tag(tag) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the internal/private API of Issue.
|
// This is the internal/private API of Issue.
|
||||||
|
|
|
||||||
21
src/lib.rs
21
src/lib.rs
|
|
@ -20,6 +20,8 @@ pub enum ParseFilterError {
|
||||||
pub struct Filter<'a> {
|
pub struct Filter<'a> {
|
||||||
pub include_states: std::collections::HashSet<crate::issue::State>,
|
pub include_states: std::collections::HashSet<crate::issue::State>,
|
||||||
pub include_assignees: std::collections::HashSet<&'a str>,
|
pub include_assignees: std::collections::HashSet<&'a str>,
|
||||||
|
pub include_tags: std::collections::HashSet<&'a str>,
|
||||||
|
pub exclude_tags: std::collections::HashSet<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Filter<'a> {
|
impl<'a> Filter<'a> {
|
||||||
|
|
@ -33,6 +35,8 @@ impl<'a> Filter<'a> {
|
||||||
State::New,
|
State::New,
|
||||||
]),
|
]),
|
||||||
include_assignees: std::collections::HashSet::<&'a str>::new(),
|
include_assignees: std::collections::HashSet::<&'a str>::new(),
|
||||||
|
include_tags: std::collections::HashSet::<&'a str>::new(),
|
||||||
|
exclude_tags: std::collections::HashSet::<&'a str>::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
for filter_chunk_str in filter_str.split(":") {
|
for filter_chunk_str in filter_str.split(":") {
|
||||||
|
|
@ -48,12 +52,29 @@ impl<'a> Filter<'a> {
|
||||||
f.include_states.insert(crate::issue::State::from_str(s)?);
|
f.include_states.insert(crate::issue::State::from_str(s)?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"assignee" => {
|
"assignee" => {
|
||||||
f.include_assignees.clear();
|
f.include_assignees.clear();
|
||||||
for s in tokens[1].split(",") {
|
for s in tokens[1].split(",") {
|
||||||
f.include_assignees.insert(s);
|
f.include_assignees.insert(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"tag" => {
|
||||||
|
f.include_tags.clear();
|
||||||
|
f.exclude_tags.clear();
|
||||||
|
for s in tokens[1].split(",") {
|
||||||
|
if s.len() == 0 {
|
||||||
|
return Err(ParseFilterError::ParseError);
|
||||||
|
}
|
||||||
|
if s.chars().nth(0).unwrap() == '-' {
|
||||||
|
f.exclude_tags.insert(&s[1..]);
|
||||||
|
} else {
|
||||||
|
f.include_tags.insert(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
println!("unknown filter chunk '{}'", filter_chunk_str);
|
println!("unknown filter chunk '{}'", filter_chunk_str);
|
||||||
return Err(ParseFilterError::ParseError);
|
return Err(ParseFilterError::ParseError);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue