rustic_rs/commands/
rewrite.rs1use crate::{
4 Application, RUSTIC_APP,
5 commands::snapshots::print_snapshots,
6 repository::{IndexedRepo, OpenRepo, get_snapots_from_ids},
7 status_err,
8};
9
10use abscissa_core::{Command, Runnable, Shutdown};
11use anyhow::Result;
12use log::info;
13
14use rustic_core::{
15 Excludes, NodeModification, RewriteOptions, RewriteTreesOptions, StringList,
16 repofile::{SnapshotFile, SnapshotModification},
17};
18
19#[derive(clap::Parser, Command, Debug, Default)]
21pub(crate) struct RewriteCmd {
22 #[clap(value_name = "ID")]
26 pub ids: Vec<String>,
27
28 #[clap(long)]
30 pub forget: bool,
31
32 #[clap(long, value_name = "TAG[,TAG,..]")]
34 pub tags_rewritten: Option<StringList>,
35
36 #[clap(flatten, next_help_heading = "Snapshot options")]
37 pub modification: SnapshotModification,
38
39 #[clap(long, help_heading = "Tree rewrite options")]
41 pub all_trees: bool,
42
43 #[clap(flatten, next_help_heading = "Exclude options")]
44 pub excludes: Excludes,
45
46 #[clap(flatten, next_help_heading = "Node modification options")]
47 pub node_modification: NodeModification,
48}
49
50impl Runnable for RewriteCmd {
51 fn run(&self) {
52 let repo = &RUSTIC_APP.config().repository;
53
54 if let Err(err) =
55 if self.excludes.is_empty() && self.node_modification.is_empty() && !self.all_trees {
56 repo.run_open(|repo| self.inner_run_open(repo))
57 } else {
58 repo.run_indexed(|repo| self.inner_run_indexed(repo))
59 }
60 {
61 status_err!("{}", err);
62 RUSTIC_APP.shutdown(Shutdown::Crash);
63 }
64 }
65}
66
67impl RewriteCmd {
68 fn opts(&self) -> RewriteOptions {
69 let config = RUSTIC_APP.config();
70 RewriteOptions::default()
71 .forget(self.forget)
72 .tags_rewritten(self.tags_rewritten.clone())
73 .modification(self.modification.clone())
74 .dry_run(config.global.dry_run)
75 }
76
77 fn inner_run_open(&self, repo: OpenRepo) -> Result<()> {
78 let snapshots = get_snapots_from_ids(&repo, &self.ids)?;
79
80 let snaps = repo.rewrite_snapshots(snapshots, &self.opts())?;
81
82 self.output(snaps);
83
84 Ok(())
85 }
86
87 fn inner_run_indexed(&self, repo: IndexedRepo) -> Result<()> {
88 let snapshots = get_snapots_from_ids(&repo, &self.ids)?;
89 let tree_opts = RewriteTreesOptions::default()
90 .all_trees(self.all_trees)
91 .excludes(self.excludes.clone())
92 .node_modification(self.node_modification.clone());
93
94 let snaps = repo.rewrite_snapshots_and_trees(snapshots, &self.opts(), &tree_opts)?;
95
96 self.output(snaps);
97
98 Ok(())
99 }
100
101 fn output(&self, snaps: Vec<SnapshotFile>) {
102 let config = RUSTIC_APP.config();
103 if config.global.dry_run {
104 println!("Would have rewritten the following snapshots:");
105 print_snapshots(snaps, false, true);
106 } else {
107 info!("{} snapshots have been rewritten", snaps.len());
108 }
109 }
110}