1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
mod git;
use std::fs::{create_dir_all, remove_file, write, File};
use std::io::{Error, ErrorKind::Other, Read, Result};
use std::path::Path;
use git::Git;
pub trait Remote {
fn can_handle(&self, remote: &str) -> bool;
fn sync_up(&self, remote: &str, directory: &Path) -> Result<()>;
fn sync_down(&self, remote: &str, directory: &Path) -> Result<()>;
}
pub fn add(config_directory: &Path, remote_config: &Path, remote: &str) -> Result<()> {
create_dir_all(config_directory)?;
write(remote_config, remote)?;
Ok(())
}
pub fn remove(remote_config: &Path) -> Result<()> {
if remote_config.exists() {
remove_file(remote_config)?;
}
Ok(())
}
pub fn sync_up(data_directory: &Path, remote_config: &Path) -> Result<()> {
let remote_address =
read_remote(remote_config).ok_or_else(|| Error::new(Other, "No remote is configured"))?;
create_dir_all(data_directory)?;
let remotes = available_remotes();
for remote in remotes {
if remote.can_handle(&remote_address) {
return remote.sync_up(&remote_address, data_directory);
}
}
Err(Error::new(
Other,
"No valid strategies found for your configured remote.",
))
}
pub fn sync_down(data_directory: &Path, remote_config: &Path) -> Result<()> {
let remote_address =
read_remote(remote_config).ok_or_else(|| Error::new(Other, "No remote is configured"))?;
create_dir_all(data_directory)?;
let remotes = available_remotes();
for remote in remotes {
if remote.can_handle(&remote_address) {
return remote.sync_down(&remote_address, data_directory);
}
}
Err(Error::new(
Other,
"No valid strategies found for your configured remote.",
))
}
fn available_remotes() -> Vec<Box<dyn Remote>> {
vec![Box::new(Git::new())]
}
fn read_remote(file_path: &Path) -> Option<String> {
let mut file = File::open(file_path).ok()?;
let mut contents = String::new();
file.read_to_string(&mut contents).ok()?;
Some(contents)
}
#[cfg(test)]
mod tests {
use super::*;
use test_utilities::*;
#[test]
fn test_adds_a_remote() {
let test_dir = setup_test_dir();
let config_dir = test_dir.join("config");
let remote_config = config_dir.join("remoteconfig");
assert!(!&config_dir.exists());
add(&config_dir, &remote_config, "whaaat").expect("Could not add a remote");
assert!(&config_dir.exists());
assert_file_contents(&remote_config, "whaaat");
cleanup_test_dir(&test_dir);
}
#[test]
fn test_removes_a_remote() {
let test_dir = setup_test_dir();
let remote_config = test_dir.join("remoteconfig");
create_test_file(&remote_config, "remote control");
assert_file_contents(&remote_config, "remote control");
remove(&remote_config).expect("Could not remove a remote");
assert!(!&remote_config.exists());
cleanup_test_dir(&test_dir);
}
}
|