feat(commands): create show and set subcommands for config

Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
This commit is contained in:
simonsan 2024-01-02 21:19:14 +01:00
parent 188ef505cb
commit 3427e04224
No known key found for this signature in database
GPG Key ID: E11D13668EC3B71B
10 changed files with 80 additions and 51 deletions

View File

@ -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),

View File

@ -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

View File

@ -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),
}

View File

@ -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(())
}
}

View File

@ -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}");
}
}

View File

@ -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)]

View File

@ -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<RusticConfig> 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")

View File

@ -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

View File

@ -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, "<function>")
}
}
impl FromStr for SnapshotFn {
type Err = RhaiErrorKinds;
fn from_str(s: &str) -> Result<Self, Self::Err> {
@ -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)

View File

@ -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,