use anyhow::{Context, Result};
use async_compression::tokio::bufread::GzipDecoder;
use async_compression::tokio::write::GzipEncoder;
use async_tar::Archive;
use spin_common::ui::quoted_path;
use std::path::{Path, PathBuf};
pub async fn archive(source: &Path, working_dir: &Path) -> Result<PathBuf> {
let tar_gz_path = working_dir
.join(source.file_name().unwrap())
.with_extension("tar.gz");
let tar_gz = tokio::fs::File::create(tar_gz_path.as_path())
.await
.context(format!(
"Unable to create tar archive for source {}",
quoted_path(source)
))?;
let tar_gz_enc = GzipEncoder::new(tar_gz);
let mut tar_builder = async_tar::Builder::new(
tokio_util::compat::TokioAsyncWriteCompatExt::compat_write(tar_gz_enc),
);
tar_builder
.append_dir_all(".", source)
.await
.context(format!(
"Unable to create tar archive for source {}",
quoted_path(source)
))?;
tar_builder.finish().await?;
use tokio::io::AsyncWriteExt;
tar_builder
.into_inner()
.await?
.into_inner()
.shutdown()
.await?;
Ok(tar_gz_path)
}
pub async fn unarchive(source: &Path, dest: &Path) -> Result<()> {
let decoder = GzipDecoder::new(tokio::io::BufReader::new(
tokio::fs::File::open(source).await?,
));
let archive = Archive::new(tokio_util::compat::TokioAsyncReadCompatExt::compat(decoder));
if let Err(e) = archive.unpack(dest).await {
return Err(e.into());
};
Ok(())
}