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