diff options
author | fxqnlr <[email protected]> | 2024-09-25 15:13:34 +0200 |
---|---|---|
committer | fxqnlr <[email protected]> | 2024-09-25 15:13:34 +0200 |
commit | d44041040d755306c39d6de8da5b42d7ded6808c (patch) | |
tree | d664c15e014aa36dc5735ec4be4919866fb6a9e5 /src | |
parent | 0ed94b3f011a2d3c22bdc4affb502720be22c371 (diff) | |
download | arbs-d44041040d755306c39d6de8da5b42d7ded6808c.tar arbs-d44041040d755306c39d6de8da5b42d7ded6808c.tar.gz arbs-d44041040d755306c39d6de8da5b42d7ded6808c.zip |
added notifications and improved stuff
Diffstat (limited to 'src')
-rw-r--r-- | src/backup.rs | 37 | ||||
-rw-r--r-- | src/cli.rs | 7 | ||||
-rw-r--r-- | src/config.rs | 28 | ||||
-rw-r--r-- | src/error.rs | 17 | ||||
-rw-r--r-- | src/main.rs | 47 | ||||
-rw-r--r-- | src/packages.rs | 13 | ||||
-rw-r--r-- | src/pathinfo.rs | 110 |
7 files changed, 153 insertions, 106 deletions
diff --git a/src/backup.rs b/src/backup.rs index 3d07ace..b468917 100644 --- a/src/backup.rs +++ b/src/backup.rs | |||
@@ -2,18 +2,18 @@ use std::{ | |||
2 | fs::{create_dir_all, File}, | 2 | fs::{create_dir_all, File}, |
3 | io::{Read, Write}, | 3 | io::{Read, Write}, |
4 | path::PathBuf, | 4 | path::PathBuf, |
5 | time::{SystemTime, UNIX_EPOCH}, | 5 | time::SystemTime, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use serde::{Deserialize, Serialize}; | 8 | use serde::{Deserialize, Serialize}; |
9 | use tracing::info; | 9 | use tracing::{debug, info}; |
10 | use uuid::Uuid; | 10 | use uuid::Uuid; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | config::Config, | 13 | config::Config, |
14 | error::{Error, Result}, | 14 | error::{Error, Result}, |
15 | packages::{Manager, PackageList}, | 15 | packages::PackageList, |
16 | pathinfo::PathInfo, | 16 | pathinfo::PathInfo, send_notification, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | pub type Id = String; | 19 | pub type Id = String; |
@@ -28,16 +28,20 @@ pub struct Backup { | |||
28 | } | 28 | } |
29 | 29 | ||
30 | impl Backup { | 30 | impl Backup { |
31 | pub fn create(config: &Config, manager: Option<Manager>) -> Result<Self> { | 31 | pub fn create(config: &Config) -> Result<Self> { |
32 | let mut files: Vec<PathInfo> = Vec::new(); | 32 | let mut files: Vec<PathInfo> = Vec::new(); |
33 | for dir in &config.directories { | 33 | for dir in &config.directories { |
34 | files.push(PathInfo::from_path(config, dir)?); | 34 | files.push(PathInfo::from_path(config, dir)?); |
35 | } | 35 | } |
36 | Ok(Self { | 36 | Ok(Self { |
37 | // TODO: UUID not really needed, maybe a shorter hash | ||
38 | id: Uuid::new_v4().to_string(), | 37 | id: Uuid::new_v4().to_string(), |
39 | timestamp: Self::get_timestamp(), | 38 | timestamp: SystemTime::now() |
40 | packages: Manager::get_manager(manager)?.get_installed()?, | 39 | .duration_since(SystemTime::UNIX_EPOCH)? |
40 | .as_secs(), | ||
41 | packages: config | ||
42 | .package_manager | ||
43 | .to_package_manager() | ||
44 | .get_installed()?, | ||
41 | files, | 45 | files, |
42 | device: config.device.clone(), | 46 | device: config.device.clone(), |
43 | }) | 47 | }) |
@@ -58,12 +62,14 @@ impl Backup { | |||
58 | path.save(&backup_root)?; | 62 | path.save(&backup_root)?; |
59 | } | 63 | } |
60 | 64 | ||
65 | send_notification("Backup created" , "", notify_rust::Urgency::Normal)?; | ||
66 | |||
61 | Ok(()) | 67 | Ok(()) |
62 | } | 68 | } |
63 | 69 | ||
64 | pub fn get_last(config: &Config) -> Result<Option<Self>> { | 70 | pub fn get_last(config: &Config) -> Result<Option<Self>> { |
65 | let backup_index_root = format!("{}/index.json", config.root); | 71 | let backup_index_root = format!("{}/index.json", config.root); |
66 | info!(?backup_index_root, "backup index location:"); | 72 | debug!(?backup_index_root, "backup index location:"); |
67 | let list: Vec<IndexEntry> = match Self::get_json_content(&backup_index_root) { | 73 | let list: Vec<IndexEntry> = match Self::get_json_content(&backup_index_root) { |
68 | Ok(list) => list, | 74 | Ok(list) => list, |
69 | Err(err) => { | 75 | Err(err) => { |
@@ -74,8 +80,6 @@ impl Backup { | |||
74 | } | 80 | } |
75 | }; | 81 | }; |
76 | 82 | ||
77 | info!(?list, "backup index:"); | ||
78 | |||
79 | Ok(Some(Self::from_index( | 83 | Ok(Some(Self::from_index( |
80 | config, | 84 | config, |
81 | &list.last().ok_or(Error::BackupNotFound)?.id, | 85 | &list.last().ok_or(Error::BackupNotFound)?.id, |
@@ -122,6 +126,8 @@ impl Backup { | |||
122 | path.restore(config, &backup_root)?; | 126 | path.restore(config, &backup_root)?; |
123 | } | 127 | } |
124 | 128 | ||
129 | send_notification("Backup restored" , "", notify_rust::Urgency::Normal)?; | ||
130 | |||
125 | Ok(()) | 131 | Ok(()) |
126 | } | 132 | } |
127 | 133 | ||
@@ -131,13 +137,6 @@ impl Backup { | |||
131 | file.read_to_string(&mut content)?; | 137 | file.read_to_string(&mut content)?; |
132 | Ok(serde_json::from_str(&content)?) | 138 | Ok(serde_json::from_str(&content)?) |
133 | } | 139 | } |
134 | |||
135 | fn get_timestamp() -> u64 { | ||
136 | SystemTime::now() | ||
137 | .duration_since(UNIX_EPOCH) | ||
138 | .unwrap() | ||
139 | .as_secs() | ||
140 | } | ||
141 | } | 140 | } |
142 | 141 | ||
143 | #[derive(Debug, Clone, Serialize, Deserialize)] | 142 | #[derive(Debug, Clone, Serialize, Deserialize)] |
@@ -165,7 +164,7 @@ impl IndexEntry { | |||
165 | 164 | ||
166 | f.write_all(&serde_json::to_vec(&loc)?)?; | 165 | f.write_all(&serde_json::to_vec(&loc)?)?; |
167 | } else { | 166 | } else { |
168 | create_dir_all(&config.root).unwrap(); | 167 | create_dir_all(&config.root)?; |
169 | let mut f = File::create(backup_index_root)?; | 168 | let mut f = File::create(backup_index_root)?; |
170 | f.write_all(&serde_json::to_vec(&vec![self])?)?; | 169 | f.write_all(&serde_json::to_vec(&vec![self])?)?; |
171 | }; | 170 | }; |
@@ -2,8 +2,6 @@ use std::path::PathBuf; | |||
2 | 2 | ||
3 | use clap::{Parser, Subcommand}; | 3 | use clap::{Parser, Subcommand}; |
4 | 4 | ||
5 | use crate::packages::Manager; | ||
6 | |||
7 | #[derive(Parser)] | 5 | #[derive(Parser)] |
8 | pub struct Cli { | 6 | pub struct Cli { |
9 | #[arg(short, long)] | 7 | #[arg(short, long)] |
@@ -16,10 +14,7 @@ pub struct Cli { | |||
16 | #[derive(Subcommand)] | 14 | #[derive(Subcommand)] |
17 | pub enum Subcommands { | 15 | pub enum Subcommands { |
18 | GenerateConfig, | 16 | GenerateConfig, |
19 | Save { | 17 | Save, |
20 | #[arg(short, long)] | ||
21 | package_manager: Option<Manager>, | ||
22 | }, | ||
23 | Restore { | 18 | Restore { |
24 | #[arg(short, long)] | 19 | #[arg(short, long)] |
25 | package_install: bool | 20 | package_install: bool |
diff --git a/src/config.rs b/src/config.rs index 46d2204..848be19 100644 --- a/src/config.rs +++ b/src/config.rs | |||
@@ -4,6 +4,8 @@ use config::{File, Map}; | |||
4 | use serde::{Deserialize, Serialize}; | 4 | use serde::{Deserialize, Serialize}; |
5 | use tracing::{debug, trace}; | 5 | use tracing::{debug, trace}; |
6 | 6 | ||
7 | use crate::{error::{Error, Result}, packages::Manager}; | ||
8 | |||
7 | #[derive(Debug, Serialize, Deserialize)] | 9 | #[derive(Debug, Serialize, Deserialize)] |
8 | #[serde(default)] | 10 | #[serde(default)] |
9 | pub struct Config { | 11 | pub struct Config { |
@@ -11,6 +13,7 @@ pub struct Config { | |||
11 | pub directories: Vec<String>, | 13 | pub directories: Vec<String>, |
12 | pub custom_directories: Map<String, String>, | 14 | pub custom_directories: Map<String, String>, |
13 | pub device: String, | 15 | pub device: String, |
16 | pub package_manager: Manager, | ||
14 | } | 17 | } |
15 | 18 | ||
16 | impl Default for Config { | 19 | impl Default for Config { |
@@ -22,17 +25,18 @@ impl Default for Config { | |||
22 | device: gethostname::gethostname() | 25 | device: gethostname::gethostname() |
23 | .into_string() | 26 | .into_string() |
24 | .expect("invalid hostname string"), | 27 | .expect("invalid hostname string"), |
28 | package_manager: Manager::from_sys().expect("couldn't get package manager"), | ||
25 | } | 29 | } |
26 | } | 30 | } |
27 | } | 31 | } |
28 | 32 | ||
29 | impl Config { | 33 | impl Config { |
30 | pub fn load(path: Option<PathBuf>) -> core::result::Result<Self, config::ConfigError> { | 34 | pub fn load(path: Option<PathBuf>) -> Result<Self> { |
31 | debug!("load config"); | 35 | debug!("load config"); |
32 | let source = if let Some(source) = path { | 36 | let source = if let Some(source) = path { |
33 | source | 37 | source |
34 | } else { | 38 | } else { |
35 | Self::get_location() | 39 | Self::get_location()? |
36 | }; | 40 | }; |
37 | 41 | ||
38 | let config = config::Config::builder() | 42 | let config = config::Config::builder() |
@@ -40,14 +44,14 @@ impl Config { | |||
40 | .add_source(config::Environment::with_prefix("FXBAUP").separator("_")) | 44 | .add_source(config::Environment::with_prefix("FXBAUP").separator("_")) |
41 | .build()?; | 45 | .build()?; |
42 | 46 | ||
43 | let cfg = config.try_deserialize(); | 47 | let cfg = config.try_deserialize()?; |
44 | trace!(?cfg, "loaded config"); | 48 | trace!(?cfg, "loaded config"); |
45 | 49 | ||
46 | cfg | 50 | Ok(cfg) |
47 | } | 51 | } |
48 | 52 | ||
49 | pub fn generate() -> crate::error::Result<()> { | 53 | pub fn generate() -> Result<()> { |
50 | let loc = Self::get_location(); | 54 | let loc = Self::get_location()?; |
51 | create_dir_all(loc.parent().unwrap())?; | 55 | create_dir_all(loc.parent().unwrap())?; |
52 | let mut f = std::fs::File::create(loc)?; | 56 | let mut f = std::fs::File::create(loc)?; |
53 | f.write_all(toml::to_string(&Self::default())?.as_bytes())?; | 57 | f.write_all(toml::to_string(&Self::default())?.as_bytes())?; |
@@ -55,10 +59,12 @@ impl Config { | |||
55 | Ok(()) | 59 | Ok(()) |
56 | } | 60 | } |
57 | 61 | ||
58 | fn get_location() -> PathBuf { | 62 | fn get_location() -> Result<PathBuf> { |
59 | let mut conf_dir = dirs::config_local_dir().unwrap(); | 63 | let Some(mut config_dir) = dirs::config_dir() else { |
60 | conf_dir.push("arbs"); | 64 | return Err(Error::NoSysDir); |
61 | conf_dir.push("config.toml"); | 65 | }; |
62 | conf_dir | 66 | config_dir.push(env!("CARGO_PKG_NAME")); |
67 | config_dir.push("config.toml"); | ||
68 | Ok(config_dir) | ||
63 | } | 69 | } |
64 | } | 70 | } |
diff --git a/src/error.rs b/src/error.rs index cb57e99..8270b45 100644 --- a/src/error.rs +++ b/src/error.rs | |||
@@ -1,3 +1,5 @@ | |||
1 | use tracing::error; | ||
2 | |||
1 | pub type Result<T> = std::result::Result<T, Error>; | 3 | pub type Result<T> = std::result::Result<T, Error>; |
2 | 4 | ||
3 | #[derive(Debug, thiserror::Error)] | 5 | #[derive(Debug, thiserror::Error)] |
@@ -17,6 +19,10 @@ pub enum Error { | |||
17 | #[error("Requested backup not found")] | 19 | #[error("Requested backup not found")] |
18 | BackupNotFound, | 20 | BackupNotFound, |
19 | 21 | ||
22 | // Utils | ||
23 | #[error("System directory not found")] | ||
24 | NoSysDir, | ||
25 | |||
20 | // Packages | 26 | // Packages |
21 | #[error("Unknown Package Manger Output")] | 27 | #[error("Unknown Package Manger Output")] |
22 | UnknownOutput, | 28 | UnknownOutput, |
@@ -26,11 +32,22 @@ pub enum Error { | |||
26 | 32 | ||
27 | // Deps | 33 | // Deps |
28 | #[error(transparent)] | 34 | #[error(transparent)] |
35 | Config(#[from] config::ConfigError), | ||
36 | |||
37 | #[error(transparent)] | ||
29 | SerdeJson(#[from] serde_json::Error), | 38 | SerdeJson(#[from] serde_json::Error), |
30 | 39 | ||
31 | #[error(transparent)] | 40 | #[error(transparent)] |
32 | TomlSerialize(#[from] toml::ser::Error), | 41 | TomlSerialize(#[from] toml::ser::Error), |
33 | 42 | ||
43 | #[cfg(feature = "notifications")] | ||
44 | #[error(transparent)] | ||
45 | Notify(#[from] notify_rust::error::Error), | ||
46 | |||
47 | // Rust | ||
34 | #[error(transparent)] | 48 | #[error(transparent)] |
35 | Io(#[from] std::io::Error), | 49 | Io(#[from] std::io::Error), |
50 | |||
51 | #[error(transparent)] | ||
52 | SystemTime(#[from] std::time::SystemTimeError), | ||
36 | } | 53 | } |
diff --git a/src/main.rs b/src/main.rs index 487d095..ab23ab7 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -2,8 +2,9 @@ use backup::Backup; | |||
2 | use clap::Parser; | 2 | use clap::Parser; |
3 | use cli::Subcommands; | 3 | use cli::Subcommands; |
4 | use config::Config; | 4 | use config::Config; |
5 | use error::Error; | 5 | use error::{Error, Result}; |
6 | use tracing::{debug, level_filters::LevelFilter}; | 6 | use notify_rust::Urgency; |
7 | use tracing::{debug, error, level_filters::LevelFilter}; | ||
7 | use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; | 8 | use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; |
8 | 9 | ||
9 | mod backup; | 10 | mod backup; |
@@ -13,9 +14,7 @@ mod error; | |||
13 | mod packages; | 14 | mod packages; |
14 | mod pathinfo; | 15 | mod pathinfo; |
15 | 16 | ||
16 | fn main() -> color_eyre::Result<()> { | 17 | fn main() -> Result<()> { |
17 | color_eyre::install()?; | ||
18 | |||
19 | let file_appender = tracing_appender::rolling::never("./", "arbs.log"); | 18 | let file_appender = tracing_appender::rolling::never("./", "arbs.log"); |
20 | let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender); | 19 | let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender); |
21 | 20 | ||
@@ -35,15 +34,27 @@ fn main() -> color_eyre::Result<()> { | |||
35 | ) | 34 | ) |
36 | .init(); | 35 | .init(); |
37 | debug!("logging initialized"); | 36 | debug!("logging initialized"); |
37 | |||
38 | match run_cli() { | ||
39 | Ok(()) => { println!("OK") ; Ok(())}, | ||
40 | Err(err) => { | ||
41 | error!(?err); | ||
42 | error!("{:?}", std::error::Error::source(&err)); | ||
43 | send_notification("Backup Error", &err.to_string(), Urgency::Critical)?; | ||
44 | Err(err) | ||
45 | } | ||
46 | } | ||
47 | } | ||
38 | 48 | ||
49 | fn run_cli() -> Result<()> { | ||
39 | let cli = cli::Cli::parse(); | 50 | let cli = cli::Cli::parse(); |
40 | 51 | ||
41 | let config = Config::load(cli.config)?; | 52 | let config = Config::load(cli.config)?; |
42 | 53 | ||
43 | match cli.subcommand { | 54 | match cli.subcommand { |
44 | Subcommands::GenerateConfig => Config::generate()?, | 55 | Subcommands::GenerateConfig => Config::generate()?, |
45 | Subcommands::Save { package_manager } => { | 56 | Subcommands::Save => { |
46 | let backup = Backup::create(&config, package_manager)?; | 57 | let backup = Backup::create(&config)?; |
47 | backup.save(&config)?; | 58 | backup.save(&config)?; |
48 | } | 59 | } |
49 | Subcommands::Restore { package_install } => { | 60 | Subcommands::Restore { package_install } => { |
@@ -56,7 +67,27 @@ fn main() -> color_eyre::Result<()> { | |||
56 | } | 67 | } |
57 | 68 | ||
58 | last_backup.restore(&config)?; | 69 | last_backup.restore(&config)?; |
59 | } | 70 | }, |
60 | }; | 71 | }; |
61 | Ok(()) | 72 | Ok(()) |
62 | } | 73 | } |
74 | |||
75 | fn send_notification(summary: &str, body: &str, urgency: Urgency) -> Result<()> { | ||
76 | #[cfg(feature = "notifications")] | ||
77 | { | ||
78 | let Some(mut icon) = dirs::data_dir() else { | ||
79 | return Err(Error::NoSysDir); | ||
80 | }; | ||
81 | icon.push(env!("CARGO_PKG_NAME")); | ||
82 | icon.push("icon.png"); | ||
83 | |||
84 | notify_rust::Notification::new() | ||
85 | .summary(summary) | ||
86 | .body(body) | ||
87 | .icon(&icon.to_string_lossy()) | ||
88 | .timeout(0) | ||
89 | .urgency(urgency) | ||
90 | .show()?; | ||
91 | } | ||
92 | Ok(()) | ||
93 | } | ||
diff --git a/src/packages.rs b/src/packages.rs index de818f4..41b9478 100644 --- a/src/packages.rs +++ b/src/packages.rs | |||
@@ -37,15 +37,12 @@ pub enum Manager { | |||
37 | } | 37 | } |
38 | 38 | ||
39 | impl Manager { | 39 | impl Manager { |
40 | pub fn get_manager(manager: Option<Manager>) -> Result<Box<dyn PackageManager>> { | 40 | pub fn from_sys() -> Result<Self> { |
41 | #[cfg(not(target_os = "linux"))] | 41 | #[cfg(not(target_os = "linux"))] |
42 | return Err(Error::Unsupported); | 42 | return Err(Error::Unsupported); |
43 | 43 | ||
44 | #[cfg(target_os = "linux")] | 44 | #[cfg(target_os = "linux")] |
45 | { | 45 | { |
46 | if let Some(man) = manager { | ||
47 | return Ok(man.to_package_manager()); | ||
48 | } | ||
49 | let mut os_release = File::open("/etc/os-release")?; | 46 | let mut os_release = File::open("/etc/os-release")?; |
50 | let mut content = String::new(); | 47 | let mut content = String::new(); |
51 | os_release.read_to_string(&mut content)?; | 48 | os_release.read_to_string(&mut content)?; |
@@ -63,15 +60,15 @@ impl Manager { | |||
63 | } | 60 | } |
64 | } | 61 | } |
65 | 62 | ||
66 | fn from_str(value: &str) -> Result<Box<dyn PackageManager>> { | 63 | fn from_str(value: &str) -> Result<Self> { |
67 | Ok(match value { | 64 | Ok(match value { |
68 | "arch" => Box::new(Pacman), | 65 | "arch" => Self::Pacman, |
69 | "gentoo" => Box::new(Portage), | 66 | "gentoo" => Self::Portage, |
70 | _ => return Err(Error::Unsupported), | 67 | _ => return Err(Error::Unsupported), |
71 | }) | 68 | }) |
72 | } | 69 | } |
73 | 70 | ||
74 | fn to_package_manager(&self) -> Box<dyn PackageManager> { | 71 | pub fn to_package_manager(&self) -> Box<dyn PackageManager> { |
75 | match self { | 72 | match self { |
76 | Self::Pacman => Box::new(Pacman), | 73 | Self::Pacman => Box::new(Pacman), |
77 | Self::Portage => Box::new(Portage), | 74 | Self::Portage => Box::new(Portage), |
diff --git a/src/pathinfo.rs b/src/pathinfo.rs index 1231ff8..009f46a 100644 --- a/src/pathinfo.rs +++ b/src/pathinfo.rs | |||
@@ -6,7 +6,7 @@ use std::{ | |||
6 | }; | 6 | }; |
7 | 7 | ||
8 | use serde::{Deserialize, Serialize}; | 8 | use serde::{Deserialize, Serialize}; |
9 | use tracing::{debug, info}; | 9 | use tracing::{debug, info, trace}; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | backup::{Backup, Id}, | 12 | backup::{Backup, Id}, |
@@ -35,7 +35,7 @@ impl PathInfo { | |||
35 | rel_location: &str, | 35 | rel_location: &str, |
36 | location_root: &LocationRoot, | 36 | location_root: &LocationRoot, |
37 | ) -> Result<Self> { | 37 | ) -> Result<Self> { |
38 | info!("Handling {rel_location}"); | 38 | trace!("Handling {rel_location}"); |
39 | let path = Self::get_abs_path(&location_root.to_string(), rel_location); | 39 | let path = Self::get_abs_path(&location_root.to_string(), rel_location); |
40 | Ok(if path.is_dir() { | 40 | Ok(if path.is_dir() { |
41 | let mut last_modified = Some(String::new()); | 41 | let mut last_modified = Some(String::new()); |
@@ -83,7 +83,7 @@ impl PathInfo { | |||
83 | ) -> Result<Self> { | 83 | ) -> Result<Self> { |
84 | let last_modified = Self::compare_to_last_modified(config, location_root, rel_location)?; | 84 | let last_modified = Self::compare_to_last_modified(config, location_root, rel_location)?; |
85 | 85 | ||
86 | info!("From file {rel_location} ({last_modified:?})"); | 86 | debug!("From file {rel_location} ({last_modified:?})"); |
87 | 87 | ||
88 | Ok(Self { | 88 | Ok(Self { |
89 | rel_location: rel_location.to_string(), | 89 | rel_location: rel_location.to_string(), |
@@ -301,14 +301,15 @@ mod tests { | |||
301 | .custom_directories | 301 | .custom_directories |
302 | .insert("test".to_string(), "/usr/local/test".to_string()); | 302 | .insert("test".to_string(), "/usr/local/test".to_string()); |
303 | 303 | ||
304 | let mut values_ok: Vec<(&str, LocationRoot)> = Vec::new(); | 304 | let values_ok = vec![ |
305 | values_ok.push(("u:test", LocationRoot::User)); | 305 | ("u:test", LocationRoot::User), |
306 | values_ok.push(("s:", LocationRoot::SystemConfig)); | 306 | ("s:", LocationRoot::SystemConfig), |
307 | values_ok.push(("r:", LocationRoot::Root)); | 307 | ("r:", LocationRoot::Root), |
308 | values_ok.push(( | 308 | ( |
309 | "c:test", | 309 | "c:test", |
310 | LocationRoot::Custom("/usr/local/test".to_string()), | 310 | LocationRoot::Custom("/usr/local/test".to_string()), |
311 | )); | 311 | ), |
312 | ]; | ||
312 | 313 | ||
313 | for value in values_ok { | 314 | for value in values_ok { |
314 | println!("Testing {value:?}"); | 315 | println!("Testing {value:?}"); |
@@ -316,18 +317,19 @@ mod tests { | |||
316 | println!("\x1B[FTesting {value:?} ✓"); | 317 | println!("\x1B[FTesting {value:?} ✓"); |
317 | } | 318 | } |
318 | 319 | ||
319 | let mut values_err: Vec<(&str, String)> = Vec::new(); | 320 | let values_err = vec![ |
320 | values_err.push(( | 321 | ( |
321 | "c:rest", | 322 | "c:rest", |
322 | Error::CustomDirectory("rest".to_string()).to_string(), | 323 | Error::CustomDirectory("rest".to_string()).to_string(), |
323 | )); | 324 | ), |
324 | values_err.push(("t:test/", Error::InvalidIndex("t".to_string()).to_string())); | 325 | ("t:test/", Error::InvalidIndex("t".to_string()).to_string()), |
325 | values_err.push(( | 326 | ( |
326 | "test:test/usr", | 327 | "test:test/usr", |
327 | Error::InvalidIndex("test".to_string()).to_string(), | 328 | Error::InvalidIndex("test".to_string()).to_string(), |
328 | )); | 329 | ), |
329 | values_err.push(("/usr/local/test", Error::NoIndex.to_string())); | 330 | ("/usr/local/test", Error::NoIndex.to_string()), |
330 | values_err.push(("c/usr/local/test", Error::NoIndex.to_string())); | 331 | ("c/usr/local/test", Error::NoIndex.to_string()), |
332 | ]; | ||
331 | 333 | ||
332 | for value in values_err { | 334 | for value in values_err { |
333 | println!("Testing {value:?}"); | 335 | println!("Testing {value:?}"); |
@@ -351,47 +353,47 @@ mod tests { | |||
351 | .custom_directories | 353 | .custom_directories |
352 | .insert("test".to_string(), "/usr/local/test".to_string()); | 354 | .insert("test".to_string(), "/usr/local/test".to_string()); |
353 | 355 | ||
354 | let mut values_ok: Vec<(&str, (String, LocationRoot))> = Vec::new(); | 356 | let values_ok = vec![ |
355 | values_ok.push(( | ||
356 | "~/.config/nvim", | ||
357 | (".config/nvim".to_string(), LocationRoot::User), | ||
358 | )); | ||
359 | values_ok.push(( | ||
360 | "u:test/.config/nvim", | ||
361 | (".config/nvim".to_string(), LocationRoot::User), | ||
362 | )); | ||
363 | values_ok.push(( | ||
364 | "r:/.config/nvim", | ||
365 | (".config/nvim".to_string(), LocationRoot::Root), | ||
366 | )); | ||
367 | values_ok.push(( | ||
368 | "r:/.config/nvim", | ||
369 | (".config/nvim".to_string(), LocationRoot::Root), | ||
370 | )); | ||
371 | values_ok.push(( | ||
372 | "s:/.config/nvim", | ||
373 | (".config/nvim".to_string(), LocationRoot::SystemConfig), | ||
374 | )); | ||
375 | values_ok.push(( | ||
376 | "c:test/.config/nvim", | ||
377 | ( | 357 | ( |
378 | ".config/nvim".to_string(), | 358 | "~/.config/nvim", |
379 | LocationRoot::Custom("/usr/local/test".to_string()), | 359 | (".config/nvim".to_string(), LocationRoot::User), |
360 | ), | ||
361 | ( | ||
362 | "u:test/.config/nvim", | ||
363 | (".config/nvim".to_string(), LocationRoot::User), | ||
380 | ), | 364 | ), |
381 | )); | 365 | ( |
366 | "r:/.config/nvim", | ||
367 | (".config/nvim".to_string(), LocationRoot::Root), | ||
368 | ), | ||
369 | ( | ||
370 | "r:/.config/nvim", | ||
371 | (".config/nvim".to_string(), LocationRoot::Root), | ||
372 | ), | ||
373 | ( | ||
374 | "s:/.config/nvim", | ||
375 | (".config/nvim".to_string(), LocationRoot::SystemConfig), | ||
376 | ), | ||
377 | ( | ||
378 | "c:test/.config/nvim", | ||
379 | ( | ||
380 | ".config/nvim".to_string(), | ||
381 | LocationRoot::Custom("/usr/local/test".to_string()), | ||
382 | ), | ||
383 | ), | ||
384 | ]; | ||
382 | 385 | ||
383 | for value in values_ok { | 386 | for value in values_ok { |
384 | print!("Testing {value:?}"); | 387 | print!("Testing {value:?}"); |
385 | assert_eq!(PathInfo::parse_location(&value.0, &config)?, value.1); | 388 | assert_eq!(PathInfo::parse_location(value.0, &config)?, value.1); |
386 | println!("\x1B[FTesting {value:?} ✓"); | 389 | println!("\x1B[FTesting {value:?} ✓"); |
387 | } | 390 | } |
388 | Ok(()) | 391 | Ok(()) |
389 | } | 392 | } |
390 | 393 | ||
391 | #[test] | 394 | #[test] |
392 | fn compare_to_last_modified() -> color_eyre::Result<()> { | 395 | fn compare_to_last_modified() -> Result<()> { |
393 | let mut config = Config::default(); | 396 | let mut config = Config { root: "./backup-test".to_string(), ..Default::default() }; |
394 | config.root = "./backup-test".to_string(); | ||
395 | config | 397 | config |
396 | .directories | 398 | .directories |
397 | .push("u:fx/code/proj/arbs/backup-test-dir".to_string()); | 399 | .push("u:fx/code/proj/arbs/backup-test-dir".to_string()); |
@@ -404,7 +406,7 @@ mod tests { | |||
404 | let mut f = File::create("./backup-test-dir/nothing.txt")?; | 406 | let mut f = File::create("./backup-test-dir/nothing.txt")?; |
405 | f.write_all("unmodified".as_bytes())?; | 407 | f.write_all("unmodified".as_bytes())?; |
406 | 408 | ||
407 | let backup = Backup::create(&config, None)?; | 409 | let backup = Backup::create(&config)?; |
408 | backup.save(&config)?; | 410 | backup.save(&config)?; |
409 | 411 | ||
410 | let mut f = File::create("./backup-test-dir/size.txt")?; | 412 | let mut f = File::create("./backup-test-dir/size.txt")?; |