Revised error handling and some cleanup
- `fatal()` function for handling the termination of the program when a fatal human-readable error digestable error occurs. This function terminates the program and will never return a value. - Much like the aforementioned function, the `error()` function now prints the error and terminates the program, instead of printing the error and returning the error code as an i32 integer. - ErrorType enum implemented as an encapsulate to delineate error type. - Display trait implemented for ErrorType enum for use cases whereby the program being terminated is inconvenient for the given code path. - `generic()` function added to GenericError trait for handling errors of which do not require a message to be prepended. - Global configuration is now statically cached with OnceLock instead of lazy_static, and is loaded on-demand instead of during the invocation of the `init()` function from the init module upon program startup. - Use of lazy_static was also eliminated in pacwrap-core's sync module.
This commit is contained in:
parent
ed5b112538
commit
d1622eb0b4
22 changed files with 161 additions and 110 deletions
|
@ -99,7 +99,7 @@ fn conduct_transaction(config: &Global, handle: &mut TransactionHandle, agent: T
|
|||
err!(SyncError::InitializationFailure(error.to_string()))?
|
||||
}
|
||||
|
||||
handle.ignore(&mut None);
|
||||
handle.ignore(&mut None)?;
|
||||
|
||||
if let TransactionType::Upgrade(upgrade, downgrade, _) = action {
|
||||
if upgrade {
|
||||
|
|
|
@ -37,6 +37,6 @@ fn main() {
|
|||
};
|
||||
|
||||
if let Err(error) = result {
|
||||
error.handle();
|
||||
error.error();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ pub use self::{
|
|||
container::{Container, ContainerHandle, ContainerType},
|
||||
dbus::Dbus,
|
||||
filesystem::{BindError, Filesystem},
|
||||
global::{Global, CONFIG},
|
||||
global::{global, Global},
|
||||
permission::{PermError, Permission},
|
||||
vars::ContainerVariables,
|
||||
};
|
||||
|
@ -149,7 +149,7 @@ fn handle<'a>(vars: ContainerVariables) -> Result<ContainerHandle<'a>> {
|
|||
}
|
||||
}
|
||||
|
||||
fn config() -> Result<Global> {
|
||||
fn load_config() -> Result<Global> {
|
||||
match serde_yaml::from_reader(File::open(*CONFIG_FILE).prepend_io(|| CONFIG_FILE.to_string())?) {
|
||||
Ok(file) => Ok(file),
|
||||
Err(error) => err!(ConfigError::Load(CONFIG_FILE.to_string(), error.to_string()))?,
|
||||
|
|
|
@ -17,21 +17,18 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::process::exit;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
config::{config, save},
|
||||
config::{load_config, save},
|
||||
constants::CONFIG_FILE,
|
||||
sync::event::summary::SummaryKind,
|
||||
Result,
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
pub static ref CONFIG: Global = Global::load();
|
||||
}
|
||||
static CONFIG: OnceLock<Global> = OnceLock::new();
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub enum Verbosity {
|
||||
|
@ -188,13 +185,6 @@ impl Default for Global {
|
|||
}
|
||||
|
||||
impl Global {
|
||||
fn load() -> Self {
|
||||
match config() {
|
||||
Ok(config) => config,
|
||||
Err(error) => exit(error.error()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
config: Configuration::new(),
|
||||
|
@ -215,6 +205,20 @@ impl Global {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn global() -> Result<&'static Global> {
|
||||
Ok(match CONFIG.get() {
|
||||
Some(f) => f,
|
||||
None => {
|
||||
let cfg = match load_config() {
|
||||
Ok(config) => Ok(config),
|
||||
Err(error) => error.fatal(),
|
||||
}?;
|
||||
|
||||
CONFIG.get_or_init(|| cfg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn ignore_pkg() -> Vec<String> {
|
||||
vec!["".into()]
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
use std::{fs::File, io::Write, path::Path};
|
||||
|
||||
use crate::{
|
||||
config::global::CONFIG,
|
||||
constants::{CACHE_DIR, CONFIG_DIR, DATA_DIR},
|
||||
err,
|
||||
Error,
|
||||
|
@ -97,9 +96,5 @@ pub fn init() -> Result<()> {
|
|||
data_layout().instantiate()?;
|
||||
cache_layout().instantiate()?;
|
||||
initialize_file(&format!("{}/repositories.conf", *CONFIG_DIR), REPO_CONF_DEFAULT)?;
|
||||
initialize_file(&format!("{}/pacwrap.yml", *CONFIG_DIR), PACWRAP_CONF_DEFAULT)?;
|
||||
|
||||
let _ = *CONFIG;
|
||||
|
||||
Ok(())
|
||||
initialize_file(&format!("{}/pacwrap.yml", *CONFIG_DIR), PACWRAP_CONF_DEFAULT)
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ use crate::{
|
|||
exec::args::ExecutionArgs,
|
||||
Error,
|
||||
ErrorGeneric,
|
||||
ErrorType,
|
||||
};
|
||||
|
||||
static GPU_DEV: OnceLock<Vec<String>> = OnceLock::new();
|
||||
|
@ -42,8 +43,8 @@ struct Graphics;
|
|||
#[typetag::serde(name = "gpu")]
|
||||
impl Permission for Graphics {
|
||||
fn check(&self) -> Result<Option<Condition>, PermError> {
|
||||
let gpu_dev = populate_dev().map_err(|f| {
|
||||
f.error();
|
||||
let gpu_dev = populate_dev().map_err(|error| {
|
||||
eprintln!("{}", ErrorType::Error(&error));
|
||||
Fail("No graphics devices are available.".into())
|
||||
})?;
|
||||
let nvidia = !gpu_dev.iter().filter(|a| a.contains("nvidia")).collect::<Vec<_>>().is_empty();
|
||||
|
|
|
@ -17,11 +17,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::{
|
||||
env::var,
|
||||
process::{exit, id},
|
||||
time::Duration,
|
||||
};
|
||||
use std::{env::var, process::id, time::Duration};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use nix::unistd::{getegid, geteuid};
|
||||
|
@ -109,7 +105,7 @@ lazy_static! {
|
|||
}
|
||||
|
||||
fn env(env: &'static str) -> &'static str {
|
||||
var(env).map_or_else(|_| exit(error!(ErrorKind::EnvVarUnset(env)).error()), |var| var.leak())
|
||||
var(env).map_or_else(|_| error!(ErrorKind::EnvVarUnset(env)).fatal(), |var| var.leak())
|
||||
}
|
||||
|
||||
fn env_opt(env: &str) -> &'static str {
|
||||
|
|
|
@ -62,12 +62,20 @@ pub trait Downcast {
|
|||
}
|
||||
|
||||
pub trait ErrorGeneric<R, E> {
|
||||
fn prepend<F>(self, f: F) -> StdResult<R, Error>
|
||||
fn prepend<F>(self, f: F) -> Result<R>
|
||||
where
|
||||
F: FnOnce() -> String;
|
||||
fn prepend_io<F>(self, f: F) -> StdResult<R, Error>
|
||||
fn prepend_io<F>(self, f: F) -> Result<R>
|
||||
where
|
||||
F: FnOnce() -> String;
|
||||
fn generic(self) -> Result<R>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ErrorType<'a> {
|
||||
Error(&'a Error),
|
||||
Warn(&'a Error),
|
||||
Fatal(&'a Error),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -86,18 +94,18 @@ impl Error {
|
|||
Self { kind: err }
|
||||
}
|
||||
|
||||
pub fn handle(&self) {
|
||||
eprintln!("{}error:{} {}", *BOLD_RED, *RESET, self.kind);
|
||||
exit(self.kind.code());
|
||||
pub fn fatal(&self) -> ! {
|
||||
eprintln!("{}", ErrorType::Fatal(self));
|
||||
exit(self.kind.code())
|
||||
}
|
||||
|
||||
pub fn error(&self) -> i32 {
|
||||
eprintln!("{}error:{} {}", *BOLD_RED, *RESET, self.kind);
|
||||
self.kind.code()
|
||||
pub fn error(&self) -> ! {
|
||||
eprintln!("{}", ErrorType::Error(self));
|
||||
exit(self.kind.code())
|
||||
}
|
||||
|
||||
pub fn warn(&self) {
|
||||
eprintln!("{}warning:{} {}", *BOLD_YELLOW, *RESET, self.kind);
|
||||
eprintln!("{}", ErrorType::Warn(self))
|
||||
}
|
||||
|
||||
#[allow(clippy::borrowed_box)]
|
||||
|
@ -113,13 +121,21 @@ impl Error {
|
|||
}
|
||||
}
|
||||
|
||||
impl_error!(GenericError);
|
||||
impl Display for ErrorType<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
match self {
|
||||
Self::Fatal(e) => write!(f, "{}fatal:{} {}", *BOLD_RED, *RESET, e.kind),
|
||||
Self::Error(e) => write!(f, "{}error:{} {}", *BOLD_RED, *RESET, e.kind),
|
||||
Self::Warn(e) => write!(f, "{}warning:{} {}", *BOLD_YELLOW, *RESET, e.kind),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R, E> ErrorGeneric<R, E> for StdResult<R, E>
|
||||
where
|
||||
E: Display,
|
||||
{
|
||||
fn prepend<F>(self, f: F) -> StdResult<R, Error>
|
||||
fn prepend<F>(self, f: F) -> Result<R>
|
||||
where
|
||||
F: FnOnce() -> String, {
|
||||
match self {
|
||||
|
@ -131,7 +147,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn prepend_io<F>(self, f: F) -> StdResult<R, Error>
|
||||
fn prepend_io<F>(self, f: F) -> Result<R>
|
||||
where
|
||||
F: FnOnce() -> String, {
|
||||
match self {
|
||||
|
@ -142,6 +158,16 @@ where
|
|||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn generic(self) -> Result<R> {
|
||||
match self {
|
||||
Ok(f) => Ok(f),
|
||||
Err(err) => err!(GenericError {
|
||||
prepend: "An error has occurred".into(),
|
||||
error: err.to_string(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for GenericError {
|
||||
|
@ -150,6 +176,8 @@ impl Display for GenericError {
|
|||
}
|
||||
}
|
||||
|
||||
impl_error!(GenericError);
|
||||
|
||||
impl<T> Downcast for T
|
||||
where
|
||||
T: ErrorTrait + 'static,
|
||||
|
|
|
@ -31,15 +31,15 @@ use serde::Serialize;
|
|||
use serde_yaml::Value;
|
||||
|
||||
use crate::{
|
||||
config::CONFIG,
|
||||
config::global,
|
||||
constants::BWRAP_EXECUTABLE,
|
||||
err,
|
||||
error::*,
|
||||
exec::{ExecutionError, ExecutionType},
|
||||
sync::{
|
||||
alpm_config,
|
||||
transaction::{TransactionMetadata, TransactionParameters},
|
||||
SyncError,
|
||||
DEFAULT_ALPM_CONF,
|
||||
},
|
||||
utils::TermControl,
|
||||
ErrorKind,
|
||||
|
@ -155,8 +155,8 @@ pub fn agent_params(
|
|||
metadata: &TransactionMetadata,
|
||||
) -> Result<i32> {
|
||||
serialize(params, writer)?;
|
||||
serialize(&*CONFIG, writer)?;
|
||||
serialize(&*DEFAULT_ALPM_CONF, writer)?;
|
||||
serialize(global()?, writer)?;
|
||||
serialize(alpm_config()?, writer)?;
|
||||
serialize(metadata, writer)?;
|
||||
Ok(reader.as_raw_fd())
|
||||
}
|
||||
|
|
|
@ -21,20 +21,18 @@ use std::{
|
|||
fs::{create_dir, create_dir_all},
|
||||
os::unix::fs::symlink,
|
||||
path::Path,
|
||||
process::exit,
|
||||
sync::OnceLock,
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
use alpm::{Alpm, LogLevel, SigLevel, Usage};
|
||||
use lazy_static::lazy_static;
|
||||
use pacmanconf::{self, Config, Repository};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
config::{global::ProgressKind, ContainerHandle, ContainerType::*, ContainerVariables, Global, CONFIG},
|
||||
config::{global, global::ProgressKind, ContainerHandle, ContainerType::*, ContainerVariables, Global},
|
||||
constants::{ARROW_RED, BAR_GREEN, BOLD, CACHE_DIR, CONFIG_DIR, DATA_DIR, RESET, UNIX_TIMESTAMP, VERBOSE},
|
||||
err,
|
||||
error,
|
||||
exec::pacwrap_key,
|
||||
impl_error,
|
||||
sync::{
|
||||
|
@ -57,11 +55,8 @@ pub mod utils;
|
|||
mod resolver;
|
||||
mod resolver_local;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref DEFAULT_ALPM_CONF: AlpmConfigData = AlpmConfigData::new();
|
||||
static ref PACMAN_CONF: pacmanconf::Config = load_repositories();
|
||||
static ref DEFAULT_SIGLEVEL: SigLevel = default_signature();
|
||||
}
|
||||
static PACMAN_CONFIG: OnceLock<pacmanconf::Config> = OnceLock::new();
|
||||
static ALPM_CONFIG_DATA: OnceLock<AlpmConfigData> = OnceLock::new();
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub enum SyncError {
|
||||
|
@ -145,7 +140,7 @@ impl From<&Repository> for AlpmRepository {
|
|||
Self {
|
||||
name: repo.name.clone(),
|
||||
mirrors: repo.servers.clone(),
|
||||
sig_lvl: signature(&repo.sig_level, *DEFAULT_SIGLEVEL).bits(),
|
||||
sig_lvl: signature(&repo.sig_level, default_signature()).bits(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -170,23 +165,33 @@ pub struct AlpmConfigData {
|
|||
}
|
||||
|
||||
impl AlpmConfigData {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
repos: PACMAN_CONF.repos.iter().map(|a| a.into()).collect(),
|
||||
}
|
||||
fn new() -> Result<Self> {
|
||||
Ok(Self {
|
||||
repos: pacman_conf()?.repos.iter().map(|a| a.into()).collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn alpm_log_callback(level: LogLevel, msg: &str, counter: &mut usize) {
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
|
||||
let time = now.as_secs() as usize - *counter;
|
||||
let nano = now.subsec_nanos().to_string();
|
||||
let log_level = level.bits() / 4;
|
||||
let verbosity = if *VERBOSE { 3 } else { 2 };
|
||||
pub fn alpm_config() -> Result<&'static AlpmConfigData> {
|
||||
Ok(match ALPM_CONFIG_DATA.get() {
|
||||
Some(data) => data,
|
||||
None => {
|
||||
let data = AlpmConfigData::new()?;
|
||||
|
||||
if log_level < verbosity {
|
||||
eprint!("[{}.{:.6}] [ALPM] {}", time, nano, msg);
|
||||
}
|
||||
ALPM_CONFIG_DATA.get_or_init(|| data)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn pacman_conf() -> Result<&'static Config> {
|
||||
Ok(match PACMAN_CONFIG.get() {
|
||||
Some(c) => c,
|
||||
None => {
|
||||
let cfg = load_pacman_conf()?;
|
||||
|
||||
PACMAN_CONFIG.get_or_init(|| cfg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn instantiate_alpm_agent(config: &Global, remotes: &AlpmConfigData, transflags: &TransactionFlags) -> Alpm {
|
||||
|
@ -215,14 +220,20 @@ pub fn instantiate_alpm_agent(config: &Global, remotes: &AlpmConfigData, transfl
|
|||
handle
|
||||
}
|
||||
|
||||
pub fn instantiate_alpm(inshandle: &ContainerHandle, transflags: &TransactionFlags) -> Alpm {
|
||||
alpm_handle(inshandle.vars(), &DEFAULT_ALPM_CONF, transflags, format!("{}/var/lib/pacman/", inshandle.vars().root()))
|
||||
pub fn instantiate_alpm(inshandle: &ContainerHandle, transflags: &TransactionFlags) -> Result<Alpm> {
|
||||
alpm_handle(inshandle.vars(), alpm_config()?, transflags, format!("{}/var/lib/pacman/", inshandle.vars().root()))
|
||||
}
|
||||
|
||||
fn alpm_handle(insvars: &ContainerVariables, remotes: &AlpmConfigData, transflags: &TransactionFlags, db_path: String) -> Alpm {
|
||||
fn alpm_handle(
|
||||
insvars: &ContainerVariables,
|
||||
remotes: &AlpmConfigData,
|
||||
transflags: &TransactionFlags,
|
||||
db_path: String,
|
||||
) -> Result<Alpm> {
|
||||
let config = global()?;
|
||||
let mut handle = Alpm::new(insvars.root(), &db_path).expect("Unable to acquire ALPM handle");
|
||||
let debug = transflags.intersects(TransactionFlags::DEBUG);
|
||||
let disable_sandbox = CONFIG.alpm().disable_sandbox() || transflags.intersects(TransactionFlags::NO_ALPM_SANDBOX);
|
||||
let disable_sandbox = config.alpm().disable_sandbox() || transflags.intersects(TransactionFlags::NO_ALPM_SANDBOX);
|
||||
|
||||
if debug {
|
||||
handle.set_log_cb(*UNIX_TIMESTAMP as usize, alpm_log_callback);
|
||||
|
@ -236,11 +247,23 @@ fn alpm_handle(insvars: &ContainerVariables, remotes: &AlpmConfigData, transflag
|
|||
handle.set_logfile(format!("{}/pacwrap.log", *DATA_DIR)).expect("set logfile");
|
||||
handle.set_gpgdir(format!("{}/pacman/gnupg", *DATA_DIR)).expect("set gpgdir");
|
||||
handle.set_cachedirs([format!("{}/pkg", *CACHE_DIR)].iter()).expect("set cachedirs");
|
||||
handle.set_parallel_downloads(CONFIG.alpm().parallel_downloads());
|
||||
handle.set_disable_dl_timeout(CONFIG.alpm().download_timeout());
|
||||
handle.set_check_space(CONFIG.alpm().check_space());
|
||||
handle.set_parallel_downloads(config.alpm().parallel_downloads());
|
||||
handle.set_disable_dl_timeout(config.alpm().download_timeout());
|
||||
handle.set_check_space(global()?.alpm().check_space());
|
||||
handle = register_remote(handle, remotes);
|
||||
handle
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
fn alpm_log_callback(level: LogLevel, msg: &str, counter: &mut usize) {
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
|
||||
let time = now.as_secs() as usize - *counter;
|
||||
let nano = now.subsec_nanos().to_string();
|
||||
let log_level = level.bits() / 4;
|
||||
let verbosity = if *VERBOSE { 3 } else { 2 };
|
||||
|
||||
if log_level < verbosity {
|
||||
eprint!("[{}.{:.6}] [ALPM] {}", time, nano, msg);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn instantiate_container<'a>(handle: &'a ContainerHandle<'a>) -> Result<()> {
|
||||
|
@ -312,7 +335,7 @@ fn synchronize_database(ag: &mut TransactionAggregator, force: bool) -> Result<(
|
|||
};
|
||||
let flags = ag.flags();
|
||||
let db_path = format!("{}/pacman/", *DATA_DIR);
|
||||
let mut handle = alpm_handle(handle.vars(), &DEFAULT_ALPM_CONF, flags, db_path);
|
||||
let mut handle = alpm_handle(handle.vars(), alpm_config()?, flags, db_path)?;
|
||||
|
||||
ag.lock()?.assert()?;
|
||||
println!("{} {}Synchronizing package databases...{}", *BAR_GREEN, *BOLD, *RESET);
|
||||
|
@ -326,7 +349,7 @@ fn synchronize_database(ag: &mut TransactionAggregator, force: bool) -> Result<(
|
|||
ag.lock()?.assert()?;
|
||||
|
||||
for handle in ag.cache().filter_handle(vec![Base, Slice, Aggregate]).iter() {
|
||||
for repo in PACMAN_CONF.repos.iter() {
|
||||
for repo in pacman_conf()?.repos.iter() {
|
||||
let src = &format!("{}/pacman/sync/{}.db", *DATA_DIR, repo.name);
|
||||
let dest = &format!("{}/var/lib/pacman/sync/{}.db", handle.vars().root(), repo.name);
|
||||
|
||||
|
@ -363,13 +386,13 @@ fn signature(sigs: &Vec<String>, default: SigLevel) -> SigLevel {
|
|||
}
|
||||
|
||||
fn default_signature() -> SigLevel {
|
||||
signature(&CONFIG.alpm().sig_level(), SigLevel::PACKAGE | SigLevel::DATABASE_OPTIONAL)
|
||||
signature(&global().expect("pacwrap.yml").alpm().sig_level(), SigLevel::PACKAGE | SigLevel::DATABASE_OPTIONAL)
|
||||
}
|
||||
|
||||
fn load_repositories() -> Config {
|
||||
fn load_pacman_conf() -> Result<Config> {
|
||||
let path = format!("{}/repositories.conf", *CONFIG_DIR);
|
||||
|
||||
match Config::from_file(&path) {
|
||||
Ok(match Config::from_file(&path) {
|
||||
Ok(config) => config,
|
||||
Err(error) => {
|
||||
//The following code is ugly, precisely because, the pacman_conf library does not
|
||||
|
@ -377,9 +400,8 @@ fn load_repositories() -> Config {
|
|||
|
||||
let error = error.to_string();
|
||||
let error = error.split("error: ").collect::<Vec<_>>()[1].split("\n").collect::<Vec<&str>>()[0];
|
||||
let error = error!(SyncError::RepoConfError(path, error.to_string()));
|
||||
|
||||
exit(error.error());
|
||||
err!(SyncError::RepoConfError(path, error.to_string()))?
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use self::{SyncState::*, TransactionMode::*, TransactionType::*};
|
||||
use crate::{
|
||||
config::{ContainerHandle, Global, CONFIG},
|
||||
config::{global, ContainerHandle, Global},
|
||||
constants::{ARROW_CYAN, BAR_CYAN, BOLD, BOLD_GREEN, BOLD_YELLOW, RESET},
|
||||
err,
|
||||
log::{Level, Logger},
|
||||
|
@ -326,11 +326,11 @@ impl<'a> TransactionHandle<'a> {
|
|||
.extend(self.meta.foreign_pkgs.iter().map(|p| p.to_owned().into()).collect::<Vec<_>>());
|
||||
}
|
||||
|
||||
pub fn ignore(&mut self, log: &mut Option<&mut Logger>) {
|
||||
pub fn ignore(&mut self, log: &mut Option<&mut Logger>) -> Result<()> {
|
||||
let alpm = self.alpm.as_mut().unwrap();
|
||||
let config = match self.config {
|
||||
Some(config) => config,
|
||||
None => &*CONFIG,
|
||||
None => global()?,
|
||||
};
|
||||
let local = match self.meta.mode {
|
||||
Local => &self.meta.resident_pkgs,
|
||||
|
@ -391,6 +391,8 @@ impl<'a> TransactionHandle<'a> {
|
|||
*BOLD, *RESET, *BOLD_YELLOW, *RESET, *BOLD_GREEN, *RESET
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn prepare(&mut self, trans_type: &TransactionType, flags: &TransactionFlags) -> Result<()> {
|
||||
|
@ -402,7 +404,7 @@ impl<'a> TransactionHandle<'a> {
|
|||
let queue = self.meta.queue.iter().map(|i| i.as_ref()).collect::<Vec<_>>();
|
||||
let config = match self.config {
|
||||
Some(config) => config,
|
||||
None => &*CONFIG,
|
||||
None => global()?,
|
||||
};
|
||||
|
||||
if let Local = self.meta.mode {
|
||||
|
|
|
@ -17,10 +17,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
process::exit,
|
||||
};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use alpm::Alpm;
|
||||
use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle};
|
||||
|
@ -245,7 +242,7 @@ impl<'a> TransactionAggregator<'a> {
|
|||
None => Vec::new(),
|
||||
};
|
||||
|
||||
let alpm = sync::instantiate_alpm(inshandle, self.flags());
|
||||
let alpm = sync::instantiate_alpm(inshandle, self.flags())?;
|
||||
let mut meta = TransactionMetadata::new(queue);
|
||||
let mut handle = TransactionHandle::new(&mut meta).alpm_handle(alpm);
|
||||
let mut act: Box<dyn Transaction> = Prepare.from(self);
|
||||
|
@ -292,7 +289,7 @@ impl<'a> TransactionAggregator<'a> {
|
|||
return match err.downcast::<SyncError>().map_err(|err| error!(SyncError::from(err)))? {
|
||||
SyncError::TransactionAgentFailure => {
|
||||
self.logger().log(Level::Fatal, &format!("Transaction error: {:?}", err))?;
|
||||
exit(err.kind().code())
|
||||
err.fatal()
|
||||
}
|
||||
_ => {
|
||||
self.logger().log(Level::Error, &format!("Transaction error: {:?}", err))?;
|
||||
|
|
|
@ -20,7 +20,10 @@
|
|||
use std::{os::unix::process::ExitStatusExt, process::Child, result::Result as StdResult};
|
||||
|
||||
use crate::{
|
||||
config::{ContainerHandle, CONFIG},
|
||||
config::{
|
||||
global::{global, Global},
|
||||
ContainerHandle,
|
||||
},
|
||||
constants::{BOLD, RESET},
|
||||
err,
|
||||
exec::transaction_agent,
|
||||
|
@ -84,7 +87,7 @@ impl Transaction for Commit {
|
|||
erroneous_preparation(error)?
|
||||
}
|
||||
|
||||
let result = confirm(&self.state, ag, handle);
|
||||
let result = confirm(&self.state, ag, handle, global()?);
|
||||
let result = match result {
|
||||
Err(result) => return result,
|
||||
Ok(result) => result,
|
||||
|
@ -102,7 +105,7 @@ impl Transaction for Commit {
|
|||
ag.keyring_update(inshandle)?;
|
||||
}
|
||||
|
||||
handle.set_alpm(Some(sync::instantiate_alpm(inshandle, ag.flags())));
|
||||
handle.set_alpm(Some(sync::instantiate_alpm(inshandle, ag.flags())?));
|
||||
handle.apply_configuration(inshandle, ag.flags().intersects(TransactionFlags::CREATE))?;
|
||||
ag.logger().log(Info, &format!("container {instance}'s {state} transaction complete"))?;
|
||||
next_state(handle, ag.action(), &self.state, true)
|
||||
|
@ -117,6 +120,7 @@ fn confirm(
|
|||
state: &TransactionState,
|
||||
ag: &TransactionAggregator,
|
||||
handle: &mut TransactionHandle,
|
||||
global: &'static Global,
|
||||
) -> StdResult<(u64, u64), Result<TransactionState>> {
|
||||
let database = ag.flags().intersects(TransactionFlags::DATABASE_ONLY | TransactionFlags::FORCE_DATABASE);
|
||||
let foreign = !handle.get_mode().bool();
|
||||
|
@ -126,7 +130,7 @@ fn confirm(
|
|||
};
|
||||
let confirm = foreign || database && !create;
|
||||
let sum = Summary::new()
|
||||
.kind(CONFIG.config().summary(), confirm)
|
||||
.kind(global.config().summary(), confirm)
|
||||
.mode(handle.get_mode())
|
||||
.generate(handle.alpm());
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ impl Transaction for Prepare {
|
|||
if !deps.is_empty() {
|
||||
for dep in deps.iter().rev() {
|
||||
match ag.cache().get_instance_option(dep) {
|
||||
Some(dep_handle) => handle.enumerate_package_lists(&sync::instantiate_alpm(dep_handle, ag.flags())),
|
||||
Some(dep_handle) => handle.enumerate_package_lists(&sync::instantiate_alpm(dep_handle, ag.flags())?),
|
||||
None => err!(SyncError::DependentContainerMissing(dep.to_string()))?,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ impl Transaction for Stage {
|
|||
|
||||
ag.action().action_message(self.mode);
|
||||
handle.set_mode(self.mode);
|
||||
handle.ignore(&mut ag.flags().contains(TransactionFlags::DEBUG).then_some(ag.logger()));
|
||||
handle.ignore(&mut ag.flags().contains(TransactionFlags::DEBUG).then_some(ag.logger()))?;
|
||||
handle.meta.set_flags(ag.flags(), &self.flags);
|
||||
|
||||
match ag.action() {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::{process::exit, thread::Builder};
|
||||
use std::thread::Builder;
|
||||
|
||||
use alpm::{
|
||||
Alpm,
|
||||
|
@ -197,7 +197,7 @@ pub fn signal_trap() {
|
|||
println!();
|
||||
|
||||
if count == 3 {
|
||||
exit(error!(SyncError::SignalInterrupt).error());
|
||||
error!(SyncError::SignalInterrupt).error()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -39,6 +39,7 @@ use pacwrap_core::{
|
|||
Error,
|
||||
ErrorGeneric,
|
||||
ErrorKind,
|
||||
ErrorType,
|
||||
Result,
|
||||
};
|
||||
|
||||
|
@ -52,7 +53,7 @@ pub fn compose(args: &mut Arguments) -> Result<()> {
|
|||
let result = engage_aggregator(args, &lock);
|
||||
|
||||
if let Err(error) = lock.unlock() {
|
||||
error.error();
|
||||
eprintln!("{}", ErrorType::Error(&error));
|
||||
}
|
||||
|
||||
result
|
||||
|
|
|
@ -47,6 +47,6 @@ fn main() {
|
|||
};
|
||||
|
||||
if let Err(error) = result {
|
||||
error.handle();
|
||||
error.error();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ pub fn query(arguments: &mut Arguments) -> Result<()> {
|
|||
}
|
||||
|
||||
let handle = config::provide_handle(target)?;
|
||||
let handle = instantiate_alpm(&handle, &flags);
|
||||
let handle = instantiate_alpm(&handle, &flags)?;
|
||||
|
||||
for pkg in handle.localdb().pkgs() {
|
||||
if explicit && pkg.reason() != PackageReason::Explicit {
|
||||
|
|
|
@ -49,7 +49,7 @@ pub fn remove(args: &mut Arguments) -> Result<()> {
|
|||
let result = engage_aggregator(action, args, &mut logger, &lock);
|
||||
|
||||
if let Err(error) = lock.unlock() {
|
||||
error.error();
|
||||
eprintln!("{}", ErrorType::Error(&error));
|
||||
}
|
||||
|
||||
result
|
||||
|
|
|
@ -51,7 +51,7 @@ pub fn synchronize(args: &mut Arguments) -> Result<()> {
|
|||
let result = engage_aggregator(&mut cache, &mut logger, args, &lock, action, create);
|
||||
|
||||
if let Err(error) = lock.unlock() {
|
||||
error.error();
|
||||
eprintln!("{}", ErrorType::Error(&error));
|
||||
}
|
||||
|
||||
result
|
||||
|
|
|
@ -36,6 +36,7 @@ use pacwrap_core::{
|
|||
ErrorGeneric,
|
||||
ErrorKind,
|
||||
ErrorTrait,
|
||||
ErrorType,
|
||||
Result,
|
||||
};
|
||||
|
||||
|
@ -93,7 +94,7 @@ pub fn remove_containers(args: &mut Arguments) -> Result<()> {
|
|||
|
||||
if let (true, _) | (_, true) = (no_confirm, prompt_targets(&instances, "Delete containers?", false)) {
|
||||
if let Err(err) = delete_roots(&cache, &lock, &mut logger, &instances, force) {
|
||||
err.error();
|
||||
eprintln!("{}", ErrorType::Error(&err));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue