use std::io::Write;
use std::path::PathBuf;
use anyhow::bail;
use clap::Clap;
use libpijul::changestore::*;
use libpijul::{Base32, TxnT, TxnTExt};
use crate::repository::Repository;
#[derive(Clap, Debug)]
pub struct Log {
#[clap(long = "repository")]
repo_path: Option<PathBuf>,
#[clap(long = "channel")]
channel: Option<String>,
#[clap(long = "hash-only")]
hash_only: bool,
#[clap(long = "state")]
states: bool,
#[clap(long = "description")]
descriptions: bool,
}
impl Log {
pub fn run(self) -> Result<(), anyhow::Error> {
let repo = Repository::find_root(self.repo_path)?;
let txn = repo.pristine.txn_begin()?;
let channel_name = repo.config.get_current_channel(self.channel.as_ref());
let channel = if let Some(channel) = txn.load_channel(channel_name)? {
channel
} else {
bail!("No such channel: {:?}", channel_name)
};
super::pager();
let changes = repo.changes;
let mut stdout = std::io::stdout();
if self.hash_only {
for h in txn.reverse_log(&channel.borrow(), None)? {
let h = (h?.1).0;
writeln!(stdout, "{}", h.to_base32())?
}
} else {
let states = self.states;
for h in txn.reverse_log(&channel.borrow(), None)? {
let (h, mrk) = h?.1;
let header = changes.get_header(&h)?;
writeln!(stdout, "Change {}", h.to_base32())?;
writeln!(stdout, "Author: {:?}", header.authors)?;
writeln!(stdout, "Date: {}", header.timestamp)?;
if states {
writeln!(stdout, "State: {}", mrk.to_base32())?;
}
writeln!(stdout, "\n {}\n", header.message)?;
if self.descriptions {
if let Some(ref descr) = header.description {
writeln!(stdout, "\n {}\n", descr)?;
}
}
}
}
Ok(())
}
}