Use try_for_each_with
in Creator::create in order to avoid putting
Sender in a mutex and return errors rather than passing messages
This commit is contained in:
parent
be0c8dc6e7
commit
d3b5d096e5
@ -1,11 +1,14 @@
|
||||
use hpk_package::deku::DekuError;
|
||||
|
||||
use {
|
||||
crate::{Item, Package, Plist, Specs},
|
||||
hpk_package::Entry,
|
||||
crate::{Item, ItemError, Package, Plist, Specs},
|
||||
hpk_package::{tar, Entry},
|
||||
rayon::prelude::{IntoParallelRefIterator, ParallelIterator},
|
||||
std::{
|
||||
borrow::BorrowMut,
|
||||
env,
|
||||
error::Error,
|
||||
fmt,
|
||||
fs::{self, File},
|
||||
io::{self, Write},
|
||||
path::{Path, PathBuf},
|
||||
@ -19,10 +22,10 @@ use {
|
||||
zstd::Encoder,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Message {
|
||||
MemberAdded(String),
|
||||
Success(String),
|
||||
Failure(String),
|
||||
}
|
||||
|
||||
/// Creates a package archive
|
||||
@ -90,51 +93,38 @@ impl Creator {
|
||||
archive.set_extension("tar.zst");
|
||||
let fd = File::create(&archive)?;
|
||||
let writer = Mutex::new(Encoder::new(fd, 0)?);
|
||||
let sender = Mutex::new(sender);
|
||||
env::set_current_dir(&self.path)?;
|
||||
let s = sender.clone();
|
||||
self.entries
|
||||
.par_iter()
|
||||
.filter(|x| x.as_path() != Path::new("."))
|
||||
.for_each(|x| {
|
||||
let sender = sender.lock().unwrap().clone();
|
||||
if let Ok(item) = Item::try_create(x.as_path()) {
|
||||
if let Entry::File {
|
||||
path: _,
|
||||
.try_for_each_with(s, |s, x| {
|
||||
let item = Item::try_create(x.as_path())?;
|
||||
if let Entry::File {
|
||||
path: _,
|
||||
sha256sum: _,
|
||||
mode: _,
|
||||
size,
|
||||
} = &item.entry
|
||||
{
|
||||
totalsize.fetch_add(*size, Ordering::Release);
|
||||
}
|
||||
let path = match item.entry.clone() {
|
||||
Entry::File {
|
||||
path,
|
||||
sha256sum: _,
|
||||
mode: _,
|
||||
size,
|
||||
} = &item.entry
|
||||
{
|
||||
totalsize.fetch_add(*size, Ordering::Release);
|
||||
size: _,
|
||||
}
|
||||
let path = match item.entry.clone() {
|
||||
Entry::File {
|
||||
path,
|
||||
sha256sum: _,
|
||||
mode: _,
|
||||
size: _,
|
||||
}
|
||||
| Entry::Link { path, target: _ }
|
||||
| Entry::Directory { path, mode: _ } => path,
|
||||
};
|
||||
plist.lock().unwrap().borrow_mut().entries.push(item.entry);
|
||||
match writer.lock().unwrap().borrow_mut().write_all(&item.data) {
|
||||
Ok(_) => sender
|
||||
.send(Message::MemberAdded(format!("{}", path.display())))
|
||||
.expect("couldn't send message"),
|
||||
Err(e) => sender
|
||||
.send(Message::Failure(format!("{e}")))
|
||||
.expect("couldn't send message"),
|
||||
}
|
||||
} else {
|
||||
sender
|
||||
.send(Message::Failure(format!(
|
||||
"Could not process DirEntry for {}",
|
||||
x.display()
|
||||
)))
|
||||
.expect("could not send message");
|
||||
}
|
||||
});
|
||||
| Entry::Link { path, target: _ }
|
||||
| Entry::Directory { path, mode: _ } => path,
|
||||
};
|
||||
plist.lock().unwrap().borrow_mut().entries.push(item.entry);
|
||||
writer.lock().unwrap().borrow_mut().write_all(&item.data)?;
|
||||
s.send(Message::MemberAdded(format!("{}", path.display())))
|
||||
.expect("couldn't send message");
|
||||
Ok::<(), CreationError>(())
|
||||
})?;
|
||||
let mut package: Package = self.specs.into();
|
||||
package.size = totalsize.into_inner();
|
||||
let plist = plist.into_inner()?;
|
||||
@ -143,9 +133,50 @@ impl Creator {
|
||||
let mut writer = writer.into_inner()?;
|
||||
writer.write_all(&node.to_vec()?)?;
|
||||
let _fd = writer.finish()?;
|
||||
let sender = sender.into_inner()?;
|
||||
sender.send(Message::Success(format!("{} saved", archive.display())))?;
|
||||
env::set_current_dir(d)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CreationError {
|
||||
Io(io::Error),
|
||||
Fmt(fmt::Error),
|
||||
Tar(tar::Error),
|
||||
Deku(DekuError),
|
||||
}
|
||||
|
||||
impl fmt::Display for CreationError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for CreationError {
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
match self {
|
||||
Self::Io(e) => Some(e),
|
||||
Self::Fmt(e) => Some(e),
|
||||
Self::Tar(e) => Some(e),
|
||||
Self::Deku(e) => Some(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for CreationError {
|
||||
fn from(value: io::Error) -> Self {
|
||||
Self::Io(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ItemError> for CreationError {
|
||||
fn from(value: ItemError) -> Self {
|
||||
match value {
|
||||
ItemError::Io(e) => Self::Io(e),
|
||||
ItemError::Fmt(e) => Self::Fmt(e),
|
||||
ItemError::Tar(e) => Self::Tar(e),
|
||||
ItemError::Deku(e) => Self::Deku(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ mod cli;
|
||||
use {
|
||||
clap::ArgMatches,
|
||||
cli::cli,
|
||||
hpk::{Creator, Dependency, Message, Specs, Version},
|
||||
hpk::{CreationError, Creator, Dependency, Message, Specs, Version},
|
||||
indicatif::{ProgressBar, ProgressStyle},
|
||||
ron::ser::{to_writer_pretty, PrettyConfig},
|
||||
std::{
|
||||
@ -93,13 +93,9 @@ fn create(matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
|
||||
pb.inc(1);
|
||||
pb.finish_and_clear();
|
||||
}
|
||||
Message::Failure(s) => {
|
||||
eprint!("{s}");
|
||||
return Err(io::Error::new(io::ErrorKind::Other, s));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
Ok::<(), CreationError>(())
|
||||
});
|
||||
creator.create(&outdir, sender)?;
|
||||
match handle.join() {
|
||||
|
@ -175,7 +175,11 @@ impl<T: io::Read> Installer<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_entry(entry: &Entry, node: &Node, path: PathBuf) -> Result<InstallMessage, InstallError> {
|
||||
fn extract_entry(
|
||||
entry: &Entry,
|
||||
node: &Node,
|
||||
path: PathBuf,
|
||||
) -> Result<InstallMessage, InstallError> {
|
||||
match entry {
|
||||
Entry::Directory { path: _, mode } => {
|
||||
DirBuilder::new().mode(*mode).create(&path)?;
|
||||
|
@ -1,14 +1,15 @@
|
||||
use hpk_package::{
|
||||
deku::DekuError,
|
||||
sha2::{Digest, Sha256},
|
||||
tar::{Node, Owner},
|
||||
tar::{Error as TarError, Node, Owner},
|
||||
Entry,
|
||||
};
|
||||
use std::{
|
||||
error::Error,
|
||||
ffi::OsStr,
|
||||
fmt::Write,
|
||||
fmt::{self, Write},
|
||||
fs,
|
||||
io::Read,
|
||||
io::{self, Read},
|
||||
os::unix::fs::MetadataExt,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
@ -21,7 +22,7 @@ pub struct Item {
|
||||
}
|
||||
|
||||
impl Item {
|
||||
pub fn try_create(path: &Path) -> Result<Self, Box<dyn Error>> {
|
||||
pub fn try_create(path: &Path) -> Result<Self, ItemError> {
|
||||
let path = fix_path(path);
|
||||
let meta = fs::metadata(&path)?;
|
||||
let filename = format!("{}", path.display());
|
||||
@ -68,6 +69,55 @@ impl Item {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ItemError {
|
||||
Io(io::Error),
|
||||
Fmt(fmt::Error),
|
||||
Tar(TarError),
|
||||
Deku(DekuError),
|
||||
}
|
||||
|
||||
impl fmt::Display for ItemError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for ItemError {
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
match self {
|
||||
Self::Io(e) => Some(e),
|
||||
Self::Fmt(e) => Some(e),
|
||||
Self::Tar(e) => Some(e),
|
||||
Self::Deku(e) => Some(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for ItemError {
|
||||
fn from(value: io::Error) -> Self {
|
||||
Self::Io(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<fmt::Error> for ItemError {
|
||||
fn from(value: fmt::Error) -> Self {
|
||||
Self::Fmt(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TarError> for ItemError {
|
||||
fn from(value: TarError) -> Self {
|
||||
Self::Tar(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DekuError> for ItemError {
|
||||
fn from(value: DekuError) -> Self {
|
||||
Self::Deku(value)
|
||||
}
|
||||
}
|
||||
|
||||
fn fix_path(path: &Path) -> PathBuf {
|
||||
let path = if let Ok(p) = path.strip_prefix("./") {
|
||||
p
|
||||
|
@ -9,12 +9,12 @@ mod repository;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub use {
|
||||
creator::{Creator, Message},
|
||||
creator::{CreationError, Creator, Message},
|
||||
db::Database,
|
||||
hooks::{Hooks, Pinstall},
|
||||
hpk_package::{tar, Arch, Dependency, GitRev, Package, Plist, Rapid, SemVer, Specs, Version},
|
||||
installer::{InstallError, InstallMessage, Installer},
|
||||
item::Item,
|
||||
item::{Item, ItemError},
|
||||
repository::Repository,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user