use crate::repository::Repository;
use libpijul::pristine::{Hash, Merkle, TxnT};
use libpijul::{MutTxnTExt, TxnTExt};
use std::path::PathBuf;
#[derive(Clap, Debug)]
pub struct Archive {
#[clap(long = "repository")]
repo_path: Option<PathBuf>,
#[clap(long = "channel")]
channel: Option<String>,
#[clap(long = "remote")]
remote: Option<String>,
#[clap(short = 'k', about="Do not check certificates")]
no_cert_check: bool,
#[clap(long = "state")]
state: Option<String>,
#[clap(long = "change", multiple = true)]
change: Vec<String>,
#[clap(long = "prefix")]
prefix: Option<String>,
#[clap(short = 'o')]
name: String,
}
impl Archive {
pub async fn run(self) -> Result<(), anyhow::Error> {
let state: Option<Merkle> = if let Some(ref state) = self.state {
Some(state.parse()?)
} else {
None
};
let mut extra: Vec<Hash> = Vec::new();
for h in self.change.iter() {
extra.push(h.parse()?);
}
if let Some(ref rem) = self.remote {
debug!("unknown");
let mut remote = crate::remote::unknown_remote(
rem,
if let Some(ref channel) = self.channel {
channel
} else {
crate::DEFAULT_CHANNEL
},
self.no_cert_check
)
.await?;
let mut p = std::path::Path::new(&self.name).to_path_buf();
if !self.name.ends_with(".tar.gz") {
p.set_extension("tar.gz");
}
let mut f = std::fs::File::create(&p)?;
remote
.archive(self.prefix, state.map(|x| (x, &extra[..])), &mut f)
.await?;
} else if let Ok(repo) = Repository::find_root(self.repo_path.clone()) {
let channel_name = repo.config.get_current_channel(self.channel.as_ref());
let mut p = std::path::Path::new(&self.name).to_path_buf();
if !self.name.ends_with(".tar.gz") {
p.set_extension("tar.gz");
}
let mut f = std::fs::File::create(&p)?;
let mut tarball = libpijul::output::Tarball::new(&mut f, self.prefix);
let conflicts = if let Some(state) = state {
let mut txn = repo.pristine.mut_txn_begin();
let mut channel = txn.load_channel(&channel_name).unwrap();
txn.archive_with_state(
&repo.changes,
&mut channel,
state,
&extra[..],
&mut tarball,
)?
} else {
let txn = repo.pristine.txn_begin()?;
let channel = txn.load_channel(&channel_name).unwrap();
txn.archive(&repo.changes, &channel, &mut tarball)?
};
if !conflicts.is_empty() {
eprintln!("There were {} conflicts", conflicts.len())
}
}
Ok(())
}
}