Revert "more review stuff"

This reverts commit b95f3889bb.

This is WIP and does not compile right now. See branch `review`.
This commit is contained in:
Dr. Matthias Ratajczak
2023-01-30 14:39:27 +01:00
parent 091fd3488d
commit aa9cdbf362
4 changed files with 99 additions and 138 deletions
-4
View File
@@ -67,10 +67,6 @@ impl Backend for Pacman {
cmd.status() cmd.status()
.with_context(|| format!("running command [{cmd:?}]")) .with_context(|| format!("running command [{cmd:?}]"))
} }
fn supports_assigning_packages_as_dependency(&self) -> bool {
true
}
} }
fn get_all_installed_packages_from_alpm() -> Result<HashSet<String>> { fn get_all_installed_packages_from_alpm() -> Result<HashSet<String>> {
-4
View File
@@ -31,10 +31,6 @@ impl Backend for Rust {
self.get_all_installed_packages() self.get_all_installed_packages()
.context("getting all installed packages") .context("getting all installed packages")
} }
fn supports_assigning_packages_as_dependency(&self) -> bool {
false
}
} }
fn extract_packages(json: Value) -> Result<HashSet<Package>> { fn extract_packages(json: Value) -> Result<HashSet<Package>> {
-2
View File
@@ -33,8 +33,6 @@ pub(crate) trait Backend {
.with_context(|| format!("running command {cmd:?}")) .with_context(|| format!("running command {cmd:?}"))
} }
fn supports_assigning_packages_as_dependency(&self) -> bool;
/// Remove the specified packages. /// Remove the specified packages.
fn remove_packages(&self, packages: &[Package]) -> Result<ExitStatus> { fn remove_packages(&self, packages: &[Package]) -> Result<ExitStatus> {
let mut cmd = Command::new(self.get_binary()); let mut cmd = Command::new(self.get_binary());
+99 -128
View File
@@ -7,7 +7,6 @@ use termios::*;
use crate::backend::{Backend, Backends, ToDoPerBackend}; use crate::backend::{Backend, Backends, ToDoPerBackend};
use crate::grouping::{Group, Package, Section}; use crate::grouping::{Group, Package, Section};
use crate::ui::get_user_confirmation;
#[derive(Debug)] #[derive(Debug)]
enum ReviewAction { enum ReviewAction {
@@ -20,80 +19,23 @@ enum ReviewAction {
Quit, Quit,
} }
struct Reviews { struct Reviews<'a> {
pub delete: Vec<Delete>, pub delete: Vec<(Rc<Box<dyn Backend>>, Package)>,
pub assign: Vec<Assign>, pub assign: Vec<(Rc<Box<dyn Backend>>, Package, &'a Group, &'a Section)>,
pub as_dependency: Vec<AsDependency>,
} }
struct AsDependency { impl<'a> Reviews<'a> {
backend: Rc<Box<dyn Backend>>,
package: Package,
}
impl AsDependency {
fn new(backend: Rc<Box<dyn Backend>>, package: Package) -> Self {
Self { backend, package }
}
}
struct Assign {
backend: Rc<Box<dyn Backend>>,
package: Package,
group: Rc<Group>,
}
impl Assign {
fn new(backend: Rc<Box<dyn Backend>>, package: Package, group: Rc<Group>) -> Self {
Self {
backend,
package,
group,
}
}
}
struct Delete {
items: Vec<>
backend: Rc<Box<dyn Backend>>,
package: Package,
}
impl Delete {
fn new(backend: Rc<Box<dyn Backend>>, package: Package) -> Self {
Self { backend, package }
}
}
impl Reviews {
fn new() -> Self { fn new() -> Self {
Self { Self {
delete: vec![], delete: vec![],
assign: vec![], assign: vec![],
as_dependency: vec![],
} }
} }
fn show_strategy(&mut self) {
self.delete
.sort_by_key(|d| (&d.backend.get_section(), &d.package));
if !self.delete.is_empty() {
println!("Will delete the following packages:");
let mut iter = self.delete.iter().peekable();
// while let Some(delete) = iter.next() {
// delete.
// }
}
}
fn execute(&self) -> Result<()> {
todo!()
}
} }
pub(crate) fn review(todo_per_backend: ToDoPerBackend, groups: HashSet<Group>) -> Result<()> { pub(crate) fn review(todo_per_backend: ToDoPerBackend, groups: HashSet<Group>) -> Result<()> {
let mut reviews = Reviews::new(); let mut reviews = Reviews::new();
let mut groups: Vec<_> = groups.into_iter().map(Rc::new).collect(); let mut groups: Vec<_> = groups.into_iter().collect();
groups.sort_unstable(); groups.sort_unstable();
if todo_per_backend.nothing_to_do_for_all_backends() { if todo_per_backend.nothing_to_do_for_all_backends() {
@@ -101,87 +43,110 @@ pub(crate) fn review(todo_per_backend: ToDoPerBackend, groups: HashSet<Group>) -
return Ok(()); return Ok(());
} }
gather_reviews(todo_per_backend, groups, &mut reviews)?;
reviews.show_strategy();
if !get_user_confirmation() {
return Ok(());
}
reviews.execute()
}
fn gather_reviews(
todo_per_backend: ToDoPerBackend,
groups: Vec<Rc<Group>>,
reviews: &mut Reviews,
) -> Result<()> {
for (backend, packages) in todo_per_backend.into_iter() { for (backend, packages) in todo_per_backend.into_iter() {
let backend = Rc::new(backend); let backend = Rc::new(backend);
for package in packages { for package in packages {
println!("{}: {package}", backend.get_section()); println!("{}: {package}", backend.get_section());
get_action_for_package(package, &groups, reviews, &backend)?; get_action_for_package(package, &groups, &mut reviews, &backend)?;
} }
} }
Ok(())
todo!()
} }
fn get_action_for_package( fn get_action_for_package(
package: Package, package: Package,
groups: &[Rc<Group>], groups: &[Group],
reviews: &mut Reviews, reviews: &mut Reviews,
backend: &Rc<Box<dyn Backend>>, backend: &Rc<Box<dyn Backend>>,
) -> Result<()> { ) -> Result<()> {
loop { todo!();
match ask_user_action_for_package(backend)? { // loop {
ReviewAction::AsDependency => { // match ask_user_action_for_package()? {
let as_dependency = AsDependency::new(backend.clone(), package); // ReviewAction::AsDependency => todo!(),
reviews.as_dependency.push(as_dependency); // ReviewAction::AssignGroupBackend => {
break; // if let Some(val) = assign_group_backend(&package, groups)? {
} // break;
ReviewAction::AssignGroupBackend => { // };
if let Some(group) = assign_group(groups)? { // }
let assign = Assign::new(backend.clone(), package, group); // ReviewAction::Delete => {
reviews.assign.push(assign); // reviews.delete.push((backend.clone(), package));
break; // break;
}; // }
} // ReviewAction::Info => backend.show_package_info(&package)?,
ReviewAction::Delete => { // ReviewAction::Invalid => (),
let delete = Delete::new(backend.clone(), package); // ReviewAction::Skip => break,
reviews.delete.push(delete); // ReviewAction::Quit => bail!("user wants to quit"),
break; // }
} // }
ReviewAction::Info => backend.show_package_info(&package)?,
ReviewAction::Invalid => (),
ReviewAction::Skip => break,
ReviewAction::Quit => bail!("user wants to quit"), // TODO requires an own error type?
}
}
Ok(()) Ok(())
} }
fn ask_user_action_for_package(backend: &Rc<Box<dyn Backend>>) -> Result<ReviewAction> { fn ask_user_group_section(groups: &[Group]) -> Result<Option<GroupSectionReply>> {
if backend.supports_assigning_packages_as_dependency() { let group = match ask_group(groups)? {
ask_action_including_dependency() Some(group) => group,
None => return Ok(None),
};
let section_reply = match ask_section(&group.sections)? {
Some(reply) => reply,
None => return Ok(None),
};
let section = match section_reply {
SectionReply::Existing(section) => section,
SectionReply::New => return Ok(Some(GroupSectionReply::New)),
};
Ok(Some(GroupSectionReply::Existing((group, section))))
}
enum GroupSectionReply<'a> {
Existing((&'a Group, &'a Section)),
New,
}
enum SectionReply<'a> {
Existing(&'a Section),
New,
}
fn ask_section(sections: &HashSet<Section>) -> Result<Option<SectionReply>> {
let sections: Vec<_> = sections.iter().collect();
let mut buf = String::new();
stdin().read_line(&mut buf)?;
let reply = buf.trim();
let idx: usize = if let Ok(idx) = reply.parse() {
idx
} else { } else {
ask_action_without_dependency() return Ok(None);
};
if idx < sections.len() {
Ok(Some(SectionReply::Existing(&sections[idx])))
} else if idx == sections.len() {
Ok(Some(SectionReply::New))
} else {
Ok(None)
} }
} }
fn ask_action_without_dependency() -> Result<ReviewAction> { fn ask_new_section_name() -> Result<String> {
print!("assign to (g)roup, (d)elete, (s)kip, (i)nfo, (q)uit? "); print!("new section name: ");
match read_single_char_from_terminal()? { let reply = stdin().lines().next().context("reading line from stdin")?;
'd' => Ok(ReviewAction::Delete), reply.map_err(|e| anyhow!(e))
'g' => Ok(ReviewAction::AssignGroupBackend),
'i' => Ok(ReviewAction::Info),
'q' => Ok(ReviewAction::Quit),
's' => Ok(ReviewAction::Skip),
_ => Ok(ReviewAction::Invalid),
}
} }
fn ask_action_including_dependency() -> Result<ReviewAction> { fn print_enumerated_sections(sections: &[Section]) {
for (i, section) in sections.iter().enumerate() {
println!("{i}: {}", section.name);
}
println!("{}: [new]", sections.len());
}
fn ask_user_action_for_package() -> Result<ReviewAction> {
print!("assign to (g)roup, (d)elete, (s)kip, (i)nfo, (a)s dependency, (q)uit? "); print!("assign to (g)roup, (d)elete, (s)kip, (i)nfo, (a)s dependency, (q)uit? ");
match read_single_char_from_terminal()? { match read_single_char_from_terminal()? {
'a' => Ok(ReviewAction::AsDependency), 'a' => Ok(ReviewAction::AsDependency),
@@ -212,13 +177,14 @@ fn read_single_char_from_terminal() -> Result<char> {
Ok(result) Ok(result)
} }
fn print_enumerated_groups(groups: &[Rc<Group>]) { fn print_enumerated_groups(groups: &[Group]) {
for (i, group) in groups.iter().enumerate() { for (i, group) in groups.iter().enumerate() {
println!("{i}: {}", group.name); println!("{i}: {}", group.name);
} }
} }
fn ask_group(groups: &[Rc<Group>]) -> Result<Option<Rc<Group>>> { fn ask_group(groups: &[Group]) -> Result<Option<&Group>> {
print_enumerated_groups(groups);
let mut buf = String::new(); let mut buf = String::new();
stdin().read_line(&mut buf)?; stdin().read_line(&mut buf)?;
let reply = buf.trim(); let reply = buf.trim();
@@ -230,13 +196,18 @@ fn ask_group(groups: &[Rc<Group>]) -> Result<Option<Rc<Group>>> {
}; };
if idx < groups.len() { if idx < groups.len() {
Ok(Some(groups[idx].clone())) Ok(Some(&groups[idx]))
} else { } else {
Ok(None) Ok(None)
} }
} }
fn assign_group(groups: &[Rc<Group>]) -> Result<Option<Rc<Group>>> { fn assign_group_backend(package: &Package, groups: &[Group]) -> Result<()> {
print_enumerated_groups(groups); let reply = ask_user_group_section(groups)?;
ask_group(groups) match reply {
Some(val) => todo!(),
None => todo!(),
}
todo!()
} }