Skip to content

Commit 9aa911c

Browse files
committed
refactor: use lazy static for gpg and dotfile dir
1 parent 13d05dc commit 9aa911c

File tree

14 files changed

+147
-78
lines changed

14 files changed

+147
-78
lines changed

src/dots.rs

Lines changed: 43 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::gpg::Gpg;
21
use crate::paths::DotPaths;
32
use crate::settings::dots::{Dot, DotOverride};
43
use crate::templating::Variables;
@@ -8,14 +7,13 @@ use std::fs;
87
use std::fs::File;
98
use std::io::Write;
109
use std::path::{Path, PathBuf};
10+
use crate::settings::dotfile_dir;
1111

1212
impl Dot {
13-
pub(crate) fn install<P: AsRef<Path>>(
13+
pub(crate) fn install(
1414
&self,
15-
dotfile_dir: P,
1615
vars: &Variables,
1716
auto_ignored: Vec<PathBuf>,
18-
gpg: Option<&Gpg>,
1917
) -> Result<()> {
2018
let source = &self.source()?;
2119
let copy_path = &self.build_copy_path();
@@ -26,8 +24,8 @@ impl Dot {
2624
// Add local vars to the global ones
2725
let mut vars = vars.clone();
2826

29-
if let Some(local_vars_path) = self.resolve_var_path(dotfile_dir.as_ref()) {
30-
let local_vars = Dot::load_local_vars(&local_vars_path, gpg);
27+
if let Some(local_vars_path) = self.resolve_var_path() {
28+
let local_vars = Dot::load_local_vars(&local_vars_path);
3129
vars.extend(local_vars);
3230
}
3331

@@ -38,8 +36,8 @@ impl Dot {
3836
self.traverse_and_copy(source, copy_path, ignored_paths.as_slice(), &vars)
3937
}
4038

41-
fn load_local_vars(source: &Path, gpg: Option<&Gpg>) -> Variables {
42-
Variables::from_toml(source, gpg).unwrap_or_else(|err| {
39+
fn load_local_vars(source: &Path) -> Variables {
40+
Variables::from_toml(source).unwrap_or_else(|err| {
4341
eprintln!("{}", err.to_string().yellow());
4442
Variables::default()
4543
})
@@ -105,7 +103,6 @@ impl Dot {
105103
impl DotOverride {
106104
pub(crate) fn resolve_var_path(
107105
&self,
108-
dotfile_dir: &Path,
109106
origin: Option<&PathBuf>,
110107
) -> Option<PathBuf> {
111108
let source = match (self.get_source(), origin) {
@@ -115,14 +112,12 @@ impl DotOverride {
115112
};
116113

117114
let vars = self.vars().unwrap_or_else(Dot::default_vars);
118-
self.resolve_from_source(dotfile_dir, source, &vars)
115+
self.resolve_from_source(source, &vars)
119116
}
120117
}
121118

122119
impl Dot {
123-
pub(crate) fn resolve_var_path(&self, dotfile_dir: &Path) -> Option<PathBuf> {
124-
self.resolve_from_source(dotfile_dir, &self.source, &self.vars)
125-
}
120+
126121
}
127122

128123
pub(crate) trait DotVar {
@@ -138,12 +133,11 @@ pub(crate) trait DotVar {
138133

139134
fn resolve_from_source(
140135
&self,
141-
dotfile_dir: &Path,
142136
source: &Path,
143137
path: &Path,
144138
) -> Option<PathBuf> {
145-
let relative_to_dot = dotfile_dir.join(source).join(path);
146-
let relative_to_dotfile_dir = dotfile_dir.join(path);
139+
let relative_to_dot = dotfile_dir().join(source).join(path);
140+
let relative_to_dotfile_dir = dotfile_dir().join(path);
147141
// FIXME : we should not try to look for path like this
148142
// Instead "../vars.toml" should be used
149143
if relative_to_dot.exists() {
@@ -154,17 +148,16 @@ pub(crate) trait DotVar {
154148
} else if relative_to_dotfile_dir.exists() && !self.is_default_var_path() {
155149
Some(relative_to_dotfile_dir)
156150
} else {
157-
self.vars_path_not_found(dotfile_dir, source, path)
151+
self.vars_path_not_found(source, path)
158152
}
159153
} else {
160154
// Warning is emitted only if the path is not "vars.toml"
161-
self.vars_path_not_found(dotfile_dir, source, path)
155+
self.vars_path_not_found(source, path)
162156
}
163157
}
164158

165159
fn vars_path_not_found(
166160
&self,
167-
dotfile_dir: &Path,
168161
source: &Path,
169162
path: &Path,
170163
) -> Option<PathBuf> {
@@ -176,7 +169,7 @@ pub(crate) trait DotVar {
176169
"was neither found in".yellow(),
177170
source,
178171
"nor in".yellow(),
179-
dotfile_dir
172+
dotfile_dir()
180173
);
181174
}
182175
None
@@ -269,77 +262,71 @@ mod tests {
269262
.is_equal_to(PathBuf::from("/etc/profile"));
270263
}
271264

272-
#[sealed_test(env = [("HOME", ".")])]
265+
#[sealed_test(files = ["tests/dotfiles_simple"], before = setup("dotfiles_simple"))]
273266
fn symlink_ok() -> Result<()> {
274267
// Arrange
275268
run_cmd!(
276-
mkdir .dots;
277-
echo "Hello Tom" > .dots/dot;
269+
mkdir dotfiles_simple/.dots;
270+
echo "Hello Tom" > dotfiles_simple/.dots/template.css;
278271
)?;
279272

280273
let dot = Dot {
281-
source: PathBuf::from("dot"),
282-
target: PathBuf::from("dot_target"),
274+
source: PathBuf::from("template.css"),
275+
target: PathBuf::from(".config/template.css"),
283276
ignore: vec![],
284277
vars: Dot::default_vars(),
285278
};
286279

280+
287281
// Act
288282
dot.symlink()?;
289-
run_cmd!(tree -a;)?;
290283

291284
// Assert
292-
let symlink = PathBuf::from("dot_target");
285+
let symlink = PathBuf::from(".config/template.css");
293286
assert_that!(symlink.is_symlink()).is_true();
294287
assert_that!(fs::read_to_string(symlink)?).is_equal_to(&"Hello Tom\n".to_string());
295288

296289
Ok(())
297290
}
298291

299-
#[sealed_test(env = [("HOME", ".")])]
292+
#[sealed_test(files = ["tests/dotfiles_with_multiple_nested_dir"], before = setup("dotfiles_with_multiple_nested_dir"))]
300293
fn copy() -> Result<()> {
301294
// Arrange
302-
run_cmd!(
303-
mkdir -p dir/subdir_one;
304-
mkdir -p dir/subdir_two;
305-
mkdir .dots;
306-
echo "Hello From subdir 1" > dir/subdir_one/subfile;
307-
echo "Hello From subdir 2" > dir/subdir_two/subfile;
308-
)?;
309-
310295
let dot = Dot {
311296
source: PathBuf::from("dir"),
312-
target: PathBuf::from("."),
297+
target: PathBuf::from(".config/dir"),
313298
ignore: vec![],
314299
vars: Dot::default_vars(),
315300
};
316301

317302
// Act
318303
dot.traverse_and_copy(
319-
PathBuf::from("dir").canonicalize()?.as_path(),
320-
PathBuf::from(".dots/dir").as_path(),
304+
PathBuf::from("dotfiles_with_multiple_nested_dir/dir").as_path(),
305+
PathBuf::from("dotfiles_with_multiple_nested_dir/.dots/dir").as_path(),
321306
&vec![],
322307
&Variables::default(),
323308
)?;
324309

310+
run_cmd!(tree -a)?;
311+
312+
313+
325314
// Assert
326-
let file_one = PathBuf::from(".dots/dir/subdir_one/subfile");
327-
let file_two = PathBuf::from(".dots/dir/subdir_two/subfile");
315+
let file_one = PathBuf::from("dotfiles_with_multiple_nested_dir/.dots/dir/subdir_one/subfile");
316+
let file_two = PathBuf::from("dotfiles_with_multiple_nested_dir/.dots/dir/subdir_two/subfile");
328317
assert_that!(file_one).exists();
329318
assert_that!(file_two).exists();
330319
assert_that!(fs::read_to_string(file_one)?)
331-
.is_equal_to(&"Hello From subdir 1\n".to_string());
320+
.is_equal_to(&"Hello From subdir 1".to_string());
332321
assert_that!(fs::read_to_string(file_two)?)
333-
.is_equal_to(&"Hello From subdir 2\n".to_string());
322+
.is_equal_to(&"Hello From subdir 2".to_string());
334323
Ok(())
335324
}
336325

337-
#[sealed_test(files = ["tests/dotfiles_non_utf8/ferris.png"],env = [("HOME", ".")])]
326+
#[sealed_test(files = ["tests/dotfiles_non_utf8"], before = setup("dotfiles_non_utf8"))]
338327
fn copy_non_utf8() -> Result<()> {
339-
run_cmd!(tree -a;)?;
340-
341-
let source = PathBuf::from("ferris.png");
342-
let target = PathBuf::from("ferris.png");
328+
let source = PathBuf::from("dotfiles_non_utf8/ferris.png");
329+
let target = PathBuf::from("dotfiles_non_utf8/.config/ferris.png");
343330

344331
let dot = Dot {
345332
source: source.clone(),
@@ -350,12 +337,14 @@ mod tests {
350337

351338
dot.traverse_and_copy(
352339
&source,
353-
PathBuf::from(".dots/ferris.png").as_path(),
340+
PathBuf::from("dotfiles_non_utf8/.dots/ferris.png").as_path(),
354341
&vec![],
355342
&Variables::default(),
356343
)?;
357344

358-
assert_that!(PathBuf::from(".dots/ferris.png")).exists();
345+
run_cmd!(tree -a)?;
346+
347+
assert_that!(PathBuf::from("dotfiles_non_utf8/.dots/ferris.png")).exists();
359348
Ok(())
360349
}
361350

@@ -451,7 +440,7 @@ mod tests {
451440
vars: Dot::default_vars(),
452441
};
453442

454-
dot.install(env::current_dir()?, &Variables::default(), vec![], None)?;
443+
dot.install(&Variables::default(), vec![])?;
455444

456445
assert_that!(PathBuf::from(".dots")).exists();
457446
assert_that!(PathBuf::from(".dots/source_dot")).exists();
@@ -476,7 +465,7 @@ mod tests {
476465
vars.insert("name", "Tom Bombadil");
477466

478467
// Act
479-
dot.install(env::current_dir()?, &vars, vec![], None)?;
468+
dot.install( &vars, vec![])?;
480469
let dot = PathBuf::from(".dots/dotfiles/dot");
481470

482471
// Assert
@@ -513,7 +502,7 @@ mod tests {
513502
vars: PathBuf::from("my_vars.toml"),
514503
};
515504

516-
dot.install(env::current_dir()?, &Variables::default(), vec![], None)?;
505+
dot.install(&Variables::default(), vec![])?;
517506

518507
let content = fs::read_to_string(".dots/dir/template")?;
519508
assert_that!(content).is_equal_to(&"Hello Tom\n".to_string());
@@ -544,7 +533,7 @@ mod tests {
544533
};
545534

546535
// Arrange
547-
dot.install(env::current_dir()?, &Variables::default(), vec![], None)?;
536+
dot.install( &Variables::default(), vec![])?;
548537

549538
// Assert
550539
let content = fs::read_to_string(PathBuf::from(

src/paths/error.rs renamed to src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::io;
22
use std::path::PathBuf;
33
use thiserror::Error;
44

5-
pub(super) type Result<T> = std::result::Result<T, Error>;
5+
pub(crate) type Result<T> = std::result::Result<T, Error>;
66

77
#[derive(Error, Debug)]
88
pub enum Error {

src/gpg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl Gpg {
2626
value: &str,
2727
var_file: &S,
2828
) -> Result<()> {
29-
let mut vars = Variables::from_toml(var_file.as_ref(), Some(self))?;
29+
let mut vars = Variables::from_toml(var_file.as_ref())?;
3030
let encrypted = self.encrypt(value)?;
3131
let encrypted = encrypted.replace(PGP_HEADER, "");
3232
let encrypted = encrypted.replace(PGP_FOOTER, "");

src/install/command.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pub enum InstallCommand {
2+
Render,
3+
Symlink,
4+
RenderAndSymlink,
5+
Ignore,
6+
}

src/install/dotfile.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use std::convert::TryFrom;
2+
use std::path::PathBuf;
3+
use crate::{Dot, DotPaths, Variables};
4+
use crate::error::*;
5+
6+
pub enum DotFile {
7+
Dir {
8+
// The directory source path
9+
source: PathBuf,
10+
// Symlink path
11+
target: PathBuf,
12+
// Dotfiles subdirectories and file
13+
children: Vec<DotFile>,
14+
// Local variables
15+
vars: Option<Variables>,
16+
},
17+
File {
18+
// The directory source path
19+
source: PathBuf,
20+
// Symlink path
21+
target: PathBuf,
22+
// Local variables
23+
vars: Option<Variables>,
24+
},
25+
}
26+
27+
impl TryFrom<Dot> for DotFile {
28+
type Error = crate::error::Error;
29+
30+
fn try_from(dot: Dot) -> Result<Self> {
31+
let source = dot.source()?;
32+
let target = dot.target()?;
33+
34+
let vars = dot
35+
.resolve_var_path()
36+
.and_then(|path| Variables::from_toml(path.as_path()).ok());
37+
38+
if source.is_dir() {
39+
Ok(DotFile::Dir {
40+
source,
41+
target,
42+
children: vec![],
43+
vars,
44+
})
45+
} else {
46+
Ok(DotFile::File {
47+
source,
48+
target,
49+
vars,
50+
})
51+
}
52+
}
53+
}

src/install/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod command;
2+
pub mod dotfile;

0 commit comments

Comments
 (0)