pijul 1.0.0-alpha

The sound distributed version control system.
use crate::repository::*;
use libanu::change::Local;
use libanu::changestore::ChangeStore;
use libanu::pristine::*;
use libanu::*;
use std::path::PathBuf;

#[derive(Clap, Debug)]
pub struct Change {
    #[clap(long = "repository")]
    repo_path: Option<PathBuf>,
    #[clap(long = "channel")]
    channel: Option<String>,
    hash: String,
}

impl Change {
    pub fn run(self) -> Result<(), anyhow::Error> {
        let repo = Repository::find_root(self.repo_path.clone())?;
        let txn = repo.pristine.txn_begin()?;
        let channel_name = repo.config.get_current_channel(self.channel.as_ref());
        let channel = txn.load_channel(channel_name).unwrap();
        let changes = repo.changes;
        let (hash, _) = txn.hash_from_prefix(&self.hash)?;
        let change = changes.get_change(&hash).unwrap();
        let file_name = |l: &Local, inode: Position<Option<Hash>>| -> String {
            if txn.get_revchanges(&channel, hash).is_some() {
                let inode = Position {
                    change: inode.change.unwrap_or(hash),
                    pos: inode.pos,
                };
                format!(
                    "{}:{}",
                    txn.find_youngest_path(&changes, &channel, inode).unwrap().0,
                    l.line
                )
            } else {
                format!("{}:{}", l.path, l.line)
            }
        };
        let o = std::io::stdout();
        let mut o = o.lock();
        change.write(&changes, Some(hash), file_name, true, &mut o)?;
        Ok(())
    }
}