Skip to main content

dfx_core/extension/manager/
mod.rs

1use crate::config::cache::get_cache_path_for_version;
2use crate::error::extension::{
3    GetExtensionBinaryError, LoadExtensionManifestsError, NewExtensionManagerError,
4};
5use crate::extension::{installed::InstalledExtensionManifests, manifest::ExtensionManifest};
6pub use install::InstallOutcome;
7use semver::Version;
8use std::collections::HashMap;
9use std::path::PathBuf;
10
11mod execute;
12mod install;
13mod list;
14mod uninstall;
15
16pub struct ExtensionManager {
17    pub dir: PathBuf,
18    pub dfx_version: Version,
19}
20
21impl ExtensionManager {
22    pub fn new(version: &Version) -> Result<Self, NewExtensionManagerError> {
23        let extensions_dir = get_cache_path_for_version(&version.to_string())?.join("extensions");
24
25        Ok(Self {
26            dir: extensions_dir,
27            dfx_version: version.clone(),
28        })
29    }
30
31    pub fn get_extension_directory(&self, extension_name: &str) -> PathBuf {
32        self.dir.join(extension_name)
33    }
34
35    pub fn get_extension_binary(
36        &self,
37        extension_name: &str,
38    ) -> Result<std::process::Command, GetExtensionBinaryError> {
39        let dir = self.get_extension_directory(extension_name);
40        if !dir.exists() {
41            return Err(GetExtensionBinaryError::ExtensionNotInstalled(
42                extension_name.to_string(),
43            ));
44        }
45        let bin = dir.join(extension_name);
46        if !bin.exists() {
47            Err(GetExtensionBinaryError::ExtensionBinaryDoesNotExist(bin))
48        } else if !bin.is_file() {
49            Err(GetExtensionBinaryError::ExtensionBinaryIsNotAFile(bin))
50        } else {
51            Ok(std::process::Command::new(bin))
52        }
53    }
54
55    pub fn is_extension_installed(&self, extension_name: &str) -> bool {
56        self.get_extension_directory(extension_name).exists()
57    }
58
59    pub fn load_installed_extension_manifests(
60        &self,
61    ) -> Result<InstalledExtensionManifests, LoadExtensionManifestsError> {
62        let manifests = self
63            .list_installed_extensions()?
64            .into_iter()
65            .map(|name| {
66                ExtensionManifest::load(&name, &self.dir)
67                    .map(|manifest| (manifest.name.clone(), manifest))
68            })
69            .collect::<Result<HashMap<_, _>, _>>()?;
70        Ok(InstalledExtensionManifests(manifests))
71    }
72}