#![allow(unused)]
use std::fs::{self, File};
use std::io;
use std::net::IpAddr;
use std::net::Ipv4Addr;
use std::net::SocketAddr;
use std::path::Path;
use std::sync::Mutex;
use duct::cmd;
use rand::Rng;
pub const SERVER_ADDR: SocketAddr =
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 0);
pub struct GitRepo {
repo: tempfile::TempDir,
}
impl GitRepo {
pub fn init(lfs_server: SocketAddr) -> io::Result<Self> {
let repo = tempfile::TempDir::new()?;
let path = repo.path();
cmd!("git", "init", ".").dir(path).run()?;
git_lfs_install(path)?;
cmd!("git", "remote", "add", "origin", "fake_remote")
.dir(path)
.run()?;
cmd!(
"git",
"config",
"lfs.url",
format!("http://{}/api/test/test", lfs_server)
)
.dir(path)
.run()?;
cmd!("git", "config", "user.name", "Foo Bar")
.dir(path)
.run()?;
cmd!("git", "config", "user.email", "foobar@example.com")
.dir(path)
.run()?;
cmd!("git", "lfs", "track", "*.bin").dir(path).run()?;
cmd!("git", "add", ".gitattributes").dir(path).run()?;
cmd!("git", "commit", "-m", "Initial commit")
.dir(path)
.run()?;
Ok(Self { repo })
}
pub fn clone_repo(&self) -> io::Result<Self> {
let repo = tempfile::TempDir::new()?;
let src_dir_str = self
.repo
.path()
.to_str()
.expect("could not convert src repo path to str");
let dst_dir_str = repo
.path()
.to_str()
.expect("could not convert src repo path to str");
cmd!("git", "clone", src_dir_str, dst_dir_str).run()?;
Ok(Self { repo })
}
pub fn add_random<R: Rng>(
&self,
path: &Path,
size: usize,
rng: &mut R,
) -> io::Result<()> {
let mut file = File::create(self.repo.path().join(path))?;
gen_file(&mut file, size, rng)?;
cmd!("git", "add", path).dir(self.repo.path()).run()?;
Ok(())
}
pub fn commit(&self, message: &str) -> io::Result<()> {
cmd!("git", "commit", "-m", message)
.dir(self.repo.path())
.run()?;
Ok(())
}
pub fn lfs_push(&self) -> io::Result<()> {
cmd!("git", "lfs", "push", "origin", "master")
.dir(self.repo.path())
.run()?;
Ok(())
}
pub fn lfs_pull(&self) -> io::Result<()> {
cmd!("git", "lfs", "pull").dir(self.repo.path()).run()?;
Ok(())
}
pub fn pull(&self) -> io::Result<()> {
cmd!("git", "pull").dir(self.repo.path()).run()?;
Ok(())
}
pub fn clean_lfs(&self) -> io::Result<()> {
fs::remove_dir_all(self.repo.path().join(".git/lfs"))
}
}
fn gen_file<W, R>(
writer: &mut W,
mut size: usize,
rng: &mut R,
) -> io::Result<()>
where
W: io::Write,
R: Rng,
{
let mut buf = [0u8; 4096];
while size > 0 {
let to_write = buf.len().min(size);
let buf = &mut buf[..to_write];
rng.fill(buf);
writer.write_all(buf)?;
size -= to_write;
}
Ok(())
}
pub fn init_logger() -> tracing::subscriber::DefaultGuard {
let subscriber = tracing_subscriber::fmt().with_test_writer().finish();
tracing::subscriber::set_default(subscriber)
}
fn git_lfs_install(path: &Path) -> io::Result<()> {
static LFS_INSTALL: Mutex<()> = Mutex::new(());
let _guard = LFS_INSTALL.lock().unwrap();
cmd!("git", "lfs", "install").dir(path).run()?;
Ok(())
}