diff --git a/Cargo.lock b/Cargo.lock index 3c7749f..cfe07ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,6 +45,21 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.14" @@ -160,6 +175,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "byteorder" version = "1.5.0" @@ -184,6 +205,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.5", +] + [[package]] name = "clap" version = "4.5.7" @@ -257,6 +292,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + [[package]] name = "cpufeatures" version = "0.2.12" @@ -422,6 +463,7 @@ checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" name = "firefish-cli" version = "0.1.0-alpha.1" dependencies = [ + "chrono", "clap", "color-print", "serde", @@ -632,6 +674,29 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -670,6 +735,15 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1769,6 +1843,60 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.66", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + [[package]] name = "whoami" version = "1.5.1" @@ -1779,6 +1907,15 @@ dependencies = [ "wasite", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index cb52530..58d5f9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ name = "fishctl" path = "src/main.rs" [dependencies] +chrono = "0.4" clap = { version = "4.5", features = ["derive"] } color-print = "0.3" thiserror = "1.0" diff --git a/src/command/config/update.rs b/src/command/config/update.rs index 5b7f0d0..2fcec09 100644 --- a/src/command/config/update.rs +++ b/src/command/config/update.rs @@ -4,29 +4,50 @@ mod v1; use crate::{ command::config::{next_revision, RevisionCheckError}, - config::Revision, + config::{Revision, CLIENT_CONFIG_PATH, SERVER_CONFIG_PATH}, }; +use chrono::Local; +use color_print::cprintln; +use std::{fs, io}; #[derive(thiserror::Error, Debug)] pub(crate) enum UpdateError { #[error(transparent)] UnknownRevision(#[from] RevisionCheckError), #[error(transparent)] + FileOperation(#[from] io::Error), + #[error(transparent)] V1(#[from] v1::Error), } -async fn update_to_latest() -> Result<(), UpdateError> { - if next_revision()?.is_none() { - println!("Your config files are already up-to-date! (as of this fishctl release)"); - return Ok(()); - } +fn take_backup() -> Result<(), UpdateError> { + let current_time = Local::now().format("%Y%m%d%H%M%S").to_string(); + let server_backup_filename = format!("{}-backup-{}", SERVER_CONFIG_PATH, current_time); + let client_backup_filename = format!("{}-backup-{}", CLIENT_CONFIG_PATH, current_time); + cprintln!( + "Saving server config backup as {}...", + server_backup_filename + ); + fs::copy(SERVER_CONFIG_PATH, server_backup_filename)?; + + cprintln!( + "Saving client config backup as {}...", + client_backup_filename + ); + fs::copy(CLIENT_CONFIG_PATH, client_backup_filename)?; + + Ok(()) +} + +async fn update_to_latest() -> Result<(), UpdateError> { while let Some(next_revision) = next_revision()? { run_impl(next_revision).await?; } Ok(()) } +/// Updates config files to the specified revision. async fn run_impl(revision: Revision) -> Result<(), UpdateError> { match revision { Revision::V1 => v1::run().await?, @@ -35,6 +56,16 @@ async fn run_impl(revision: Revision) -> Result<(), UpdateError> { } pub(super) async fn run(revision: Option) -> Result<(), UpdateError> { + let next_revision = next_revision()?; + + if next_revision.is_none() { + println!("Your config files are already up-to-date! (as of this fishctl release)"); + return Ok(()); + } + if next_revision.unwrap() != Revision::V1 { + take_backup()?; + } + match revision { Some(revision) => run_impl(revision).await, None => update_to_latest().await, diff --git a/src/command/config/update/v1.rs b/src/command/config/update/v1.rs index 32baa28..d208184 100644 --- a/src/command/config/update/v1.rs +++ b/src/command/config/update/v1.rs @@ -432,7 +432,7 @@ fn create_new_client_config(meta: Meta) -> Result { } pub(super) async fn run() -> Result<(), Error> { - println!("Updating the config revision to 1..."); + println!("Updating the config to revision 1..."); let (default_yml, meta) = read_old_config().await?;