move todo_per_backend into separate module

This commit is contained in:
steven-omaha
2023-01-10 15:21:02 +01:00
parent 627f66ea35
commit 1bf19f4669
4 changed files with 102 additions and 83 deletions
+3
View File
@@ -1,6 +1,7 @@
mod macros; mod macros;
mod pacman; mod pacman;
mod rust; mod rust;
mod todo_per_backend;
use std::collections::HashSet; use std::collections::HashSet;
use std::os::unix::process::CommandExt; use std::os::unix::process::CommandExt;
@@ -8,6 +9,8 @@ use std::process::Command;
use crate::{Group, Package}; use crate::{Group, Package};
pub(crate) use todo_per_backend::ToDoPerBackend;
pub use pacman::Pacman; pub use pacman::Pacman;
pub use rust::Rust; pub use rust::Rust;
pub(in crate::backend) type Switches = &'static [&'static str]; pub(in crate::backend) type Switches = &'static [&'static str];
+48
View File
@@ -0,0 +1,48 @@
use super::Backend;
use crate::Package;
pub(crate) struct ToDoPerBackend(Vec<(Box<dyn Backend>, Vec<Package>)>);
impl ToDoPerBackend {
pub(crate) fn new() -> Self {
Self(vec![])
}
pub(crate) fn push(&mut self, item: (Box<dyn Backend>, Vec<Package>)) {
self.0.push(item);
}
pub(crate) fn into_iter(self) -> impl Iterator<Item = (Box<dyn Backend>, Vec<Package>)> {
self.0.into_iter()
}
pub(crate) fn iter(&self) -> impl Iterator<Item = &(Box<dyn Backend>, Vec<Package>)> {
self.0.iter()
}
pub(crate) fn nothing_to_do_for_all_backends(&self) -> bool {
self.0.iter().all(|(_, diff)| diff.is_empty())
}
pub(crate) fn install_missing_packages(&self) {
self.0
.iter()
.for_each(|(backend, diff)| backend.install_packages(diff));
}
pub(crate) fn is_empty(&self) -> bool {
self.0.iter().all(|(_, packages)| packages.is_empty())
}
pub(crate) fn show(&self) {
for (backend, packages) in self.iter() {
if packages.is_empty() {
continue;
}
println!("{}", backend.get_section());
for package in packages {
println!(" {package}");
}
}
}
}
+45 -81
View File
@@ -1,14 +1,13 @@
use std::collections::HashSet; use std::collections::HashSet;
use anyhow::{bail, Context, Result}; use anyhow::{ensure, Context, Result};
use clap::ArgMatches; use clap::ArgMatches;
use crate::action; use crate::action;
use crate::backend::{Backend, Backends}; use crate::backend::{Backends, ToDoPerBackend};
use crate::cmd::run_edit_command; use crate::cmd::run_edit_command;
use crate::ui::get_user_confirmation; use crate::ui::get_user_confirmation;
use crate::Group; use crate::Group;
use crate::Package;
pub struct Pacdef { pub struct Pacdef {
args: ArgMatches, args: ArgMatches,
@@ -20,39 +19,6 @@ impl Pacdef {
Self { args, groups } Self { args, groups }
} }
fn install_packages(&self) {
let mut to_install = ToDoPerBackend::new();
for mut b in Backends::iter() {
print!("{}: ", b.get_binary());
b.load(&self.groups);
let diff = b.get_missing_packages_sorted();
if diff.is_empty() {
println!("nothing to do");
continue;
}
println!("would install the following packages");
for p in &diff {
println!(" {p}");
}
to_install.push((b, diff));
println!();
}
if to_install.nothing_to_do_for_all_backends() {
return;
}
if !get_user_confirmation() {
return;
};
to_install.install_missing_packages()
}
#[allow(clippy::unit_arg)] #[allow(clippy::unit_arg)]
pub fn run_action_from_arg(self) -> Result<()> { pub fn run_action_from_arg(self) -> Result<()> {
match self.args.subcommand() { match self.args.subcommand() {
@@ -69,31 +35,63 @@ impl Pacdef {
} }
} }
fn get_missing_packages(&self) -> ToDoPerBackend {
let mut to_install = ToDoPerBackend::new();
for mut b in Backends::iter() {
b.load(&self.groups);
let diff = b.get_missing_packages_sorted();
to_install.push((b, diff));
}
to_install
}
fn install_packages(&self) {
let to_install = self.get_missing_packages();
if to_install.nothing_to_do_for_all_backends() {
println!("nothing to do");
return;
}
to_install.show();
if !get_user_confirmation() {
return;
};
to_install.install_missing_packages()
}
fn edit_group_files(&self, groups: &ArgMatches) -> Result<()> { fn edit_group_files(&self, groups: &ArgMatches) -> Result<()> {
let group_dir = crate::path::get_pacdef_group_dir()?;
let files: Vec<_> = groups let files: Vec<_> = groups
.get_many::<String>("group") .get_many::<String>("group")
.context("getting group from args")? .context("getting group from args")?
.map(|file| { .map(|file| {
let mut buf = crate::path::get_pacdef_group_dir().unwrap(); let mut buf = group_dir.clone();
buf.push(file); buf.push(file);
buf buf
}) })
.collect(); .collect();
for file in &files { for file in &files {
if !file.exists() { ensure!(
bail!("group file {} not found", file.to_string_lossy()); file.exists(),
} "group file {} not found",
file.to_string_lossy()
);
} }
if run_edit_command(&files) let success = run_edit_command(&files)
.context("running editor")? .context("running editor")?
.success() .success();
{
Ok(()) ensure!(success, "editor exited with error");
} else { Ok(())
bail!("editor exited with error")
}
} }
fn show_version(self) { fn show_version(self) {
@@ -162,37 +160,3 @@ impl Pacdef {
} }
} }
} }
struct ToDoPerBackend(Vec<(Box<dyn Backend>, Vec<Package>)>);
impl ToDoPerBackend {
fn new() -> Self {
Self(vec![])
}
fn push(&mut self, item: (Box<dyn Backend>, Vec<Package>)) {
self.0.push(item);
}
fn into_iter(self) -> impl Iterator<Item = (Box<dyn Backend>, Vec<Package>)> {
self.0.into_iter()
}
fn iter(&self) -> impl Iterator<Item = &(Box<dyn Backend>, Vec<Package>)> {
self.0.iter()
}
fn nothing_to_do_for_all_backends(&self) -> bool {
self.0.iter().all(|(_, diff)| diff.is_empty())
}
fn install_missing_packages(&self) {
self.0
.iter()
.for_each(|(backend, diff)| backend.install_packages(diff));
}
fn is_empty(&self) -> bool {
self.0.iter().all(|(_, packages)| packages.is_empty())
}
}
+6 -2
View File
@@ -68,8 +68,12 @@ impl Group {
P: AsRef<Path>, P: AsRef<Path>,
{ {
let path = p.as_ref(); let path = p.as_ref();
let content = read_to_string(path).unwrap(); let content = read_to_string(path).context("reading file content")?;
let name = path.file_name().unwrap().to_string_lossy().to_string(); let name = path
.file_name()
.context("getting file name")?
.to_string_lossy()
.to_string();
let mut lines = content.lines().peekable(); let mut lines = content.lines().peekable();
let mut sections = HashSet::new(); let mut sections = HashSet::new();