use breezyshim::branch::Branch;
use breezyshim::error::Error as BrzError;
use breezyshim::prelude::Repository;
use breezyshim::tree::PyTree;
use breezyshim::workingtree::{GenericWorkingTree, WorkingTree};
use std::path::{Path, PathBuf};
use url::Url;
pub fn export_vcs_tree<T: PyTree>(
tree: &T,
directory: &Path,
subpath: Option<&Path>,
) -> Result<(), BrzError> {
breezyshim::export::export(tree, directory, subpath)
}
pub trait DupableTree {
fn basis_tree(&self) -> breezyshim::tree::RevisionTree;
fn get_parent(&self) -> Option<String>;
fn basedir(&self) -> Option<PathBuf>;
fn export_to(&self, directory: &Path, subpath: Option<&Path>) -> Result<(), BrzError>;
}
impl DupableTree for GenericWorkingTree {
fn basis_tree(&self) -> breezyshim::tree::RevisionTree {
WorkingTree::basis_tree(self).unwrap()
}
fn get_parent(&self) -> Option<String> {
WorkingTree::branch(self).get_parent()
}
fn basedir(&self) -> Option<PathBuf> {
Some(WorkingTree::basedir(self))
}
fn export_to(&self, directory: &Path, subpath: Option<&Path>) -> Result<(), BrzError> {
export_vcs_tree(self, directory, subpath)
}
}
impl DupableTree for breezyshim::tree::RevisionTree {
fn basis_tree(&self) -> breezyshim::tree::RevisionTree {
self.repository()
.revision_tree(&self.get_revision_id())
.unwrap()
}
fn get_parent(&self) -> Option<String> {
let branch = self.repository().controldir().open_branch(None).unwrap();
branch.get_parent()
}
fn basedir(&self) -> Option<PathBuf> {
None
}
fn export_to(&self, directory: &Path, subpath: Option<&Path>) -> Result<(), BrzError> {
export_vcs_tree(self, directory, subpath)
}
}
pub fn dupe_vcs_tree(orig_tree: &dyn DupableTree, directory: &Path) -> Result<(), BrzError> {
let tree = orig_tree.basis_tree();
let result = tree.repository().controldir().sprout(
Url::from_directory_path(directory).unwrap(),
None,
Some(true),
None,
Some(&tree.get_revision_id()),
)?;
assert!(result.has_workingtree());
if let Some(parent) = orig_tree.get_parent() {
let mut branch = result.open_branch(None)?;
branch.set_parent(&parent);
}
Ok(())
}