summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backup.rs17
-rw-r--r--src/cli.rs25
-rw-r--r--src/config.rs30
-rw-r--r--src/error.rs12
-rw-r--r--src/main.rs42
-rw-r--r--src/packages.rs85
-rw-r--r--src/packages/pacman.rs13
-rw-r--r--src/packages/portage.rs4
-rw-r--r--src/pathinfo.rs41
9 files changed, 208 insertions, 61 deletions
diff --git a/src/backup.rs b/src/backup.rs
index e463593..f9de139 100644
--- a/src/backup.rs
+++ b/src/backup.rs
@@ -12,7 +12,7 @@ use uuid::Uuid;
12use crate::{ 12use crate::{
13 config::Config, 13 config::Config,
14 error::{Error, Result}, 14 error::{Error, Result},
15 packages::Package, 15 packages::{Manager, PackageList},
16 pathinfo::PathInfo, 16 pathinfo::PathInfo,
17}; 17};
18 18
@@ -22,13 +22,13 @@ pub type Id = String;
22pub struct Backup { 22pub struct Backup {
23 pub id: String, 23 pub id: String,
24 pub timestamp: u64, 24 pub timestamp: u64,
25 packages: Vec<Package>, 25 pub packages: PackageList,
26 pub files: Vec<PathInfo>, 26 pub files: Vec<PathInfo>,
27 device: String, 27 pub device: String,
28} 28}
29 29
30impl Backup { 30impl Backup {
31 pub fn create(config: &Config, packages: Vec<Package>) -> Result<Self> { 31 pub fn create(config: &Config, manager: Option<Manager>) -> 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)?);
@@ -37,7 +37,7 @@ impl Backup {
37 // TODO: UUID not really needed, maybe a shorter hash 37 // TODO: UUID not really needed, maybe a shorter hash
38 id: Uuid::new_v4().to_string(), 38 id: Uuid::new_v4().to_string(),
39 timestamp: Self::get_timestamp(), 39 timestamp: Self::get_timestamp(),
40 packages, 40 packages: Manager::get_manager(manager)?.get_installed()?,
41 files, 41 files,
42 device: config.device.clone(), 42 device: config.device.clone(),
43 }) 43 })
@@ -62,6 +62,7 @@ impl Backup {
62 62
63 pub fn get_last(config: &Config) -> Result<Option<Self>> { 63 pub fn get_last(config: &Config) -> Result<Option<Self>> {
64 let backup_index_root = format!("{}/index.json", config.root); 64 let backup_index_root = format!("{}/index.json", config.root);
65 info!(?backup_index_root, "backup index location:");
65 let list: Vec<IndexEntry> = match Self::get_json_content(&backup_index_root) { 66 let list: Vec<IndexEntry> = match Self::get_json_content(&backup_index_root) {
66 Ok(list) => list, 67 Ok(list) => list,
67 Err(err) => { 68 Err(err) => {
@@ -72,6 +73,8 @@ impl Backup {
72 } 73 }
73 }; 74 };
74 75
76 info!(?list, "backup index:");
77
75 Ok(Some(Self::from_index( 78 Ok(Some(Self::from_index(
76 config, 79 config,
77 &list.last().ok_or(Error::BackupNotFound)?.id, 80 &list.last().ok_or(Error::BackupNotFound)?.id,
@@ -109,6 +112,10 @@ impl Backup {
109 format!("{loc}/{rel_location}") 112 format!("{loc}/{rel_location}")
110 } 113 }
111 114
115 pub fn restore(&self) {
116 todo!()
117 }
118
112 fn get_json_content<T: for<'a> Deserialize<'a>>(path: &str) -> Result<T> { 119 fn get_json_content<T: for<'a> Deserialize<'a>>(path: &str) -> Result<T> {
113 let mut file = File::open(path)?; 120 let mut file = File::open(path)?;
114 let mut content = String::new(); 121 let mut content = String::new();
diff --git a/src/cli.rs b/src/cli.rs
new file mode 100644
index 0000000..6ffe03f
--- /dev/null
+++ b/src/cli.rs
@@ -0,0 +1,25 @@
1use std::path::PathBuf;
2
3use clap::{Parser, Subcommand};
4
5use crate::packages::Manager;
6
7#[derive(Parser)]
8pub struct Cli {
9 #[arg(short, long)]
10 pub config: Option<PathBuf>,
11
12 #[command(subcommand)]
13 pub subcommand: Subcommands,
14}
15
16#[derive(Subcommand)]
17pub enum Subcommands {
18 GenerateConfig,
19 Save {
20 #[arg(short, long)]
21 package_manager: Option<Manager>,
22 },
23 Restore,
24}
25
diff --git a/src/config.rs b/src/config.rs
index 13dd0e4..46d2204 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,3 +1,5 @@
1use std::{fs::create_dir_all, io::Write, path::PathBuf};
2
1use config::{File, Map}; 3use config::{File, Map};
2use serde::{Deserialize, Serialize}; 4use serde::{Deserialize, Serialize};
3use tracing::{debug, trace}; 5use tracing::{debug, trace};
@@ -6,7 +8,6 @@ use tracing::{debug, trace};
6#[serde(default)] 8#[serde(default)]
7pub struct Config { 9pub struct Config {
8 pub root: String, 10 pub root: String,
9 pub user: Vec<String>,
10 pub directories: Vec<String>, 11 pub directories: Vec<String>,
11 pub custom_directories: Map<String, String>, 12 pub custom_directories: Map<String, String>,
12 pub device: String, 13 pub device: String,
@@ -16,7 +17,6 @@ impl Default for Config {
16 fn default() -> Self { 17 fn default() -> Self {
17 Self { 18 Self {
18 root: "/mnt/backup".to_string(), 19 root: "/mnt/backup".to_string(),
19 user: vec![],
20 directories: vec![], 20 directories: vec![],
21 custom_directories: Map::new(), 21 custom_directories: Map::new(),
22 device: gethostname::gethostname() 22 device: gethostname::gethostname()
@@ -27,10 +27,16 @@ impl Default for Config {
27} 27}
28 28
29impl Config { 29impl Config {
30 pub fn load() -> Result<Self, config::ConfigError> { 30 pub fn load(path: Option<PathBuf>) -> core::result::Result<Self, config::ConfigError> {
31 debug!("load config"); 31 debug!("load config");
32 let source = if let Some(source) = path {
33 source
34 } else {
35 Self::get_location()
36 };
37
32 let config = config::Config::builder() 38 let config = config::Config::builder()
33 .add_source(File::with_name("config.toml").required(false)) 39 .add_source(File::with_name(&source.to_string_lossy()).required(false))
34 .add_source(config::Environment::with_prefix("FXBAUP").separator("_")) 40 .add_source(config::Environment::with_prefix("FXBAUP").separator("_"))
35 .build()?; 41 .build()?;
36 42
@@ -39,4 +45,20 @@ impl Config {
39 45
40 cfg 46 cfg
41 } 47 }
48
49 pub fn generate() -> crate::error::Result<()> {
50 let loc = Self::get_location();
51 create_dir_all(loc.parent().unwrap())?;
52 let mut f = std::fs::File::create(loc)?;
53 f.write_all(toml::to_string(&Self::default())?.as_bytes())?;
54
55 Ok(())
56 }
57
58 fn get_location() -> PathBuf {
59 let mut conf_dir = dirs::config_local_dir().unwrap();
60 conf_dir.push("arbs");
61 conf_dir.push("config.toml");
62 conf_dir
63 }
42} 64}
diff --git a/src/error.rs b/src/error.rs
index 0cf4dca..e24c3b1 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -14,9 +14,6 @@ pub enum Error {
14 #[error("invalid directory '{0}'")] 14 #[error("invalid directory '{0}'")]
15 InvalidDirectory(String), 15 InvalidDirectory(String),
16 16
17 #[error("Only exactly one user allowed in config")]
18 MultiUser,
19
20 #[error("Requested backup not found")] 17 #[error("Requested backup not found")]
21 BackupNotFound, 18 BackupNotFound,
22 19
@@ -24,12 +21,21 @@ pub enum Error {
24 #[error("Unknown Package Manger Output")] 21 #[error("Unknown Package Manger Output")]
25 UnknownOutput, 22 UnknownOutput,
26 23
24 #[error("Unsupported os/distro")]
25 Unsupported,
26
27 #[error("json: {source}")] 27 #[error("json: {source}")]
28 SerdeJson { 28 SerdeJson {
29 #[from] 29 #[from]
30 source: serde_json::Error, 30 source: serde_json::Error,
31 }, 31 },
32 32
33 #[error("toml serializer: {source}")]
34 TomlSerialize {
35 #[from]
36 source: toml::ser::Error,
37 },
38
33 #[error("io: {source}")] 39 #[error("io: {source}")]
34 Io { 40 Io {
35 #[from] 41 #[from]
diff --git a/src/main.rs b/src/main.rs
index 1284e0c..7393af9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,10 +1,13 @@
1use backup::Backup; 1use backup::Backup;
2use clap::Parser;
3use cli::Subcommands;
2use config::Config; 4use config::Config;
3use packages::{pacman::Pacman, PackageManager}; 5use error::Error;
4use tracing::{debug, info, level_filters::LevelFilter}; 6use tracing::{debug, level_filters::LevelFilter};
5use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; 7use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
6 8
7mod backup; 9mod backup;
10mod cli;
8mod config; 11mod config;
9mod error; 12mod error;
10mod packages; 13mod packages;
@@ -13,7 +16,7 @@ mod pathinfo;
13fn main() -> color_eyre::Result<()> { 16fn main() -> color_eyre::Result<()> {
14 color_eyre::install()?; 17 color_eyre::install()?;
15 18
16 let file_appender = tracing_appender::rolling::never("./", "arps.log"); 19 let file_appender = tracing_appender::rolling::never("./", "arbs.log");
17 let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender); 20 let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
18 21
19 tracing_subscriber::registry() 22 tracing_subscriber::registry()
@@ -33,19 +36,24 @@ fn main() -> color_eyre::Result<()> {
33 .init(); 36 .init();
34 debug!("logging initialized"); 37 debug!("logging initialized");
35 38
36 let mut cfg = Config::load()?; 39 let cli = cli::Cli::parse();
37 cfg.user.push("fx".to_string()); 40
38 cfg.directories.push("~/.config/nvim".to_string()); 41 let config = Config::load(cli.config)?;
39 cfg.root = "./backup".to_string(); 42
40 43 match cli.subcommand {
41 let pacman = Pacman; 44 Subcommands::GenerateConfig => Config::generate()?,
42 let pkgs = pacman.get_installed()?; 45 Subcommands::Save { package_manager } => {
43 let backup = Backup::create(&cfg, pkgs); 46 let backup = Backup::create(&config, package_manager)?;
44 // info!(?backup); 47 backup.save(&config)?;
45 // pacman.install(vec![Package { 48 }
46 // id: "lapce".to_string(), 49 Subcommands::Restore => {
47 // version: "0.4.2-1".to_string(), 50 let Some(last_backup) = Backup::get_last(&config)? else {
48 // explicit: true, 51 return Err(Error::BackupNotFound)?;
49 // }])?; 52 };
53
54 last_backup.packages.install()?;
55 last_backup.restore();
56 }
57 };
50 Ok(()) 58 Ok(())
51} 59}
diff --git a/src/packages.rs b/src/packages.rs
index 5ee5664..2eadcfc 100644
--- a/src/packages.rs
+++ b/src/packages.rs
@@ -1,19 +1,96 @@
1use std::{fs::File, io::Read};
2
3use pacman::Pacman;
4use portage::Portage;
1use serde::{Deserialize, Serialize}; 5use serde::{Deserialize, Serialize};
2 6
3use crate::error::Result; 7use crate::error::{Error, Result};
4 8
5pub mod pacman; 9#[cfg(feature = "pacman")]
6pub mod portage; 10mod pacman;
11#[cfg(feature = "portage")]
12mod portage;
7 13
8#[derive(Debug, Serialize, Deserialize)] 14#[derive(Debug, Serialize, Deserialize)]
15pub struct PackageList {
16 packages: Vec<Package>,
17 manager: Manager,
18}
19
20impl PackageList {
21 pub fn install(&self) -> Result<()> {
22 self.manager.to_package_manager().install(self.packages.clone())
23 }
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Package { 27pub struct Package {
10 pub id: String, 28 pub id: String,
11 pub version: String, 29 pub version: String,
12 pub explicit: bool, 30 pub explicit: bool,
13} 31}
14 32
33#[derive(Debug, Clone, clap::ValueEnum, Serialize, Deserialize)]
34pub enum Manager {
35 #[cfg(feature = "pacman")]
36 Pacman,
37 #[cfg(feature = "portage")]
38 Portage,
39}
40
41
42impl Manager {
43 pub fn get_manager(manager: Option<Manager>) -> Result<Box<dyn PackageManager>> {
44 #[cfg(not(target_os = "linux"))]
45 {
46 return Err(Error::Unsupported);
47 }
48
49 #[cfg(target_os = "linux")]
50 {
51 if let Some(man) = manager {
52 return Ok(man.to_package_manager());
53 }
54 let mut os_release = File::open("/etc/os-release")?;
55 let mut content = String::new();
56 os_release.read_to_string(&mut content)?;
57
58 let lines: Vec<&str> = content.split('\n').collect();
59 for line in lines {
60 let Some((key, value)) = line.split_once('=') else {
61 continue;
62 };
63 if key == "ID" {
64 return Self::from_str(value);
65 }
66 }
67 Err(Error::Unsupported)
68 }
69 }
70
71 fn from_str(value: &str) -> Result<Box<dyn PackageManager>> {
72 Ok(match value {
73 #[cfg(feature = "pacman")]
74 "arch" => Box::new(Pacman),
75 #[cfg(feature = "portage")]
76 "gentoo" => Box::new(Portage),
77 _ => return Err(Error::Unsupported),
78 })
79 }
80
81 fn to_package_manager(&self) -> Box<dyn PackageManager> {
82 match self {
83 #[cfg(feature = "pacman")]
84 Self::Pacman => Box::new(Pacman),
85 #[cfg(feature = "portage")]
86 Self::Portage => Box::new(Portage),
87 }
88 }
89}
90
91
15pub trait PackageManager { 92pub trait PackageManager {
16 fn get_installed(&self) -> Result<Vec<Package>>; 93 fn get_installed(&self) -> Result<PackageList>;
17 94
18 fn install(&self, pkgs: Vec<Package>) -> Result<()>; 95 fn install(&self, pkgs: Vec<Package>) -> Result<()>;
19} 96}
diff --git a/src/packages/pacman.rs b/src/packages/pacman.rs
index e10c6fb..0ad463b 100644
--- a/src/packages/pacman.rs
+++ b/src/packages/pacman.rs
@@ -1,13 +1,13 @@
1use std::process::{Command, Stdio}; 1use std::process::{Command, Stdio};
2 2
3use super::{Package, PackageManager}; 3use super::{Package, PackageList, PackageManager};
4 4
5use crate::error::{Error, Result}; 5use crate::error::{Error, Result};
6 6
7pub struct Pacman; 7pub struct Pacman;
8 8
9impl PackageManager for Pacman { 9impl PackageManager for Pacman {
10 fn get_installed(&self) -> Result<Vec<super::Package>> { 10 fn get_installed(&self) -> Result<PackageList> {
11 let pm_pkgs = Command::new("pacman").args(["-Q"]).output().unwrap(); 11 let pm_pkgs = Command::new("pacman").args(["-Q"]).output().unwrap();
12 let pm_e_pkgs = Command::new("pacman") 12 let pm_e_pkgs = Command::new("pacman")
13 .args(["-Q", "--explicit"]) 13 .args(["-Q", "--explicit"])
@@ -37,16 +37,19 @@ impl PackageManager for Pacman {
37 }); 37 });
38 } 38 }
39 39
40 Ok(pkgs) 40 Ok(PackageList {
41 packages: pkgs,
42 manager: super::Manager::Pacman,
43 })
41 } 44 }
42 45
43 fn install(&self, pkgs: Vec<super::Package>) -> Result<()> { 46 fn install(&self, pkgs: Vec<super::Package>) -> Result<()> {
44 let mut args = vec!["--noconfirm".to_string(), "-S".to_string()]; 47 let mut args = vec!["pacman".to_string(), "--noconfirm".to_string(), "-S".to_string()];
45 48
46 for pkg in pkgs { 49 for pkg in pkgs {
47 args.push(pkg.id); 50 args.push(pkg.id);
48 } 51 }
49 Command::new("pacman") 52 Command::new("doas")
50 .stdout(Stdio::inherit()) 53 .stdout(Stdio::inherit())
51 .args(args) 54 .args(args)
52 .spawn()? 55 .spawn()?
diff --git a/src/packages/portage.rs b/src/packages/portage.rs
index f9a760b..7fa09a8 100644
--- a/src/packages/portage.rs
+++ b/src/packages/portage.rs
@@ -1,11 +1,11 @@
1use tracing::error; 1use tracing::error;
2 2
3use super::PackageManager; 3use super::{PackageList, PackageManager};
4 4
5pub struct Portage; 5pub struct Portage;
6 6
7impl PackageManager for Portage { 7impl PackageManager for Portage {
8 fn get_installed(&self) -> crate::error::Result<Vec<super::Package>> { 8 fn get_installed(&self) -> crate::error::Result<PackageList> {
9 todo!() 9 todo!()
10 } 10 }
11 11
diff --git a/src/pathinfo.rs b/src/pathinfo.rs
index 8b1ca2f..03b8a6b 100644
--- a/src/pathinfo.rs
+++ b/src/pathinfo.rs
@@ -120,7 +120,8 @@ impl PathInfo {
120 let old_path = modified_backup.get_absolute_file_location(config, &last_file.rel_location); 120 let old_path = modified_backup.get_absolute_file_location(config, &last_file.rel_location);
121 let new_path = format!("{location_root}/{rel_location}"); 121 let new_path = format!("{location_root}/{rel_location}");
122 122
123 let mut old = File::open(old_path)?; let mut new = File::open(new_path)?; 123 let mut old = File::open(old_path)?;
124 let mut new = File::open(new_path)?;
124 125
125 let old_len = old.metadata()?.len(); 126 let old_len = old.metadata()?.len();
126 let new_len = new.metadata()?.len(); 127 let new_len = new.metadata()?.len();
@@ -195,12 +196,9 @@ impl PathInfo {
195 return Err(Error::InvalidDirectory(value.to_string())); 196 return Err(Error::InvalidDirectory(value.to_string()));
196 }; 197 };
197 if split.0.starts_with('~') { 198 if split.0.starts_with('~') {
198 if config.user.len() != 1 {
199 return Err(Error::MultiUser);
200 }
201 return Ok(( 199 return Ok((
202 split.1.to_string(), 200 split.1.to_string(),
203 LocationRoot::User(config.user[0].clone()), 201 LocationRoot::User,
204 )); 202 ));
205 }; 203 };
206 Ok(( 204 Ok((
@@ -212,18 +210,22 @@ impl PathInfo {
212 210
213#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] 211#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
214pub enum LocationRoot { 212pub enum LocationRoot {
215 User(String), 213 User,
216 Custom(String), 214 Custom(String),
217 SystemSettings, 215 SystemConfig,
216 UserConfig,
218 Root, 217 Root,
219} 218}
220 219
221impl Display for LocationRoot { 220impl Display for LocationRoot {
222 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 221 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223 match self { 222 match self {
224 LocationRoot::User(user) => write!(f, "/home/{user}"), 223 LocationRoot::User => write!(f, "{}", dirs::home_dir().unwrap().to_string_lossy()),
225 LocationRoot::Custom(loc) => write!(f, "{loc}"), 224 LocationRoot::Custom(loc) => write!(f, "{loc}"),
226 LocationRoot::SystemSettings => write!(f, "/etc"), 225 LocationRoot::SystemConfig => write!(f, "/etc"),
226 LocationRoot::UserConfig => {
227 write!(f, "{}", dirs::config_local_dir().unwrap().to_string_lossy())
228 }
227 LocationRoot::Root => write!(f, "/"), 229 LocationRoot::Root => write!(f, "/"),
228 } 230 }
229 } 231 }
@@ -236,8 +238,9 @@ impl LocationRoot {
236 return Err(Error::NoIndex); 238 return Err(Error::NoIndex);
237 }; 239 };
238 match split_op.0 { 240 match split_op.0 {
239 "u" => Ok(Self::User(split_op.1.to_string())), 241 "u" => Ok(Self::User),
240 "s" => Ok(Self::SystemSettings), 242 "s" => Ok(Self::SystemConfig),
243 "d" => Ok(Self::UserConfig),
241 "r" => Ok(Self::Root), 244 "r" => Ok(Self::Root),
242 "c" => Ok(Self::Custom( 245 "c" => Ok(Self::Custom(
243 config 246 config
@@ -262,7 +265,6 @@ mod tests {
262 backup::Backup, 265 backup::Backup,
263 config::Config, 266 config::Config,
264 error::{Error, Result}, 267 error::{Error, Result},
265 packages::{pacman::Pacman, PackageManager},
266 }; 268 };
267 269
268 use super::LocationRoot; 270 use super::LocationRoot;
@@ -276,8 +278,8 @@ mod tests {
276 .insert("test".to_string(), "/usr/local/test".to_string()); 278 .insert("test".to_string(), "/usr/local/test".to_string());
277 279
278 let mut values_ok: Vec<(&str, LocationRoot)> = Vec::new(); 280 let mut values_ok: Vec<(&str, LocationRoot)> = Vec::new();
279 values_ok.push(("u:test", LocationRoot::User("test".to_string()))); 281 values_ok.push(("u:test", LocationRoot::User));
280 values_ok.push(("s:", LocationRoot::SystemSettings)); 282 values_ok.push(("s:", LocationRoot::SystemConfig));
281 values_ok.push(("r:", LocationRoot::Root)); 283 values_ok.push(("r:", LocationRoot::Root));
282 values_ok.push(( 284 values_ok.push((
283 "c:test", 285 "c:test",
@@ -321,7 +323,6 @@ mod tests {
321 #[test] 323 #[test]
322 fn parse_location() -> Result<()> { 324 fn parse_location() -> Result<()> {
323 let mut config = Config::default(); 325 let mut config = Config::default();
324 config.user.push("test".to_string());
325 config 326 config
326 .custom_directories 327 .custom_directories
327 .insert("test".to_string(), "/usr/local/test".to_string()); 328 .insert("test".to_string(), "/usr/local/test".to_string());
@@ -331,14 +332,14 @@ mod tests {
331 "~/.config/nvim", 332 "~/.config/nvim",
332 ( 333 (
333 ".config/nvim".to_string(), 334 ".config/nvim".to_string(),
334 LocationRoot::User("test".to_string()), 335 LocationRoot::User,
335 ), 336 ),
336 )); 337 ));
337 values_ok.push(( 338 values_ok.push((
338 "u:test/.config/nvim", 339 "u:test/.config/nvim",
339 ( 340 (
340 ".config/nvim".to_string(), 341 ".config/nvim".to_string(),
341 LocationRoot::User("test".to_string()), 342 LocationRoot::User,
342 ), 343 ),
343 )); 344 ));
344 values_ok.push(( 345 values_ok.push((
@@ -351,7 +352,7 @@ mod tests {
351 )); 352 ));
352 values_ok.push(( 353 values_ok.push((
353 "s:/.config/nvim", 354 "s:/.config/nvim",
354 (".config/nvim".to_string(), LocationRoot::SystemSettings), 355 (".config/nvim".to_string(), LocationRoot::SystemConfig),
355 )); 356 ));
356 values_ok.push(( 357 values_ok.push((
357 "c:test/.config/nvim", 358 "c:test/.config/nvim",
@@ -385,9 +386,7 @@ mod tests {
385 let mut f = File::create("./backup-test-dir/nothing.txt")?; 386 let mut f = File::create("./backup-test-dir/nothing.txt")?;
386 f.write_all("unmodified".as_bytes())?; 387 f.write_all("unmodified".as_bytes())?;
387 388
388 let pacman = Pacman; 389 let backup = Backup::create(&config, None)?;
389 let pkgs = pacman.get_installed()?;
390 let backup = Backup::create(&config, pkgs)?;
391 backup.save(&config)?; 390 backup.save(&config)?;
392 391
393 let mut f = File::create("./backup-test-dir/size.txt")?; 392 let mut f = File::create("./backup-test-dir/size.txt")?;