add optional 'assignee' to Issue

This commit is contained in:
Sebastian Kuzminsky 2025-07-08 16:29:00 -06:00
parent 400e0ca26f
commit 645062d10c
4 changed files with 21 additions and 0 deletions

View file

@ -150,6 +150,9 @@ fn handle_command(args: &Args, issues_dir: &std::path::Path) -> anyhow::Result<(
if let Some(dependencies) = &issue.dependencies { if let Some(dependencies) = &issue.dependencies {
println!("dependencies: {:?}", dependencies); println!("dependencies: {:?}", dependencies);
} }
if let Some(assignee) = &issue.assignee {
println!("assignee: {}", assignee);
}
println!(""); println!("");
println!("{}", issue.description); println!("{}", issue.description);
for comment in &issue.comments { for comment in &issue.comments {

View file

@ -24,6 +24,7 @@ pub struct Issue {
pub timestamp: chrono::DateTime<chrono::Local>, pub timestamp: chrono::DateTime<chrono::Local>,
pub state: State, pub state: State,
pub dependencies: Option<Vec<IssueHandle>>, pub dependencies: Option<Vec<IssueHandle>>,
pub assignee: Option<String>,
pub description: String, pub description: String,
pub comments: Vec<crate::comment::Comment>, pub comments: Vec<crate::comment::Comment>,
@ -90,6 +91,7 @@ impl Issue {
let mut state = State::New; // default state, if not specified in the issue let mut state = State::New; // default state, if not specified in the issue
let mut dependencies: Option<Vec<String>> = None; let mut dependencies: Option<Vec<String>> = None;
let mut comments = Vec::<crate::comment::Comment>::new(); let mut comments = Vec::<crate::comment::Comment>::new();
let mut assignee: Option<String> = None;
for direntry in dir.read_dir()? { for direntry in dir.read_dir()? {
if let Ok(direntry) = direntry { if let Ok(direntry) = direntry {
@ -99,6 +101,10 @@ impl Issue {
} else if file_name == "state" { } else if file_name == "state" {
let state_string = std::fs::read_to_string(direntry.path())?; let state_string = std::fs::read_to_string(direntry.path())?;
state = State::from_str(state_string.trim())?; state = State::from_str(state_string.trim())?;
} else if file_name == "assignee" {
assignee = Some(String::from(
std::fs::read_to_string(direntry.path())?.trim(),
));
} else if file_name == "dependencies" { } else if file_name == "dependencies" {
let dep_strings = std::fs::read_to_string(direntry.path())?; let dep_strings = std::fs::read_to_string(direntry.path())?;
let deps: Vec<IssueHandle> = dep_strings let deps: Vec<IssueHandle> = dep_strings
@ -129,6 +135,7 @@ impl Issue {
timestamp, timestamp,
state: state, state: state,
dependencies, dependencies,
assignee,
description: description.unwrap(), description: description.unwrap(),
comments, comments,
dir: std::path::PathBuf::from(dir), dir: std::path::PathBuf::from(dir),
@ -180,6 +187,7 @@ impl Issue {
timestamp: chrono::Local::now(), timestamp: chrono::Local::now(),
state: State::New, state: State::New,
dependencies: None, dependencies: None,
assignee: None,
description: String::from(""), // FIXME: kind of bogus to use the empty string as None description: String::from(""), // FIXME: kind of bogus to use the empty string as None
comments: Vec::<crate::comment::Comment>::new(), comments: Vec::<crate::comment::Comment>::new(),
dir: issue_dir, dir: issue_dir,
@ -260,6 +268,7 @@ mod tests {
.with_timezone(&chrono::Local), .with_timezone(&chrono::Local),
state: State::New, state: State::New,
dependencies: None, dependencies: None,
assignee: None,
description: String::from("this is the title of my issue\n\nThis is the description of my issue.\nIt is multiple lines.\n* Arbitrary contents\n* But let's use markdown by convention\n"), description: String::from("this is the title of my issue\n\nThis is the description of my issue.\nIt is multiple lines.\n* Arbitrary contents\n* But let's use markdown by convention\n"),
comments: Vec::<crate::comment::Comment>::new(), comments: Vec::<crate::comment::Comment>::new(),
dir: std::path::PathBuf::from(issue_dir), dir: std::path::PathBuf::from(issue_dir),
@ -278,6 +287,7 @@ mod tests {
.with_timezone(&chrono::Local), .with_timezone(&chrono::Local),
state: State::InProgress, state: State::InProgress,
dependencies: None, dependencies: None,
assignee: Some(String::from("beep boop")),
description: String::from("minimal"), description: String::from("minimal"),
comments: Vec::<crate::comment::Comment>::new(), comments: Vec::<crate::comment::Comment>::new(),
dir: std::path::PathBuf::from(issue_dir), dir: std::path::PathBuf::from(issue_dir),

View file

@ -102,6 +102,7 @@ mod tests {
.with_timezone(&chrono::Local), .with_timezone(&chrono::Local),
state: crate::issue::State::InProgress, state: crate::issue::State::InProgress,
dependencies: None, dependencies: None,
assignee: Some(String::from("beep boop")),
description: String::from("minimal"), description: String::from("minimal"),
comments: Vec::<crate::comment::Comment>::new(), comments: Vec::<crate::comment::Comment>::new(),
dir, dir,
@ -120,6 +121,7 @@ mod tests {
.with_timezone(&chrono::Local), .with_timezone(&chrono::Local),
state: crate::issue::State::New, state: crate::issue::State::New,
dependencies: None, dependencies: None,
assignee: None,
description: String::from("this is the title of my issue\n\nThis is the description of my issue.\nIt is multiple lines.\n* Arbitrary contents\n* But let's use markdown by convention\n"), description: String::from("this is the title of my issue\n\nThis is the description of my issue.\nIt is multiple lines.\n* Arbitrary contents\n* But let's use markdown by convention\n"),
comments: Vec::<crate::comment::Comment>::new(), comments: Vec::<crate::comment::Comment>::new(),
dir, dir,
@ -147,6 +149,7 @@ mod tests {
.with_timezone(&chrono::Local), .with_timezone(&chrono::Local),
state: crate::issue::State::Done, state: crate::issue::State::Done,
dependencies: None, dependencies: None,
assignee: None,
description: String::from("oh yeah we got titles"), description: String::from("oh yeah we got titles"),
comments: Vec::<crate::comment::Comment>::new(), comments: Vec::<crate::comment::Comment>::new(),
dir, dir,
@ -179,6 +182,7 @@ mod tests {
.with_timezone(&chrono::Local), .with_timezone(&chrono::Local),
state: crate::issue::State::WontDo, state: crate::issue::State::WontDo,
dependencies: None, dependencies: None,
assignee: None,
description: String::from("issues out the wazoo\n\nLots of words\nthat don't say much\nbecause this is just\na test\n"), description: String::from("issues out the wazoo\n\nLots of words\nthat don't say much\nbecause this is just\na test\n"),
comments: expected_comments, comments: expected_comments,
dir, dir,
@ -206,6 +210,7 @@ mod tests {
.with_timezone(&chrono::Local), .with_timezone(&chrono::Local),
state: crate::issue::State::Done, state: crate::issue::State::Done,
dependencies: None, dependencies: None,
assignee: None,
description: String::from("oh yeah we got titles\n"), description: String::from("oh yeah we got titles\n"),
comments: Vec::<crate::comment::Comment>::new(), comments: Vec::<crate::comment::Comment>::new(),
dir, dir,
@ -224,6 +229,7 @@ mod tests {
.with_timezone(&chrono::Local), .with_timezone(&chrono::Local),
state: crate::issue::State::WontDo, state: crate::issue::State::WontDo,
dependencies: None, dependencies: None,
assignee: None,
description: String::from("issues out the wazoo\n\nLots of words\nthat don't say much\nbecause this is just\na test\n"), description: String::from("issues out the wazoo\n\nLots of words\nthat don't say much\nbecause this is just\na test\n"),
comments: Vec::<crate::comment::Comment>::new(), comments: Vec::<crate::comment::Comment>::new(),
dir, dir,
@ -245,6 +251,7 @@ mod tests {
crate::issue::IssueHandle::from("3fa5bfd93317ad25772680071d5ac3259cd2384f"), crate::issue::IssueHandle::from("3fa5bfd93317ad25772680071d5ac3259cd2384f"),
crate::issue::IssueHandle::from("dd79c8cfb8beeacd0460429944b4ecbe95a31561"), crate::issue::IssueHandle::from("dd79c8cfb8beeacd0460429944b4ecbe95a31561"),
]), ]),
assignee: None,
description: String::from("issue with dependencies\n\na test has begun\nfor dependencies we seek\nintertwining life"), description: String::from("issue with dependencies\n\na test has begun\nfor dependencies we seek\nintertwining life"),
comments: Vec::<crate::comment::Comment>::new(), comments: Vec::<crate::comment::Comment>::new(),
dir, dir,

View file

@ -0,0 +1 @@
beep boop