Skip to content

Commit 8da77af

Browse files
authored
Fix tool-cache path issue (#42)
In a previous refactor, foreman paths we changed and the tool cache file usage was missed. This fixes the issue and add unit tests to pin the behavior.
1 parent 7a037d9 commit 8da77af

File tree

2 files changed

+161
-16
lines changed

2 files changed

+161
-16
lines changed

src/paths.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ impl ForemanPaths {
4848
self.root_dir.clone()
4949
}
5050

51-
pub fn from_root<P: AsRef<Path>>(&self, path: P) -> PathBuf {
51+
fn from_root<P: AsRef<Path>>(&self, path: P) -> PathBuf {
5252
let mut dir = self.root_dir();
5353
dir.push(path);
5454
dir
@@ -71,7 +71,7 @@ impl ForemanPaths {
7171
}
7272

7373
pub fn index_file(&self) -> PathBuf {
74-
self.from_root("tool-cache.toml")
74+
self.from_root("tool-cache.json")
7575
}
7676

7777
pub fn create_all(&self) -> Result<(), ForemanError> {
@@ -96,3 +96,61 @@ impl Default for ForemanPaths {
9696
Self::new(root_dir)
9797
}
9898
}
99+
100+
#[cfg(test)]
101+
mod test {
102+
use super::*;
103+
104+
#[test]
105+
fn root_dir() {
106+
let root = PathBuf::from("/foreman");
107+
let paths = ForemanPaths::new(root.clone());
108+
109+
assert_eq!(paths.root_dir(), root);
110+
}
111+
112+
#[test]
113+
fn tools_dir() {
114+
let mut directory = PathBuf::from("/foreman");
115+
let paths = ForemanPaths::new(directory.clone());
116+
directory.push("tools");
117+
118+
assert_eq!(directory, paths.tools_dir());
119+
}
120+
121+
#[test]
122+
fn bin_dir() {
123+
let mut directory = PathBuf::from("/foreman");
124+
let paths = ForemanPaths::new(directory.clone());
125+
directory.push("bin");
126+
127+
assert_eq!(directory, paths.bin_dir());
128+
}
129+
130+
#[test]
131+
fn auth_store() {
132+
let mut directory = PathBuf::from("/foreman");
133+
let paths = ForemanPaths::new(directory.clone());
134+
directory.push("auth.toml");
135+
136+
assert_eq!(directory, paths.auth_store());
137+
}
138+
139+
#[test]
140+
fn user_config() {
141+
let mut directory = PathBuf::from("/foreman");
142+
let paths = ForemanPaths::new(directory.clone());
143+
directory.push("foreman.toml");
144+
145+
assert_eq!(directory, paths.user_config());
146+
}
147+
148+
#[test]
149+
fn index_file() {
150+
let mut directory = PathBuf::from("/foreman");
151+
let paths = ForemanPaths::new(directory.clone());
152+
directory.push("tool-cache.json");
153+
154+
assert_eq!(directory, paths.index_file());
155+
}
156+
}

src/tool_cache.rs

Lines changed: 101 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,21 @@ use crate::{
2222
};
2323

2424
/// Contains the current state of all of the tools that Foreman manages.
25-
#[derive(Debug, Default, Serialize, Deserialize)]
25+
#[derive(Debug, PartialEq, Serialize, Deserialize)]
2626
pub struct ToolCache {
2727
pub tools: HashMap<CiString, ToolEntry>,
2828
#[serde(skip)]
2929
paths: ForemanPaths,
3030
}
3131

3232
impl ToolCache {
33+
pub fn new(paths: &ForemanPaths) -> Self {
34+
Self {
35+
tools: Default::default(),
36+
paths: paths.clone(),
37+
}
38+
}
39+
3340
pub fn run(&self, tool: &ToolSpec, version: &Version, args: Vec<String>) -> ForemanResult<i32> {
3441
let tool_path = self.get_tool_exe_path(tool, version);
3542

@@ -173,13 +180,15 @@ impl ToolCache {
173180
}
174181

175182
pub fn load(paths: &ForemanPaths) -> ForemanResult<Self> {
176-
let mut tool_cache = fs::try_read(paths.index_file())?
183+
let path = paths.index_file();
184+
log::debug!("load tool cache from {}", path.display());
185+
186+
let mut tool_cache = fs::try_read(&path)?
177187
.map(|contents| {
178-
serde_json::from_slice(&contents).map_err(|err| {
179-
ForemanError::tool_cache_parsing(paths.index_file(), err.to_string())
180-
})
188+
serde_json::from_slice(&contents)
189+
.map_err(|err| ForemanError::tool_cache_parsing(&path, err.to_string()))
181190
})
182-
.unwrap_or_else(|| Ok(Self::default()))?;
191+
.unwrap_or_else(|| Ok(Self::new(paths)))?;
183192

184193
tool_cache.paths = paths.clone();
185194
Ok(tool_cache)
@@ -188,7 +197,7 @@ impl ToolCache {
188197
fn save(&self) -> ForemanResult<()> {
189198
let serialized =
190199
serde_json::to_string_pretty(self).expect("unable to serialize tool cache");
191-
fs::write(self.index_file(), serialized)
200+
fs::write(self.paths.index_file(), serialized)
192201
}
193202

194203
fn get_tool_exe_path(&self, tool: &ToolSpec, version: &Version) -> PathBuf {
@@ -197,15 +206,9 @@ impl ToolCache {
197206
tool_path.push(exe_name);
198207
tool_path
199208
}
200-
201-
fn index_file(&self) -> PathBuf {
202-
let mut path = self.paths.root_dir();
203-
path.push("tool-cache.json");
204-
path
205-
}
206209
}
207210

208-
#[derive(Debug, Default, Serialize, Deserialize)]
211+
#[derive(Debug, Default, PartialEq, Serialize, Deserialize)]
209212
pub struct ToolEntry {
210213
pub versions: BTreeSet<Version>,
211214
}
@@ -215,3 +218,87 @@ fn tool_identifier_to_exe_name(tool: &ToolSpec, version: &Version) -> String {
215218
name = name.replace('/', "__");
216219
name.replace('\\', "__")
217220
}
221+
222+
#[cfg(test)]
223+
mod test {
224+
use tempfile::tempdir;
225+
226+
use super::*;
227+
228+
mod load {
229+
use super::*;
230+
231+
#[test]
232+
fn use_default_when_tool_cache_file_does_not_exist() {
233+
let foreman_root = tempdir().expect("unable to create temporary directory");
234+
let paths = ForemanPaths::new(foreman_root.into_path());
235+
236+
let cache = ToolCache::load(&paths).unwrap();
237+
238+
assert_eq!(cache, ToolCache::new(&paths));
239+
}
240+
241+
#[test]
242+
fn reads_the_content_from_the_cache_file() {
243+
let foreman_root = tempdir().expect("unable to create temporary directory");
244+
let paths = ForemanPaths::new(foreman_root.into_path());
245+
246+
fs::write(
247+
paths.index_file(),
248+
r#"
249+
{
250+
"tools": {
251+
"username/toolname": {
252+
"versions": [
253+
"0.1.0"
254+
]
255+
}
256+
}
257+
}
258+
"#,
259+
)
260+
.unwrap();
261+
262+
let cache = ToolCache::load(&paths).unwrap();
263+
264+
let mut expected_cache = ToolCache::new(&paths);
265+
266+
expected_cache.tools.insert(
267+
"username/toolname".into(),
268+
ToolEntry {
269+
versions: {
270+
let mut tree = BTreeSet::new();
271+
tree.insert(Version::parse("0.1.0").unwrap());
272+
tree
273+
},
274+
},
275+
);
276+
277+
assert_eq!(cache, expected_cache);
278+
}
279+
}
280+
281+
mod save {
282+
use super::*;
283+
284+
#[test]
285+
fn snapshot_default_tool_cache() {
286+
let foreman_root = tempdir().expect("unable to create temporary directory");
287+
let paths = ForemanPaths::new(foreman_root.into_path());
288+
289+
let cache = ToolCache::new(&paths);
290+
291+
cache.save().unwrap();
292+
293+
let content = fs::try_read_to_string(paths.index_file())
294+
.unwrap()
295+
.expect("unable to find tool cache file");
296+
297+
insta::assert_snapshot!(&content, @r###"
298+
{
299+
"tools": {}
300+
}
301+
"###);
302+
}
303+
}
304+
}

0 commit comments

Comments
 (0)