use std::{
fmt::Error,
io::{stdin, IsTerminal, Read},
path::PathBuf,
};
use clap::Parser;
use crate::git::{self, ReadCommitMessageOptions};
use crate::message::Message;
#[derive(Parser, Debug)]
#[command(author, about = "CLI to lint with conventional commits", long_about = None, version)]
pub struct Args {
#[arg(short = 'g', long)]
pub config: Option<PathBuf>,
#[arg(short = 'd', long, default_value = ".")]
pub cwd: String,
#[arg(short = 'e', long)]
pub edit: Option<String>,
#[arg(short = 'f', long)]
pub from: Option<String>,
#[arg(long = "print-config")]
pub print_config: bool,
#[arg(short = 't', long)]
pub to: Option<String>,
}
impl Args {
fn has_stdin(&self) -> bool {
!stdin().is_terminal()
}
pub fn read(&self) -> Result<Vec<Message>, Error> {
if let Some(edit) = self.edit.as_deref() {
if edit != "false" {
let msg = std::fs::read_to_string(edit)
.expect(format!("Failed to read commit message from {}", edit).as_str());
return Ok(vec![Message::new(msg)]);
}
}
if self.has_stdin() {
let mut buffer = String::new();
stdin()
.read_to_string(&mut buffer)
.expect("Failed to read commit messages from stdin");
return Ok(vec![Message::new(buffer)]);
}
if self.from.is_some() || self.to.is_some() {
let config = ReadCommitMessageOptions {
from: self.from.clone(),
path: self.cwd.clone(),
to: self.to.clone(),
};
let messages = git::read(config)
.iter()
.map(|s| Message::new(s.to_string()))
.collect();
return Ok(messages);
}
let default_path = git::edit_msg_path(&self.cwd);
let msg = std::fs::read_to_string(&default_path).expect(
format!(
"Failed to read commit message from {}",
default_path.display()
)
.as_str(),
);
Ok(vec![Message::new(msg)])
}
}