1use std::fs;
2
3use crate::{App, CoreError, InstalledVersion};
4
5impl App {
6 pub fn list_installed_versions(&self) -> Result<Vec<InstalledVersion>, CoreError> {
8 let cache_root = self.home().join("cache");
9 if !cache_root.exists() {
10 return Ok(Vec::new());
11 }
12 let mut installed = Vec::new();
13
14 for plugin_entry in fs::read_dir(cache_root)? {
15 let plugin_entry = plugin_entry?;
16 if !plugin_entry.file_type()?.is_dir() {
17 continue;
18 }
19 let plugin_name = match plugin_entry.file_name().into_string() {
20 Ok(name) => name,
21 Err(_) => continue,
22 };
23 let versions_root = plugin_entry.path().join("versions");
24 if !versions_root.exists() {
25 continue;
26 }
27 for version_entry in fs::read_dir(&versions_root)? {
28 let version_entry = version_entry?;
29 if !version_entry.file_type()?.is_dir() {
30 continue;
31 }
32 if let Ok(version) = version_entry.file_name().into_string() {
33 installed.push(InstalledVersion {
34 plugin: plugin_name.clone(),
35 version,
36 install_dir: version_entry.path(),
37 });
38 }
39 }
40 }
41
42 installed.sort_by(|left, right| {
43 left.plugin
44 .cmp(&right.plugin)
45 .then(right.version.cmp(&left.version))
46 });
47 Ok(installed)
48 }
49}