Adjust `Creator` struct to use Vec<PathBuf> instead of Vec<DirEntry>;

Add `from_list` method for `Creator`
This commit is contained in:
Nathan Fisher 2023-03-30 18:43:11 -04:00
parent efb28a30e2
commit 71a87a506e
3 changed files with 19 additions and 72 deletions

View File

@ -26,7 +26,7 @@ pub enum Message {
pub struct Creator {
path: PathBuf,
entries: Vec<Result<DirEntry, walkdir::Error>>,
entries: Vec<PathBuf>,
specs: Specs,
}
@ -35,7 +35,11 @@ impl Creator {
let d = env::current_dir()?;
env::set_current_dir(path)?;
let path = path.to_path_buf();
let entries = WalkDir::new(".").into_iter().collect::<Vec<_>>();
let entries = WalkDir::new(".")
.into_iter()
.filter(|x| x.is_ok())
.map(|x| x.unwrap().path().to_path_buf())
.collect::<Vec<_>>();
env::set_current_dir(d)?;
Ok(Self {
path,
@ -44,6 +48,15 @@ impl Creator {
})
}
fn from_list(list: &[&str], specs: Specs) -> Result<Self, io::Error> {
let entries = list.iter().map(|x| Path::new(x).to_path_buf()).collect();
Ok(Self {
path: env::current_dir().unwrap_or(Path::new("/").to_path_buf()),
entries,
specs,
})
}
pub fn len(&self) -> usize {
self.entries.len()
}
@ -69,12 +82,10 @@ impl Creator {
env::set_current_dir(&self.path)?;
self.entries
.par_iter()
.filter(|x| x.is_ok())
.map(|x| x.as_ref().unwrap())
.filter(|x| x.path() != Path::new("."))
.filter(|x| x.as_path() != Path::new("."))
.for_each(|x| {
let sender = sender.lock().unwrap().clone();
if let Ok(item) = Item::try_create(x.path().to_path_buf().as_path()) {
if let Ok(item) = Item::try_create(x.as_path()) {
if let Entry::File {
path: _,
sha256sum: _,
@ -107,7 +118,7 @@ impl Creator {
sender
.send(Message::Failure(format!(
"Could not process DirEntry for {}",
x.path().display()
x.display()
)))
.expect("could not send message");
}

View File

@ -13,7 +13,7 @@ pub use {
db::Database,
hooks::Hooks,
item::Item,
package::{create_package, Dependency, Package, Specs},
package::{Dependency, Package, Specs},
plist::*,
repository::Repository,
tar,

View File

@ -127,67 +127,3 @@ impl Package {
|| (self.version == other.version && self.release > other.release))
}
}
/// Creates a package archive given a path to the included files, a package `Specs`
/// file and an output directory
///
/// ## Usage
/// ```
/// use std::path::Path;
/// use hpk::Specs;
///
/// let staging = Path::new("staged");
/// let outdir = Path::new("package");
/// let specs = Specs {
/// name: "foo".to_string(),
/// version: "0.42.0".parse().unwrap(),
/// description: "an example package".to_string(),
/// ..Default::default()
/// };
/// let result = hpk::create_package(&staging, specs, &outdir);
pub fn create_package(path: &Path, specs: Specs, outdir: &Path) -> Result<(), Box<dyn Error>> {
if !outdir.exists() {
fs::create_dir_all(outdir)?;
}
let outdir = outdir.canonicalize()?;
env::set_current_dir(path)?;
let mut items = WalkDir::new(".")
.into_iter()
.collect::<Vec<_>>()
.par_iter()
.filter(|x| x.is_ok())
.filter_map(|x| Item::try_create(x.as_ref().unwrap().path().to_path_buf().as_path()).ok())
.collect::<Vec<_>>();
let mut plist = Plist::default();
let mut archive = vec![];
let mut totalsize = 0;
while let Some(item) = items.pop() {
if let Entry::File {
path: _,
sha256sum: _,
mode: _,
size,
} = &item.entry
{
totalsize += size;
}
plist.entries.push(item.entry);
archive.extend(item.data);
}
let mut package: Package = specs.into();
package.plist = plist;
package.size = totalsize;
let node = package.save_ron_and_create_tar_node(&outdir)?.to_vec()?;
archive.extend(node);
let name = package.fullname();
let mut path = PathBuf::from(&name);
path.set_extension("tar.zst");
let mut outfile = outdir;
outfile.push(path);
let fd = File::create(&outfile)?;
let mut writer = Encoder::new(fd, 0)?;
writer.write_all(&archive)?;
let _fd = writer.finish()?;
println!("{} saved", outfile.display());
Ok(())
}