diff --git a/src/bin/ent/main.rs b/src/bin/ent/main.rs index 2a8f1f4..2d0f56a 100644 --- a/src/bin/ent/main.rs +++ b/src/bin/ent/main.rs @@ -58,12 +58,6 @@ enum Commands { #[arg(default_value_t = String::from("origin"))] remote: String, }, - - /// Get or set the Assignee field of an Issue. - Assign { - issue_id: String, - new_assignee: Option, - }, } fn handle_command(args: &Args, issues_dir: &std::path::Path) -> anyhow::Result<()> { @@ -72,52 +66,11 @@ fn handle_command(args: &Args, issues_dir: &std::path::Path) -> anyhow::Result<( let issues = entomologist::issues::Issues::new_from_dir(std::path::Path::new(issues_dir))?; let filter = entomologist::parse_filter(filter)?; - let mut uuids_by_state = std::collections::HashMap::< - entomologist::issue::State, - Vec<&entomologist::issue::IssueHandle>, - >::new(); for (uuid, issue) in issues.issues.iter() { if filter.include_states.contains(&issue.state) { - uuids_by_state - .entry(issue.state.clone()) - .or_default() - .push(uuid); + println!("{} {} ({:?})", uuid, issue.title(), issue.state); } } - - use entomologist::issue::State; - for state in [ - State::InProgress, - State::Blocked, - State::Backlog, - State::New, - State::Done, - State::WontDo, - ] { - let these_uuids = uuids_by_state.entry(state.clone()).or_default(); - if these_uuids.len() == 0 { - continue; - } - these_uuids.sort_by(|a_id, b_id| { - let a = issues.issues.get(*a_id).unwrap(); - let b = issues.issues.get(*b_id).unwrap(); - a.timestamp.cmp(&b.timestamp) - }); - println!("{:?}:", state); - for uuid in these_uuids { - let issue = issues.issues.get(*uuid).unwrap(); - let comments = match issue.comments.len() { - 0 => String::from(" "), - n => format!("🗩 {}", n), - }; - let assignee = match &issue.assignee { - Some(assignee) => format!(" (👉 {})", assignee), - None => String::from(""), - }; - println!("{} {} {}{}", uuid, comments, issue.title(), assignee); - } - println!(""); - } } Commands::New { @@ -153,21 +106,15 @@ fn handle_command(args: &Args, issues_dir: &std::path::Path) -> anyhow::Result<( match issues.get_issue(issue_id) { Some(issue) => { println!("issue {}", issue_id); - println!("author: {}", issue.author); - println!("timestamp: {}", issue.timestamp); println!("state: {:?}", issue.state); if let Some(dependencies) = &issue.dependencies { println!("dependencies: {:?}", dependencies); } - if let Some(assignee) = &issue.assignee { - println!("assignee: {}", assignee); - } println!(""); println!("{}", issue.description); for comment in &issue.comments { println!(""); println!("comment: {}", comment.uuid); - println!("author: {}", comment.author); println!("timestamp: {}", comment.timestamp); println!("{}", comment.description); } @@ -243,37 +190,6 @@ fn handle_command(args: &Args, issues_dir: &std::path::Path) -> anyhow::Result<( entomologist::git::sync(issues_dir, remote, branch)?; println!("synced {:?} with {:?}", branch, remote); } - - Commands::Assign { - issue_id, - new_assignee, - } => { - let mut issues = - entomologist::issues::Issues::new_from_dir(std::path::Path::new(issues_dir))?; - let Some(issue) = issues.issues.get_mut(issue_id) else { - return Err(anyhow::anyhow!("issue {} not found", issue_id)); - }; - match (&issue.assignee, new_assignee) { - (Some(old_assignee), Some(new_assignee)) => { - println!("issue: {}", issue_id); - println!("assignee: {} -> {}", old_assignee, new_assignee); - issue.set_assignee(new_assignee)?; - } - (Some(old_assignee), None) => { - println!("issue: {}", issue_id); - println!("assignee: {}", old_assignee); - } - (None, Some(new_assignee)) => { - println!("issue: {}", issue_id); - println!("assignee: None -> {}", new_assignee); - issue.set_assignee(new_assignee)?; - } - (None, None) => { - println!("issue: {}", issue_id); - println!("assignee: None"); - } - } - } } Ok(()) diff --git a/src/comment.rs b/src/comment.rs index d6ed66e..8cd00a0 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -3,7 +3,6 @@ use std::io::Write; #[derive(Debug, PartialEq)] pub struct Comment { pub uuid: String, - pub author: String, pub timestamp: chrono::DateTime, pub description: String, @@ -46,13 +45,11 @@ impl Comment { return Err(CommentError::CommentParseError); } - let author = crate::git::git_log_oldest_author(comment_dir)?; let timestamp = crate::git::git_log_oldest_timestamp(comment_dir)?; let dir = std::path::PathBuf::from(comment_dir); Ok(Self { uuid: String::from(dir.file_name().unwrap().to_string_lossy()), - author, timestamp, description: description.unwrap(), dir: std::path::PathBuf::from(comment_dir), @@ -105,7 +102,6 @@ mod tests { let comment = Comment::new_from_dir(comment_dir).unwrap(); let expected = Comment { uuid: String::from("9055dac36045fe36545bed7ae7b49347"), - author: String::from("Sebastian Kuzminsky "), timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-07T15:26:26-06:00") .unwrap() .with_timezone(&chrono::Local), diff --git a/src/git.rs b/src/git.rs index 6018392..28e8400 100644 --- a/src/git.rs +++ b/src/git.rs @@ -210,28 +210,6 @@ pub fn git_log_oldest_timestamp( Ok(timestamp) } -pub fn git_log_oldest_author(path: &std::path::Path) -> Result { - let mut git_dir = std::path::PathBuf::from(path); - git_dir.pop(); - let result = std::process::Command::new("git") - .args([ - "log", - "--pretty=format:%an <%ae>", - "--", - &path.file_name().unwrap().to_string_lossy(), - ]) - .current_dir(&git_dir) - .output()?; - if !result.status.success() { - println!("stdout: {}", std::str::from_utf8(&result.stdout).unwrap()); - println!("stderr: {}", std::str::from_utf8(&result.stderr).unwrap()); - return Err(GitError::Oops); - } - let author_str = std::str::from_utf8(&result.stdout).unwrap(); - let author_last = author_str.split("\n").last().unwrap(); - Ok(String::from(author_last)) -} - pub fn create_orphan_branch(branch: &str) -> Result<(), GitError> { { let tmp_worktree = tempfile::tempdir().unwrap(); diff --git a/src/issue.rs b/src/issue.rs index 68cb8f9..cdbac1f 100644 --- a/src/issue.rs +++ b/src/issue.rs @@ -20,12 +20,9 @@ pub type IssueHandle = String; #[derive(Debug, PartialEq)] pub struct Issue { - pub author: String, - pub timestamp: chrono::DateTime, + pub description: String, pub state: State, pub dependencies: Option>, - pub assignee: Option, - pub description: String, pub comments: Vec, /// This is the directory that the issue lives in. Only used @@ -91,7 +88,6 @@ impl Issue { let mut state = State::New; // default state, if not specified in the issue let mut dependencies: Option> = None; let mut comments = Vec::::new(); - let mut assignee: Option = None; for direntry in dir.read_dir()? { if let Ok(direntry) = direntry { @@ -101,10 +97,6 @@ impl Issue { } else if file_name == "state" { let state_string = std::fs::read_to_string(direntry.path())?; 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" { let dep_strings = std::fs::read_to_string(direntry.path())?; let deps: Vec = dep_strings @@ -127,16 +119,10 @@ impl Issue { return Err(IssueError::IssueParseError); } - let author = crate::git::git_log_oldest_author(dir)?; - let timestamp = crate::git::git_log_oldest_timestamp(dir)?; - Ok(Self { - author, - timestamp, + description: description.unwrap(), state: state, dependencies, - assignee, - description: description.unwrap(), comments, dir: std::path::PathBuf::from(dir), }) @@ -170,7 +156,6 @@ impl Issue { Ok(crate::comment::Comment { uuid, - author: String::from("Sebastian Kuzminsky "), timestamp: chrono::Local::now(), description: String::from(""), // FIXME dir, @@ -183,12 +168,9 @@ impl Issue { issue_dir.push(&format!("{:032x}", rnd)); std::fs::create_dir(&issue_dir)?; Ok(Self { - author: String::from(""), - timestamp: chrono::Local::now(), + description: String::from(""), // FIXME: kind of bogus to use the empty string as None state: State::New, dependencies: None, - assignee: None, - description: String::from(""), // FIXME: kind of bogus to use the empty string as None comments: Vec::::new(), dir: issue_dir, }) @@ -251,15 +233,6 @@ impl Issue { self.state = State::from_str(state_string.trim())?; Ok(()) } - - pub fn set_assignee(&mut self, new_assignee: &str) -> Result<(), IssueError> { - let mut assignee_filename = std::path::PathBuf::from(&self.dir); - assignee_filename.push("assignee"); - let mut assignee_file = std::fs::File::create(&assignee_filename)?; - write!(assignee_file, "{}", new_assignee)?; - crate::git::git_commit_file(&assignee_filename)?; - Ok(()) - } } #[cfg(test)] @@ -271,14 +244,9 @@ mod tests { let issue_dir = std::path::Path::new("test/0000/3943fc5c173fdf41c0a22251593cd476d96e6c9f/"); let issue = Issue::new_from_dir(issue_dir).unwrap(); let expected = Issue { - author: String::from("Sebastian Kuzminsky "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T12:14:26-06:00") - .unwrap() - .with_timezone(&chrono::Local), + 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"), state: State::New, 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"), comments: Vec::::new(), dir: std::path::PathBuf::from(issue_dir), }; @@ -290,14 +258,9 @@ mod tests { let issue_dir = std::path::Path::new("test/0000/7792b063eef6d33e7da5dc1856750c149ba678c6/"); let issue = Issue::new_from_dir(issue_dir).unwrap(); let expected = Issue { - author: String::from("Sebastian Kuzminsky "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T12:14:26-06:00") - .unwrap() - .with_timezone(&chrono::Local), + description: String::from("minimal"), state: State::InProgress, dependencies: None, - assignee: Some(String::from("beep boop")), - description: String::from("minimal"), comments: Vec::::new(), dir: std::path::PathBuf::from(issue_dir), }; diff --git a/src/issues.rs b/src/issues.rs index 16dab55..06af867 100644 --- a/src/issues.rs +++ b/src/issues.rs @@ -96,14 +96,9 @@ mod tests { expected.add_issue( uuid, crate::issue::Issue { - author: String::from("Sebastian Kuzminsky "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T12:14:26-06:00") - .unwrap() - .with_timezone(&chrono::Local), + description: String::from("minimal"), state: crate::issue::State::InProgress, dependencies: None, - assignee: Some(String::from("beep boop")), - description: String::from("minimal"), comments: Vec::::new(), dir, }, @@ -115,14 +110,9 @@ mod tests { expected.add_issue( uuid, crate::issue::Issue { - author: String::from("Sebastian Kuzminsky "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T12:14:26-06:00") - .unwrap() - .with_timezone(&chrono::Local), + 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"), state: crate::issue::State::New, 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"), comments: Vec::::new(), dir, } @@ -143,14 +133,9 @@ mod tests { expected.add_issue( uuid, crate::issue::Issue { - author: String::from("Sebastian Kuzminsky "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T11:59:44-06:00") - .unwrap() - .with_timezone(&chrono::Local), + description: String::from("oh yeah we got titles"), state: crate::issue::State::Done, dependencies: None, - assignee: None, - description: String::from("oh yeah we got titles"), comments: Vec::::new(), dir, }, @@ -167,23 +152,17 @@ mod tests { expected_comments.push( crate::comment::Comment { uuid: comment_uuid, - author: String::from("Sebastian Kuzminsky "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-07T15:26:26-06:00").unwrap().with_timezone(&chrono::Local), description: String::from("This is a comment on issue dd79c8cfb8beeacd0460429944b4ecbe95a31561\n\nIt has multiple lines\n"), + timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-07T15:26:26-06:00").unwrap().with_timezone(&chrono::Local), dir: std::path::PathBuf::from(comment_dir), } ); expected.add_issue( uuid, crate::issue::Issue { - author: String::from("Sebastian Kuzminsky "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-03T11:59:44-06:00") - .unwrap() - .with_timezone(&chrono::Local), + description: String::from("issues out the wazoo\n\nLots of words\nthat don't say much\nbecause this is just\na test\n"), state: crate::issue::State::WontDo, 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"), comments: expected_comments, dir, }, @@ -204,14 +183,9 @@ mod tests { expected.add_issue( uuid, crate::issue::Issue { - author: String::from("sigil-03 "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-05T13:55:49-06:00") - .unwrap() - .with_timezone(&chrono::Local), + description: String::from("oh yeah we got titles\n"), state: crate::issue::State::Done, dependencies: None, - assignee: None, - description: String::from("oh yeah we got titles\n"), comments: Vec::::new(), dir, }, @@ -223,14 +197,9 @@ mod tests { expected.add_issue( uuid, crate::issue::Issue { - author: String::from("sigil-03 "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-05T13:55:49-06:00") - .unwrap() - .with_timezone(&chrono::Local), + description: String::from("issues out the wazoo\n\nLots of words\nthat don't say much\nbecause this is just\na test\n"), state: crate::issue::State::WontDo, 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"), comments: Vec::::new(), dir, }, @@ -242,17 +211,12 @@ mod tests { expected.add_issue( uuid, crate::issue::Issue { - author: String::from("sigil-03 "), - timestamp: chrono::DateTime::parse_from_rfc3339("2025-07-05T13:55:49-06:00") - .unwrap() - .with_timezone(&chrono::Local), + description: String::from("issue with dependencies\n\na test has begun\nfor dependencies we seek\nintertwining life"), state: crate::issue::State::WontDo, dependencies: Some(vec![ crate::issue::IssueHandle::from("3fa5bfd93317ad25772680071d5ac3259cd2384f"), crate::issue::IssueHandle::from("dd79c8cfb8beeacd0460429944b4ecbe95a31561"), ]), - assignee: None, - description: String::from("issue with dependencies\n\na test has begun\nfor dependencies we seek\nintertwining life"), comments: Vec::::new(), dir, }, diff --git a/test/0000/7792b063eef6d33e7da5dc1856750c149ba678c6/assignee b/test/0000/7792b063eef6d33e7da5dc1856750c149ba678c6/assignee deleted file mode 100644 index fae06e3..0000000 --- a/test/0000/7792b063eef6d33e7da5dc1856750c149ba678c6/assignee +++ /dev/null @@ -1 +0,0 @@ -beep boop