add ent new

This commit is contained in:
Sebastian Kuzminsky 2025-07-06 00:12:22 -06:00
parent 5e482edb5c
commit 09373cda56
2 changed files with 64 additions and 9 deletions

View file

@ -22,10 +22,7 @@ enum Commands {
List,
/// Create a new issue.
New {
title: Option<String>,
description: Option<String>,
},
New { description: Option<String> },
}
fn handle_command(args: &Args, issues_dir: &std::path::Path) -> anyhow::Result<()> {
@ -37,11 +34,17 @@ fn handle_command(args: &Args, issues_dir: &std::path::Path) -> anyhow::Result<(
println!("{} {} ({:?})", uuid, issue.title(), issue.state);
}
}
Commands::New { title, description } => {
println!(
"should make a new issue, title={:?}, description={:?}",
title, description
);
Commands::New {
description: Some(description),
} => {
let mut issue = entomologist::issue::Issue::new(issues_dir)?;
issue.set_description(description)?;
println!("created new issue '{}'", issue.title());
}
Commands::New { description: None } => {
let mut issue = entomologist::issue::Issue::new(issues_dir)?;
issue.edit_description()?;
println!("created new issue '{}'", issue.title());
}
}

View file

@ -1,3 +1,4 @@
use std::io::Write;
use std::str::FromStr;
#[derive(Debug, PartialEq, serde::Deserialize)]
@ -30,6 +31,10 @@ pub enum IssueError {
StdIoError(#[from] std::io::Error),
#[error("Failed to parse issue")]
IssueParseError,
#[error("Failed to run git")]
GitError(#[from] crate::git::GitError),
#[error("Failed to run editor")]
EditorError,
}
impl FromStr for State {
@ -95,6 +100,53 @@ impl Issue {
})
}
pub fn new(dir: &std::path::Path) -> Result<Self, IssueError> {
let mut issue_dir = std::path::PathBuf::from(dir);
let rnd: u128 = rand::random();
issue_dir.push(&format!("{:0x}", rnd));
std::fs::create_dir(&issue_dir)?;
Ok(Self {
description: String::from(""), // FIXME: kind of bogus to use the empty string as None
state: State::New,
dependencies: None,
dir: issue_dir,
})
}
pub fn set_description(&mut self, description: &str) -> Result<(), IssueError> {
self.description = String::from(description);
let mut description_filename = std::path::PathBuf::from(&self.dir);
description_filename.push("description");
let mut description_file = std::fs::File::create(&description_filename)?;
write!(description_file, "{}", description)?;
crate::git::git_commit_file(&description_filename)?;
Ok(())
}
pub fn read_description(&mut self) -> Result<(), IssueError> {
let mut description_filename = std::path::PathBuf::from(&self.dir);
description_filename.push("description");
self.description = std::fs::read_to_string(description_filename)?;
Ok(())
}
pub fn edit_description(&mut self) -> Result<(), IssueError> {
let mut description_filename = std::path::PathBuf::from(&self.dir);
description_filename.push("description");
let result = std::process::Command::new("vi")
.arg(&description_filename.as_mut_os_str())
.spawn()?
.wait_with_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(IssueError::EditorError);
}
crate::git::git_commit_file(&description_filename)?;
self.read_description()?;
Ok(())
}
pub fn title<'a>(&'a self) -> &'a str {
match self.description.find("\n") {
Some(index) => &self.description.as_str()[..index],