Compare commits

..

No commits in common. "6b27a560e3c484ae8ec9044a5587b0d083ab2b06" and "cfe49adca90c60bd669b963875f91f76e4ebd6f4" have entirely different histories.

5 changed files with 101 additions and 181 deletions

View file

@ -415,114 +415,116 @@ fn handle_command(
Commands::Assign { Commands::Assign {
issue_id, issue_id,
new_assignee, new_assignee,
} => match new_assignee { } => {
Some(new_assignee) => { let issues = entomologist::database::read_issues_database(issues_database_source)?;
let issues_database = entomologist::database::make_issues_database( let Some(original_issue) = issues.issues.get(issue_id) else {
issues_database_source, return Err(anyhow::anyhow!("issue {} not found", issue_id));
entomologist::database::IssuesDatabaseAccess::ReadWrite, };
)?; let old_assignee: String = match &original_issue.assignee {
let mut issues = entomologist::issues::Issues::new_from_dir(&issues_database.dir)?; Some(assignee) => assignee.clone(),
let Some(issue) = issues.get_mut_issue(issue_id) else { None => String::from("None"),
return Err(anyhow::anyhow!("issue {} not found", issue_id)); };
}; println!("issue: {}", issue_id);
let old_assignee: String = match &issue.assignee { match new_assignee {
Some(assignee) => assignee.clone(), Some(new_assignee) => {
None => String::from("None"), let issues_database = entomologist::database::make_issues_database(
}; issues_database_source,
issue.set_assignee(new_assignee)?; entomologist::database::IssuesDatabaseAccess::ReadWrite,
println!("issue: {}", issue_id); )?;
println!("assignee: {} -> {}", old_assignee, new_assignee); let mut issues =
entomologist::issues::Issues::new_from_dir(&issues_database.dir)?;
let Some(issue) = issues.get_mut_issue(issue_id) else {
return Err(anyhow::anyhow!("issue {} not found", issue_id));
};
println!("assignee: {} -> {}", old_assignee, new_assignee);
issue.set_assignee(new_assignee)?;
}
None => {
println!("assignee: {}", old_assignee);
}
} }
None => { }
let issues = entomologist::database::read_issues_database(issues_database_source)?;
let Some(original_issue) = issues.issues.get(issue_id) else {
return Err(anyhow::anyhow!("issue {} not found", issue_id));
};
let old_assignee: String = match &original_issue.assignee {
Some(assignee) => assignee.clone(),
None => String::from("None"),
};
println!("issue: {}", issue_id);
println!("assignee: {}", old_assignee);
}
},
Commands::Tag { issue_id, tag } => match tag { Commands::Tag { issue_id, tag } => {
Some(tag) => { let issues = entomologist::database::read_issues_database(issues_database_source)?;
// Add or remove tag. let Some(issue) = issues.issues.get(issue_id) else {
if tag.len() == 0 { return Err(anyhow::anyhow!("issue {} not found", issue_id));
return Err(anyhow::anyhow!("invalid zero-length tag")); };
match tag {
Some(tag) => {
// Add or remove tag.
let issues_database = entomologist::database::make_issues_database(
issues_database_source,
entomologist::database::IssuesDatabaseAccess::ReadWrite,
)?;
let mut issues =
entomologist::issues::Issues::new_from_dir(&issues_database.dir)?;
let Some(issue) = issues.get_mut_issue(issue_id) else {
return Err(anyhow::anyhow!("issue {} not found", issue_id));
};
if tag.len() == 0 {
return Err(anyhow::anyhow!("invalid zero-length tag"));
}
if tag.chars().nth(0).unwrap() == '-' {
let tag = &tag[1..];
issue.remove_tag(tag)?;
} else {
issue.add_tag(tag)?;
}
} }
let issues_database = entomologist::database::make_issues_database( None => {
issues_database_source, // Just list the tags.
entomologist::database::IssuesDatabaseAccess::ReadWrite, match &issue.tags.len() {
)?; 0 => println!("no tags"),
let mut issues = entomologist::issues::Issues::new_from_dir(&issues_database.dir)?; _ => {
let Some(issue) = issues.get_mut_issue(issue_id) else { // Could use `format!(" {:?}", issue.tags)`
return Err(anyhow::anyhow!("issue {} not found", issue_id)); // here, but that results in `["tag1", "TAG2",
}; // "i-am-also-a-tag"]` and i don't want the
if tag.chars().nth(0).unwrap() == '-' { // double-quotes around each tag.
let tag = &tag[1..]; for tag in &issue.tags {
issue.remove_tag(tag)?; println!("{}", tag);
} else { }
issue.add_tag(tag)?;
}
}
None => {
// Just list the tags.
let issues = entomologist::database::read_issues_database(issues_database_source)?;
let Some(issue) = issues.issues.get(issue_id) else {
return Err(anyhow::anyhow!("issue {} not found", issue_id));
};
match &issue.tags.len() {
0 => println!("no tags"),
_ => {
// Could use `format!(" {:?}", issue.tags)`
// here, but that results in `["tag1", "TAG2",
// "i-am-also-a-tag"]` and i don't want the
// double-quotes around each tag.
for tag in &issue.tags {
println!("{}", tag);
} }
} }
} }
} }
}, }
Commands::DoneTime { Commands::DoneTime {
issue_id, issue_id,
done_time, done_time,
} => match done_time { } => {
Some(done_time) => { let issues = entomologist::database::read_issues_database(issues_database_source)?;
// Add or remove tag. let Some(issue) = issues.issues.get(issue_id) else {
let issues_database = entomologist::database::make_issues_database( return Err(anyhow::anyhow!("issue {} not found", issue_id));
issues_database_source, };
entomologist::database::IssuesDatabaseAccess::ReadWrite, match done_time {
)?; Some(done_time) => {
let mut issues = entomologist::issues::Issues::new_from_dir(&issues_database.dir)?; // Add or remove tag.
let Some(issue) = issues.get_mut_issue(issue_id) else { let issues_database = entomologist::database::make_issues_database(
return Err(anyhow::anyhow!("issue {} not found", issue_id)); issues_database_source,
}; entomologist::database::IssuesDatabaseAccess::ReadWrite,
let done_time = match chrono::DateTime::parse_from_rfc3339(done_time) { )?;
Ok(done_time) => done_time.with_timezone(&chrono::Local), let mut issues =
Err(e) => { entomologist::issues::Issues::new_from_dir(&issues_database.dir)?;
eprintln!("failed to parse done-time from {}", done_time); let Some(issue) = issues.get_mut_issue(issue_id) else {
return Err(e.into()); return Err(anyhow::anyhow!("issue {} not found", issue_id));
} };
}; let done_time = match chrono::DateTime::parse_from_rfc3339(done_time) {
issue.set_done_time(done_time)?; Ok(done_time) => done_time.with_timezone(&chrono::Local),
} Err(e) => {
None => { eprintln!("failed to parse done-time from {}", done_time);
let issues = entomologist::database::read_issues_database(issues_database_source)?; return Err(e.into());
let Some(issue) = issues.issues.get(issue_id) else { }
return Err(anyhow::anyhow!("issue {} not found", issue_id)); };
}; issue.set_done_time(done_time)?;
match &issue.done_time { }
None => match &issue.done_time {
Some(done_time) => println!("done_time: {}", done_time), Some(done_time) => println!("done_time: {}", done_time),
None => println!("None"), None => println!("None"),
}; },
} };
}, }
Commands::Depend { Commands::Depend {
issue_id, issue_id,

View file

@ -52,8 +52,8 @@ impl Comment {
return Err(CommentError::CommentParseError); return Err(CommentError::CommentParseError);
}; };
let (author, creation_time) = crate::git::git_log_oldest_author_timestamp(comment_dir)?; let author = crate::git::git_log_oldest_author(comment_dir)?;
let creation_time = crate::git::git_log_oldest_timestamp(comment_dir)?;
let dir = std::path::PathBuf::from(comment_dir); let dir = std::path::PathBuf::from(comment_dir);
Ok(Self { Ok(Self {

View file

@ -395,46 +395,6 @@ pub fn git_log_oldest_author(path: &std::path::Path) -> Result<String, GitError>
Ok(String::from(author_last)) Ok(String::from(author_last))
} }
pub fn git_log_oldest_author_timestamp(
path: &std::path::Path,
) -> Result<(String, chrono::DateTime<chrono::Local>), GitError> {
let mut git_dir = std::path::PathBuf::from(path);
git_dir.pop();
let result = std::process::Command::new("git")
.args([
"log",
"--pretty=format:%at %an <%ae>",
"--",
&path
.file_name()
.ok_or(std::io::Error::from(std::io::ErrorKind::NotFound))?
.to_string_lossy(),
])
.current_dir(&git_dir)
.output()?;
if !result.status.success() {
println!("stdout: {}", &String::from_utf8_lossy(&result.stdout));
println!("stderr: {}", &String::from_utf8_lossy(&result.stderr));
return Err(GitError::Oops);
}
let raw_output_str = String::from_utf8_lossy(&result.stdout);
let Some(raw_output_last) = raw_output_str.split("\n").last() else {
return Err(GitError::Oops);
};
let Some(index) = raw_output_last.find(' ') else {
return Err(GitError::Oops);
};
let author_str = &raw_output_last[index + 1..];
let timestamp_str = &raw_output_last[0..index];
let timestamp_i64 = timestamp_str.parse::<i64>()?;
let timestamp = chrono::DateTime::from_timestamp(timestamp_i64, 0)
.unwrap()
.with_timezone(&chrono::Local);
Ok((String::from(author_str), timestamp))
}
pub fn create_orphan_branch(branch: &str) -> Result<(), GitError> { pub fn create_orphan_branch(branch: &str) -> Result<(), GitError> {
{ {
let tmp_worktree = tempfile::tempdir().unwrap(); let tmp_worktree = tempfile::tempdir().unwrap();

View file

@ -166,7 +166,8 @@ impl Issue {
Err(IssueError::IdError)? Err(IssueError::IdError)?
}; };
let (author, creation_time) = crate::git::git_log_oldest_author_timestamp(dir)?; let author = crate::git::git_log_oldest_author(dir)?;
let creation_time = crate::git::git_log_oldest_timestamp(dir)?;
Ok(Self { Ok(Self {
id, id,

View file

@ -1,43 +0,0 @@
#!/bin/bash
#
# * Create a temporary ent issue database branch based on a specific
# commit in `entomologist-data`.
#
# * Perform some ent operations on this temporary branch and measure
# the runtime.
#
# * Clean up by deleteting the temporary branch.
set -e
#set -x
# This is a commit in the `entomologist-data` branch that we're somewhat
# arbitrarily using here to time different `ent` operations.
TEST_COMMIT=a33f1165d77571d770f1a1021afe4c07360247f0
# This is the branch that we create from the above commit and test our
# `ent` operations on. We'll delete this branch when we're done with
# the tests.
TEST_BRANCH=$(mktemp --dry-run entomologist-data-XXXXXXXX)
function time_ent() {
echo timing: ent "$@"
time -p ent -b "${TEST_BRANCH}" "$@"
echo
}
git branch "${TEST_BRANCH}" "${TEST_COMMIT}"
time_ent tag 7e2a3a59fb6b77403ff1035255367607
time_ent tag 7e2a3a59fb6b77403ff1035255367607 new-tag
time_ent assign 7e2a3a59fb6b77403ff1035255367607
time_ent assign 7e2a3a59fb6b77403ff1035255367607 new-user
time_ent done-time 7e2a3a59fb6b77403ff1035255367607
time_ent done-time 7e2a3a59fb6b77403ff1035255367607 2025-04-01T01:23:45-06:00
git branch -D "${TEST_BRANCH}"