use std::io;
use std::path::Path;
#[derive(Debug, Clone, Default)]
pub struct ContextTar {
bytes: Vec<u8>,
}
impl ContextTar {
pub fn from_dir(dir: impl AsRef<Path>) -> io::Result<Self> {
let mut builder = tar::Builder::new(Vec::new());
builder.follow_symlinks(false);
builder.append_dir_all(".", dir.as_ref())?;
let bytes = builder.into_inner()?;
Ok(Self { bytes })
}
pub fn from_inline_dockerfile(dockerfile_name: &str, content: &str) -> io::Result<Self> {
let mut builder = tar::Builder::new(Vec::new());
append_bytes(&mut builder, dockerfile_name, content.as_bytes())?;
let bytes = builder.into_inner()?;
Ok(Self { bytes })
}
pub fn from_dir_with_dockerfile(
dir: impl AsRef<Path>,
dockerfile_name: &str,
content: &str,
) -> io::Result<Self> {
let mut builder = tar::Builder::new(Vec::new());
builder.follow_symlinks(false);
builder.append_dir_all(".", dir.as_ref())?;
append_bytes(&mut builder, dockerfile_name, content.as_bytes())?;
let bytes = builder.into_inner()?;
Ok(Self { bytes })
}
#[must_use]
pub fn as_bytes(&self) -> &[u8] {
&self.bytes
}
#[must_use]
pub fn into_bytes(self) -> Vec<u8> {
self.bytes
}
#[must_use]
pub fn len(&self) -> usize {
self.bytes.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.bytes.is_empty()
}
}
fn append_bytes<W: io::Write>(
builder: &mut tar::Builder<W>,
name: &str,
data: &[u8],
) -> io::Result<()> {
let mut header = tar::Header::new_gnu();
header.set_size(data.len() as u64);
header.set_mode(0o644);
header.set_cksum();
builder.append_data(&mut header, name, data)
}