fix: binary install is now working
This commit is contained in:
parent
d436a49c8f
commit
d6cfab4eb7
6 changed files with 96 additions and 43 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
|
dist/
|
||||||
**/target
|
**/target
|
||||||
**/Cargo.lock
|
**/Cargo.lock
|
||||||
*.pkg
|
*.pkg
|
|
@ -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(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
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);
|
error!("Could not show files: {}", e);
|
||||||
}
|
}
|
||||||
if prompt_bool("Continue?", false) {
|
|
||||||
self.apply_overlay();
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
self.apply_overlay();
|
if !prompt_bool("Continue?", is_noninteractive()) {
|
||||||
|
return Err(BinError::Cancelled);
|
||||||
|
}
|
||||||
|
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")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
40
pkgr/src/util/fs.rs
Normal 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(())
|
||||||
|
}
|
|
@ -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(())
|
|
||||||
}
|
|
Loading…
Reference in a new issue