fix: binary install is now working

This commit is contained in:
Strix 2023-10-14 22:39:49 +02:00
parent d436a49c8f
commit d6cfab4eb7
No known key found for this signature in database
GPG key ID: 49B2E37B8915B774
6 changed files with 96 additions and 43 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
dist/
**/target **/target
**/Cargo.lock **/Cargo.lock
*.pkg *.pkg

View file

@ -1,21 +1,26 @@
use std::fmt::Display; use std::fmt::Display;
use std::io;
#[derive(Debug)] #[derive(Debug)]
pub enum BinError { pub enum BinError {
UnpackError(String), UnpackError(String),
IOError(io::Error),
Cancelled,
} }
impl Display for BinError { impl Display for BinError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
BinError::UnpackError(e) => write!(f, "Unpack error: {}", e), BinError::UnpackError(e) => write!(f, "Unpack error: {}", e),
BinError::IOError(e) => write!(f, "IO error: {}", e),
BinError::Cancelled => write!(f, "Cancelled by user"),
} }
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub enum BuildError { pub enum BuildError {
InvalidManifest, InvalidManifest(String),
} }
impl Display for BuildError { impl Display for BuildError {
@ -30,8 +35,7 @@ impl Display for BuildError {
pub enum InstallError { pub enum InstallError {
BuildError(BuildError), BuildError(BuildError),
BinError(BinError), BinError(BinError),
InvalidManifest, InvalidManifest(String),
Generic,
} }
impl ToString for InstallError { impl ToString for InstallError {
@ -39,8 +43,7 @@ impl ToString for InstallError {
match self { match self {
InstallError::BuildError(e) => format!("{}", e), InstallError::BuildError(e) => format!("{}", e),
InstallError::BinError(e) => format!("{}", e), InstallError::BinError(e) => format!("{}", e),
InstallError::InvalidManifest => "Invalid manifest".to_string(), InstallError::InvalidManifest(s) => format!("{}", s),
InstallError::Generic => "Install error".to_string(),
} }
} }
} }

View file

@ -1,5 +1,8 @@
use std::fs::{remove_dir, remove_dir_all}; use std::fs::remove_dir_all;
use std::path::Path;
use std::process::exit; use std::process::exit;
use std::{io, thread};
use libc::SIGINT;
use log::{debug, error, info, trace}; use log::{debug, error, info, trace};
@ -12,8 +15,8 @@ use crate::package::identifier::{PackageIdentifier, PackageLocator};
use crate::package::Package; use crate::package::Package;
use crate::tmpfs::TempDir; use crate::tmpfs::TempDir;
use crate::types::fetch::TryFetch; use crate::types::fetch::TryFetch;
use crate::util::{visit_dirs}; use crate::util::fs::{copy_recursively, visit_dirs};
use crate::util::prompts::prompt_bool; use crate::util::prompts::{is_noninteractive, prompt_bool};
pub mod errors; pub mod errors;
@ -62,29 +65,47 @@ impl PackageInstaller {
tmpdir.push(&self.manifest.package.name); tmpdir.push(&self.manifest.package.name);
trace!("extracting package into: {}", tmpdir.to_string()); trace!("extracting package into: {}", tmpdir.to_string());
if let Err(e) = self.extract_to(tmpdir.to_string()) { if let Err(e) = self.extract_to(tmpdir.to_string()) {
return Err(e) return Err(e);
} }
debug!("extracted package in: {}", tmpdir.to_string()); debug!("extracted package in: {}", tmpdir.to_string());
if prompt_bool("See all files?", false) { {
if let Err(e) = visit_dirs(tmpdir.path().as_path(), &|d| info!(target: "item", "{}", d.path().to_str().unwrap())) { let mut tmpdir = tmpdir.clone();
error!("Could not show files: {}", e); tmpdir.push(&self.manifest.bin.clone().unwrap().root);
if prompt_bool("See all pending installation files?", true) {
if let Err(e) = visit_dirs(tmpdir.path().as_path(),
&|d| {
info!(target: "item", "{}", d.path()
.to_str()
.unwrap()
.replace(&tmpdir.to_string(), ""))
})
{
error!("Could not show files: {}", e);
}
} }
if prompt_bool("Continue?", false) { }
self.apply_overlay(); if !prompt_bool("Continue?", is_noninteractive()) {
} return Err(BinError::Cancelled);
} else { }
self.apply_overlay(); match self.apply_overlay() {
Ok(_) => Ok(()),
Err(e) => Err(BinError::IOError(e))
}
}
fn apply_overlay(&self) -> Result<(), io::Error> {
let mut tmpdir = TempDir::default();
tmpdir.push(&self.manifest.package.name);
tmpdir.push(&self.manifest.bin.clone().unwrap().root);
if let Err(e) = copy_recursively(&tmpdir.path(), Path::new("/")) {
return Err(e);
} }
Ok(()) Ok(())
} }
fn apply_overlay(&self) {
}
fn build(&self) -> Result<(), BuildError> { fn build(&self) -> Result<(), BuildError> {
if let None = self.manifest.build.clone() { if let None = self.manifest.build.clone() {
return Err(BuildError::InvalidManifest); return Err(BuildError::InvalidManifest(String::from("No build manifest")));
} }
let build_manifest = self.manifest.build.clone().unwrap(); let build_manifest = self.manifest.build.clone().unwrap();
// TODO: Check dependencies // TODO: Check dependencies
@ -117,7 +138,7 @@ impl PackageInstaller {
if let None = self.manifest.bin { if let None = self.manifest.bin {
self.install_type = InstallType::Build; self.install_type = InstallType::Build;
if let None = self.manifest.build { if let None = self.manifest.build {
return Err(InstallError::InvalidManifest); return Err(InstallError::InvalidManifest(String::from("no bin or build manifest")));
} }
} }
} }
@ -125,7 +146,7 @@ impl PackageInstaller {
if let None = self.manifest.build { if let None = self.manifest.build {
self.install_type = InstallType::Bin; self.install_type = InstallType::Bin;
if let None = self.manifest.bin { if let None = self.manifest.bin {
return Err(InstallError::InvalidManifest); return Err(InstallError::InvalidManifest(String::from("no build or bin manifest")));
} }
} }
} }

View file

@ -2,6 +2,7 @@ use std::path::{Path, PathBuf};
use crate::CONFIG; use crate::CONFIG;
#[derive(Clone)]
pub struct TempDir { pub struct TempDir {
path: PathBuf, path: PathBuf,
} }
@ -21,7 +22,11 @@ impl TempDir {
} }
pub fn push<S: Into<String>>(&mut self, path: S) { pub fn push<S: Into<String>>(&mut self, path: S) {
self.path.push(path.into()); let mut path_str = path.into();
if path_str.starts_with('/') {
path_str = path_str[1..].to_string();
}
self.path.push(path_str);
} }
} }

40
pkgr/src/util/fs.rs Normal file
View file

@ -0,0 +1,40 @@
use std::path::Path;
use std::fs::DirEntry;
use std::{fs, io};
use log::trace;
pub fn visit_dirs(dir: &Path, cb: &dyn Fn(&DirEntry)) -> std::io::Result<()> {
if dir.is_dir() {
for entry in std::fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
visit_dirs(&path, cb)?;
} else {
cb(&entry);
}
}
}
Ok(())
}
pub fn copy_recursively(source: &Path, target: &Path) -> io::Result<()> {
if source.is_file() {
trace!("source: {:?}, target: {:?}", source, target);
fs::copy(source, target)?;
} else if source.is_dir() {
if !target.exists() {
fs::create_dir(target)?;
}
for entry in fs::read_dir(source)? {
let entry = entry?;
let file_name = entry.file_name();
let source_path = entry.path();
let target_path = target.join(&file_name);
copy_recursively(&source_path, &target_path)?;
}
}
Ok(())
}

View file

@ -1,19 +1,2 @@
use std::fs::DirEntry;
use std::path::Path;
pub mod prompts; pub mod prompts;
pub mod fs;
pub fn visit_dirs(dir: &Path, cb: &dyn Fn(&DirEntry)) -> std::io::Result<()> {
if dir.is_dir() {
for entry in std::fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
visit_dirs(&path, cb)?;
} else {
cb(&entry);
}
}
}
Ok(())
}