Few bug fixes, minor improvements and cleanup.
- Container creation in sync module now only syncs targets as required - More robust validation for --target parameters - Targets marked for reinitialization can now accept a configuration from a file if specified. - Cleaned up process module - Prompt module no longer emboldens listed targets for confirmation
This commit is contained in:
parent
68594a28e7
commit
264e9cec1f
11 changed files with 148 additions and 128 deletions
|
@ -77,9 +77,9 @@ fn delete_containers<'a>(
|
|||
let message = format!("Deleting existing container{}?", if delete.len() > 1 { "s" } else { "" });
|
||||
|
||||
if flags.contains(TransactionFlags::NO_CONFIRM) {
|
||||
println!("{} {}{}...{}", *BAR_GREEN, *BOLD, message, *RESET);
|
||||
println!("{} {}{}...{}", *BAR_GREEN, *BOLD, &message, *RESET);
|
||||
delete_roots(cache, logger, delete, force)?;
|
||||
} else if let Ok(_) = prompt_targets(&delete, message, false) {
|
||||
} else if let Ok(_) = prompt_targets(&delete, &message, false) {
|
||||
delete_roots(cache, logger, delete, force)?;
|
||||
}
|
||||
|
||||
|
@ -153,9 +153,8 @@ fn engage_aggregator<'a>(args: &mut Arguments) -> Result<()> {
|
|||
|
||||
while let Some(arg) = args.next() {
|
||||
match arg {
|
||||
Op::Short('t') | Op::Long("target") | Op::Long("from-config") => continue,
|
||||
Op::Long("from-config") => continue,
|
||||
Op::Long("noconfirm") => flags = flags | TransactionFlags::NO_CONFIRM,
|
||||
Op::Long("force") => force = true,
|
||||
Op::Long("reinitialize-all") =>
|
||||
for instance in cache.registered() {
|
||||
if let Some(handle) = cache.get_instance_option(instance) {
|
||||
|
@ -166,32 +165,43 @@ fn engage_aggregator<'a>(args: &mut Arguments) -> Result<()> {
|
|||
compose.insert(instance, None);
|
||||
}
|
||||
},
|
||||
Op::Short('f') | Op::Long("force") => force = true,
|
||||
Op::Short('r') | Op::Long("reinitialize") => reinitialize = true,
|
||||
Op::ShortPos('t', target) | Op::LongPos("target", target) =>
|
||||
if !reinitialize {
|
||||
current_target = Some(target);
|
||||
} else {
|
||||
Op::Short('t') | Op::Long("target") => match args.next() {
|
||||
Some(arg) => match arg {
|
||||
Op::ShortPos('t', t) | Op::LongPos("target", t) => current_target = Some(t),
|
||||
_ => args.invalid_operand()?,
|
||||
},
|
||||
None => err!(TargetUnspecified)?,
|
||||
},
|
||||
Op::LongPos(_, config) | Op::ShortPos(_, config) | Op::Value(config) => {
|
||||
let target = match current_target {
|
||||
Some(target) => target,
|
||||
None => match config.char_indices().filter(|a| a.1 == '.').last() {
|
||||
Some((index, ..)) => config.split_at(index).0,
|
||||
None => config,
|
||||
},
|
||||
};
|
||||
let config = if reinitialize {
|
||||
let handle = cache.get_instance(target)?;
|
||||
|
||||
if Path::new(handle.vars().root()).exists() {
|
||||
delete.push(target);
|
||||
}
|
||||
|
||||
compose.insert(target, None);
|
||||
reinitialize = false;
|
||||
},
|
||||
Op::LongPos(_, target) | Op::ShortPos(_, target) | Op::Value(target) => {
|
||||
if !target.ends_with(".yml") {
|
||||
err!(ErrorKind::Message("Unsupported file extension."))?;
|
||||
}
|
||||
|
||||
if let Some(cur_target) = current_target {
|
||||
compose.insert(cur_target, Some(target));
|
||||
current_target = None;
|
||||
} else {
|
||||
Path::new(target).try_exists().prepend_io(|| target.into())?;
|
||||
compose.insert(target.split_at(target.len() - 4).0, Some(target));
|
||||
}
|
||||
|
||||
match current_target {
|
||||
Some(_) => Some(config),
|
||||
None => None,
|
||||
}
|
||||
} else {
|
||||
Some(config)
|
||||
};
|
||||
|
||||
compose.insert(target, config);
|
||||
current_target = None;
|
||||
reinitialize = false;
|
||||
}
|
||||
_ => args.invalid_operand()?,
|
||||
}
|
||||
|
|
|
@ -358,7 +358,7 @@ fn create_placeholder(path: &str) -> Result<()> {
|
|||
fn cleanup() -> Result<()> {
|
||||
if Path::new(&*DBUS_SOCKET).exists() {
|
||||
remove_file(&*DBUS_SOCKET).prepend_io(|| DBUS_SOCKET.to_string())?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -21,13 +21,14 @@ use std::{
|
|||
str::FromStr,
|
||||
};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use nix::{
|
||||
sys::signal::{kill, Signal},
|
||||
unistd::Pid,
|
||||
};
|
||||
use pacwrap_core::{
|
||||
config::cache,
|
||||
constants::{ARROW_GREEN, BOLD, RESET},
|
||||
constants::{ARROW_GREEN, BOLD, DIM, RESET},
|
||||
err,
|
||||
impl_error,
|
||||
process::{self, Process},
|
||||
|
@ -243,6 +244,7 @@ fn process_kill(args: &mut Arguments) -> Result<()> {
|
|||
err!(InvalidArgument::TargetUnspecified)?
|
||||
}
|
||||
|
||||
let mut instances = IndexMap::new();
|
||||
let cache = cache::populate()?;
|
||||
let list = process::list(&cache)?;
|
||||
let list = match all {
|
||||
|
@ -265,11 +267,18 @@ fn process_kill(args: &mut Arguments) -> Result<()> {
|
|||
if process.fork() {
|
||||
fork_warn(process);
|
||||
}
|
||||
|
||||
match instances.get(process.instance()) {
|
||||
Some(value) => instances.insert(process.instance(), value + 1),
|
||||
None => instances.insert(process.instance(), 1),
|
||||
};
|
||||
}
|
||||
|
||||
let instances: Vec<String> = instances.iter().map(|a| format!("{} ({}{}{})", a.0, *DIM, a.1, *RESET)).collect();
|
||||
|
||||
if no_confirm {
|
||||
kill_processes(&list, sigint)
|
||||
} else if let Ok(_) = prompt_targets(&list.iter().map(|a| a.instance()).collect(), "Kill processes?", false) {
|
||||
} else if let Ok(_) = prompt_targets(&instances.iter().map(|a| a.as_ref()).collect(), "Kill container processes?", false) {
|
||||
kill_processes(&list, sigint)
|
||||
} else {
|
||||
Ok(())
|
||||
|
|
|
@ -26,7 +26,7 @@ use pacwrap_core::{
|
|||
log::Logger,
|
||||
sync::transaction::{TransactionAggregator, TransactionFlags, TransactionType},
|
||||
utils::{
|
||||
arguments::{Arguments, InvalidArgument, Operand as Op},
|
||||
arguments::{Arguments, InvalidArgument::*, Operand as Op},
|
||||
check_root,
|
||||
},
|
||||
};
|
||||
|
@ -62,7 +62,7 @@ fn engage_aggregator<'a>(action_type: TransactionType, args: &'a mut Arguments,
|
|||
let mut current_target = None;
|
||||
|
||||
if let Op::Nothing = args.next().unwrap_or_default() {
|
||||
err!(InvalidArgument::OperationUnspecified)?
|
||||
err!(OperationUnspecified)?
|
||||
}
|
||||
|
||||
while let Some(arg) = args.next() {
|
||||
|
@ -72,18 +72,23 @@ fn engage_aggregator<'a>(action_type: TransactionType, args: &'a mut Arguments,
|
|||
| Op::Long("recursive")
|
||||
| Op::Short('R')
|
||||
| Op::Short('c')
|
||||
| Op::Short('s')
|
||||
| Op::Short('t') => continue,
|
||||
| Op::Short('s') => continue,
|
||||
Op::Long("dbonly") => flags = flags | TransactionFlags::DATABASE_ONLY,
|
||||
Op::Long("noconfirm") => flags = flags | TransactionFlags::NO_CONFIRM,
|
||||
Op::Long("force-foreign") => flags = flags | TransactionFlags::FORCE_DATABASE,
|
||||
Op::Short('p') | Op::Long("preview") => flags = flags | TransactionFlags::PREVIEW,
|
||||
Op::Short('f') | Op::Long("filesystem") => flags = flags | TransactionFlags::FILESYSTEM_SYNC,
|
||||
Op::ShortPos('t', target) | Op::LongPos("target", target) => {
|
||||
cache.get_instance(target)?;
|
||||
current_target = Some(target);
|
||||
targets.push(target);
|
||||
}
|
||||
Op::Short('t') | Op::Long("target") => match args.next() {
|
||||
Some(arg) => match arg {
|
||||
Op::ShortPos('t', target) | Op::LongPos("target", target) => {
|
||||
cache.get_instance(target)?;
|
||||
current_target = Some(target);
|
||||
targets.push(target);
|
||||
}
|
||||
_ => args.invalid_operand()?,
|
||||
},
|
||||
None => err!(TargetUnspecified)?,
|
||||
},
|
||||
Op::LongPos(_, package) | Op::ShortPos(_, package) | Op::Value(package) =>
|
||||
if let Some(target) = current_target {
|
||||
match queue.get_mut(target) {
|
||||
|
@ -98,7 +103,7 @@ fn engage_aggregator<'a>(action_type: TransactionType, args: &'a mut Arguments,
|
|||
}
|
||||
|
||||
if let None = current_target {
|
||||
err!(InvalidArgument::TargetUnspecified)?
|
||||
err!(TargetUnspecified)?
|
||||
}
|
||||
|
||||
Ok(TransactionAggregator::new(&cache, log, action_type)
|
||||
|
|
|
@ -117,12 +117,18 @@ fn acquire_depends<'a>(args: &mut Arguments<'a>) -> Result<IndexMap<&'a str, (Co
|
|||
}
|
||||
None => err!(TargetUnspecified)?,
|
||||
},
|
||||
Op::ShortPos('t', target) | Op::LongPos("target", target) => match instype {
|
||||
Some(instype) => {
|
||||
current_target = target;
|
||||
deps.insert(current_target, (instype, vec![]));
|
||||
}
|
||||
None => err!(ErrorKind::Message("Container type not specified."))?,
|
||||
Op::Short('t') | Op::Long("target") => match args.next() {
|
||||
Some(arg) => match arg {
|
||||
Op::ShortPos('t', target) | Op::LongPos("target", target) => match instype {
|
||||
Some(instype) => {
|
||||
current_target = target;
|
||||
deps.insert(current_target, (instype, vec![]));
|
||||
}
|
||||
None => err!(ErrorKind::Message("Container type not specified."))?,
|
||||
},
|
||||
_ => args.invalid_operand()?,
|
||||
},
|
||||
None => err!(TargetUnspecified)?,
|
||||
},
|
||||
_ => continue,
|
||||
}
|
||||
|
@ -224,14 +230,12 @@ fn engage_aggregator<'a>(
|
|||
Op::Short('a')
|
||||
| Op::Short('s')
|
||||
| Op::Short('d')
|
||||
| Op::Short('t')
|
||||
| Op::Short('y')
|
||||
| Op::Short('u')
|
||||
| Op::Short('c')
|
||||
| Op::Long("aggregate")
|
||||
| Op::Long("slice")
|
||||
| Op::Long("dep")
|
||||
| Op::Long("target")
|
||||
| Op::Long("refresh")
|
||||
| Op::Long("upgrade")
|
||||
| Op::Long("create")
|
||||
|
@ -243,16 +247,22 @@ fn engage_aggregator<'a>(
|
|||
Op::Long("dbonly") => flags = flags | TransactionFlags::DATABASE_ONLY,
|
||||
Op::Long("force-foreign") => flags = flags | TransactionFlags::FORCE_DATABASE,
|
||||
Op::Long("noconfirm") => flags = flags | TransactionFlags::NO_CONFIRM,
|
||||
Op::ShortPos('t', target) | Op::LongPos("target", target) => {
|
||||
cache.get_instance(target)?;
|
||||
current_target = target;
|
||||
targets.insert(target);
|
||||
Op::Short('t') | Op::Long("target") => match args.next() {
|
||||
Some(arg) => match arg {
|
||||
Op::ShortPos('t', target) | Op::LongPos("target", target) => {
|
||||
cache.get_instance(target)?;
|
||||
current_target = target;
|
||||
targets.insert(target);
|
||||
|
||||
if base {
|
||||
queue.insert(current_target.into(), vec!["base"]);
|
||||
base = false;
|
||||
}
|
||||
}
|
||||
if base {
|
||||
queue.insert(current_target.into(), vec!["base"]);
|
||||
base = false;
|
||||
}
|
||||
}
|
||||
_ => args.invalid_operand()?,
|
||||
},
|
||||
None => err!(TargetUnspecified)?,
|
||||
},
|
||||
Op::LongPos(_, package) | Op::ShortPos(_, package) | Op::Value(package) =>
|
||||
if current_target != "" {
|
||||
if let Some(vec) = queue.get_mut(current_target) {
|
||||
|
@ -265,18 +275,18 @@ fn engage_aggregator<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
if flags.contains(TransactionFlags::CREATE) {
|
||||
for cache in cache.registered_handles().iter().filter(|a| a.is_creation()) {
|
||||
targets.extend(cache.metadata().dependencies());
|
||||
}
|
||||
}
|
||||
|
||||
let targets: Option<Vec<&str>> = match flags.contains(TransactionFlags::TARGET_ONLY) {
|
||||
let targets: Option<Vec<&str>> = match flags.intersects(TransactionFlags::TARGET_ONLY | TransactionFlags::CREATE) {
|
||||
true => {
|
||||
if current_target == "" && !flags.contains(TransactionFlags::FILESYSTEM_SYNC) {
|
||||
err!(TargetUnspecified)?
|
||||
}
|
||||
|
||||
if flags.contains(TransactionFlags::CREATE) {
|
||||
for cache in cache.registered_handles().iter().filter(|a| a.is_creation()) {
|
||||
targets.extend(cache.metadata().dependencies());
|
||||
}
|
||||
}
|
||||
|
||||
match flags.contains(TransactionFlags::FILESYSTEM_SYNC) {
|
||||
false => Some(targets.into_iter().collect()),
|
||||
true => None,
|
||||
|
|
|
@ -20,15 +20,17 @@
|
|||
use std::{
|
||||
fmt::{Display, Formatter},
|
||||
fs::remove_dir_all,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use pacwrap_core::{
|
||||
config::{cache, ContainerCache},
|
||||
constants::{ARROW_GREEN, BOLD, RESET},
|
||||
constants::{ARROW_GREEN, BOLD, DATA_DIR, RESET},
|
||||
err,
|
||||
impl_error,
|
||||
log::{Level::Info, Logger},
|
||||
process,
|
||||
sync::filesystem::create_blank_state,
|
||||
utils::{arguments::Operand, prompt::prompt_targets, Arguments},
|
||||
Error,
|
||||
ErrorGeneric,
|
||||
|
@ -58,7 +60,7 @@ pub fn remove_containers(args: &mut Arguments) -> Result<()> {
|
|||
let mut targets = vec![];
|
||||
let mut no_confirm = false;
|
||||
let mut force = false;
|
||||
let mut logger = Logger::new("pacwrap-utils");
|
||||
let mut logger = Logger::new("pacwrap-utils").init()?;
|
||||
|
||||
while let Some(arg) = args.next() {
|
||||
match arg {
|
||||
|
@ -103,8 +105,13 @@ pub fn delete_roots(cache: &ContainerCache<'_>, logger: &mut Logger, targets: &V
|
|||
for container in containers {
|
||||
let root = container.vars().root();
|
||||
let instance = container.vars().instance();
|
||||
|
||||
let state = &format!("{}/state/{instance}.dat", *DATA_DIR);
|
||||
remove_dir_all(root).prepend(|| format!("Failed to delete container root '{root}':"))?;
|
||||
|
||||
if Path::new(state).exists() {
|
||||
create_blank_state(instance)?;
|
||||
}
|
||||
|
||||
eprintln!("{} Deleted container {}{}{} successfully.", *ARROW_GREEN, *BOLD, instance, *RESET);
|
||||
logger.log(Info, &format!("Deleted container {instance}"))?;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue