From 3427e04224b959bcabaefd549297549c2b369958 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Tue, 2 Jan 2024 21:19:14 +0100 Subject: [PATCH] feat(commands): create show and set subcommands for config Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- src/commands.rs | 6 +-- src/commands/backup.rs | 4 +- src/commands/config.rs | 46 ++++++------------- src/commands/config/set.rs | 42 +++++++++++++++++ .../{show_config.rs => config/show.rs} | 7 +-- src/commands/copy.rs | 4 +- src/commands/forget.rs | 4 +- src/config.rs | 2 +- src/filtering.rs | 13 ++++-- src/lib.rs | 3 ++ 10 files changed, 80 insertions(+), 51 deletions(-) create mode 100644 src/commands/config/set.rs rename src/commands/{show_config.rs => config/show.rs} (65%) diff --git a/src/commands.rs b/src/commands.rs index 6ff90ec..a70af14 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -19,7 +19,6 @@ pub(crate) mod repair; pub(crate) mod repoinfo; pub(crate) mod restore; pub(crate) mod self_update; -pub(crate) mod show_config; pub(crate) mod snapshots; pub(crate) mod tag; @@ -34,7 +33,7 @@ use crate::{ config::ConfigCmd, copy::CopyCmd, diff::DiffCmd, dump::DumpCmd, forget::ForgetCmd, init::InitCmd, key::KeyCmd, list::ListCmd, ls::LsCmd, merge::MergeCmd, prune::PruneCmd, repair::RepairCmd, repoinfo::RepoInfoCmd, restore::RestoreCmd, self_update::SelfUpdateCmd, - show_config::ShowConfigCmd, snapshots::SnapshotCmd, tag::TagCmd, + snapshots::SnapshotCmd, tag::TagCmd, }, config::{progress_options::ProgressOptions, RusticConfig}, {Application, RUSTIC_APP}, @@ -104,9 +103,6 @@ enum RusticCmd { /// Show a detailed overview of the snapshots within the repository Snapshots(SnapshotCmd), - /// Show the configuration which has been read from the config file(s) - ShowConfig(ShowConfigCmd), - /// Update to the latest rustic release #[cfg_attr(not(feature = "self-update"), clap(hide = true))] SelfUpdate(SelfUpdateCmd), diff --git a/src/commands/backup.rs b/src/commands/backup.rs index 6dbf570..1cb97de 100644 --- a/src/commands/backup.rs +++ b/src/commands/backup.rs @@ -12,7 +12,7 @@ use anyhow::{bail, Context, Result}; use log::{debug, info, warn}; use merge::Merge; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use rustic_core::{ BackupOptions, ConfigOptions, KeyOptions, LocalSourceFilterOptions, LocalSourceSaveOptions, @@ -22,7 +22,7 @@ use rustic_core::{ use super::init::init; /// `backup` subcommand -#[derive(Clone, Command, Default, Debug, clap::Parser, Deserialize, Merge)] +#[derive(Clone, Command, Default, Debug, clap::Parser, Serialize, Deserialize, Merge)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] // Note: using cli_sources, sources and source within this struct is a hack to support serde(deny_unknown_fields) // for deserializing the backup options from TOML diff --git a/src/commands/config.rs b/src/commands/config.rs index bee33aa..f90bcbe 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -1,43 +1,23 @@ //! `config` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +pub mod set; +pub mod show; -use abscissa_core::{Command, Runnable, Shutdown}; +use crate::commands::config::{set::SetConfigCmd, show::ShowConfigCmd}; -use anyhow::Result; - -use rustic_core::ConfigOptions; +use abscissa_core::{Command, Runnable}; /// `config` subcommand -#[derive(clap::Parser, Command, Debug)] +#[derive(clap::Parser, Command, Runnable, Debug)] pub(crate) struct ConfigCmd { - /// Config options - #[clap(flatten)] - config_opts: ConfigOptions, + #[clap(subcommand)] + cmd: ConfigSubCmd, } -impl Runnable for ConfigCmd { - fn run(&self) { - if let Err(err) = self.inner_run() { - status_err!("{}", err); - RUSTIC_APP.shutdown(Shutdown::Crash); - }; - } -} - -impl ConfigCmd { - fn inner_run(&self) -> Result<()> { - let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?; - - let changed = repo.apply_config(&self.config_opts)?; - - if changed { - println!("saved new config"); - } else { - println!("config is unchanged"); - } - - Ok(()) - } +#[derive(clap::Subcommand, Debug, Runnable)] +enum ConfigSubCmd { + /// Set the configuration + Set(SetConfigCmd), + /// Show the configuration which has been read from the config file(s) + Show(ShowConfigCmd), } diff --git a/src/commands/config/set.rs b/src/commands/config/set.rs new file mode 100644 index 0000000..67dd825 --- /dev/null +++ b/src/commands/config/set.rs @@ -0,0 +1,42 @@ +//! `set` subcommand + +use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; + +use abscissa_core::{Command, Runnable, Shutdown}; + +use anyhow::Result; + +use rustic_core::ConfigOptions; + +/// `set` subcommand +#[derive(clap::Parser, Command, Debug)] +pub(crate) struct SetConfigCmd { + #[clap(flatten)] + config_opts: ConfigOptions, +} + +impl Runnable for SetConfigCmd { + fn run(&self) { + if let Err(err) = self.inner_run() { + status_err!("{}", err); + RUSTIC_APP.shutdown(Shutdown::Crash); + }; + } +} + +impl SetConfigCmd { + fn inner_run(&self) -> Result<()> { + let config = RUSTIC_APP.config(); + let repo = open_repository(&config)?; + + let changed = repo.apply_config(&self.config_opts)?; + + if changed { + println!("saved new config"); + } else { + println!("config is unchanged"); + } + + Ok(()) + } +} diff --git a/src/commands/show_config.rs b/src/commands/config/show.rs similarity index 65% rename from src/commands/show_config.rs rename to src/commands/config/show.rs index 10797fe..0535971 100644 --- a/src/commands/show_config.rs +++ b/src/commands/config/show.rs @@ -1,16 +1,17 @@ -//! `show-config` subcommand +//! `show` subcommand use crate::{Application, RUSTIC_APP}; use abscissa_core::{Command, Runnable}; -/// `show-config` subcommand +/// `show` subcommand #[derive(clap::Parser, Command, Debug)] pub(crate) struct ShowConfigCmd {} impl Runnable for ShowConfigCmd { fn run(&self) { let config = RUSTIC_APP.config(); - println!("{config:#?}"); + let toml_string = toml::to_string(&config).unwrap(); + println!("{toml_string}"); } } diff --git a/src/commands/copy.rs b/src/commands/copy.rs index fb7d5af..c244900 100644 --- a/src/commands/copy.rs +++ b/src/commands/copy.rs @@ -8,7 +8,7 @@ use anyhow::{bail, Result}; use log::{error, info}; use merge::Merge; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use rustic_core::{CopySnapshot, Id, KeyOptions, Repository, RepositoryOptions}; @@ -29,7 +29,7 @@ pub(crate) struct CopyCmd { } /// Target repository options -#[derive(Default, Clone, Debug, Deserialize, Merge)] +#[derive(Default, Clone, Debug, Serialize, Deserialize, Merge)] pub struct Targets { /// Target repositories #[merge(strategy = merge::vec::overwrite_empty)] diff --git a/src/commands/forget.rs b/src/commands/forget.rs index f547241..15fa390 100644 --- a/src/commands/forget.rs +++ b/src/commands/forget.rs @@ -10,7 +10,7 @@ use abscissa_core::{Command, FrameworkError, Runnable}; use anyhow::Result; use merge::Merge; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DisplayFromStr}; use crate::{commands::prune::PruneCmd, filtering::SnapshotFilter}; @@ -63,7 +63,7 @@ impl Override for ForgetCmd { /// Forget options #[serde_as] -#[derive(Clone, Default, Debug, clap::Parser, Deserialize, Merge)] +#[derive(Clone, Default, Debug, clap::Parser, Serialize, Deserialize, Merge)] #[serde(default, rename_all = "kebab-case")] pub struct ForgetOptions { /// Group snapshots by any combination of host,label,paths,tags (default: "host,label,paths") diff --git a/src/config.rs b/src/config.rs index 2546699..cd98adf 100644 --- a/src/config.rs +++ b/src/config.rs @@ -33,7 +33,7 @@ use crate::{ /// /// # Example // TODO: add example -#[derive(Clone, Default, Debug, Parser, Deserialize, Merge)] +#[derive(Clone, Default, Debug, Parser, Serialize, Deserialize, Merge)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] pub struct RusticConfig { /// Global options diff --git a/src/filtering.rs b/src/filtering.rs index fefb7ae..6faa9a9 100644 --- a/src/filtering.rs +++ b/src/filtering.rs @@ -2,10 +2,10 @@ use crate::error::RhaiErrorKinds; use log::warn; use rustic_core::{repofile::SnapshotFile, StringList}; -use std::{error::Error, str::FromStr}; +use std::{error::Error, fmt::Display, str::FromStr}; use rhai::{serde::to_dynamic, Dynamic, Engine, FnPtr, AST}; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DisplayFromStr}; /// A function to filter snapshots @@ -14,6 +14,13 @@ use serde_with::{serde_as, DisplayFromStr}; #[derive(Clone, Debug)] pub(crate) struct SnapshotFn(FnPtr, AST); +impl Display for SnapshotFn { + // FIXME: What shall we display here? + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "") + } +} + impl FromStr for SnapshotFn { type Err = RhaiErrorKinds; fn from_str(s: &str) -> Result { @@ -43,7 +50,7 @@ impl SnapshotFn { } #[serde_as] -#[derive(Clone, Default, Debug, Deserialize, merge::Merge, clap::Parser)] +#[derive(Clone, Default, Debug, Serialize, Deserialize, merge::Merge, clap::Parser)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] pub struct SnapshotFilter { /// Hostname to filter (can be specified multiple times) diff --git a/src/lib.rs b/src/lib.rs index b594b31..f7d2905 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,6 +32,9 @@ Application based on the [Abscissa] framework. overflowing_literals, path_statements, patterns_in_fns_without_body, + // unnameable_types, // unstable + private_bounds, + private_interfaces, trivial_numeric_casts, unused_results, trivial_casts,