1use anyhow::{Result, anyhow};
4
5use crate::pkg::{self, transaction};
6use crate::utils;
7
8pub fn run(
18 package_name: &str,
19 yes: bool,
20 plugin_manager: Option<&crate::pkg::plugin::PluginManager>
21) -> Result<()> {
22 let request = pkg::resolve::parse_source_string(package_name)?;
23 let mut candidates = Vec::new();
24 for scope in [
25 pkg::types::Scope::User,
26 pkg::types::Scope::System,
27 pkg::types::Scope::Project
28 ] {
29 candidates.extend(pkg::local::find_installed_manifests_matching(
30 &request, scope
31 )?);
32 }
33 if candidates.is_empty() {
34 return Err(anyhow!("Package '{package_name}' is not installed."));
35 }
36 let chosen = crate::cmd::installed_select::choose_installed_manifest(
37 package_name,
38 &candidates,
39 yes
40 )?;
41
42 if let Some(pm) = plugin_manager {
43 pm.set_context(chosen.scope)?;
44 pm.trigger_hook("on_rollback", None)?;
45 }
46 pkg::rollback::run(&pkg::local::installed_manifest_source(&chosen), yes)
47}
48
49pub fn run_transaction_rollback(
57 yes: bool,
58 plugin_manager: Option<&crate::pkg::plugin::PluginManager>
59) -> Result<()> {
60 if !utils::ask_for_confirmation(
61 "This will roll back the last recorded transaction. Are you sure?",
62 yes
63 ) {
64 println!("Operation aborted.");
65 return Ok(());
66 }
67
68 if let Some(id) = transaction::get_last_transaction_id()? {
69 println!("Rolling back transaction {id}...");
70 if let Some(pm) = plugin_manager {
71 pm.trigger_hook("on_rollback", None)?;
72 }
73 transaction::rollback(&id)
74 } else {
75 println!("No transactions found to roll back.");
76 Ok(())
77 }
78}