1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// This is free and unencumbered software released into the public domain.
pub mod crates;
pub mod http;
pub mod pypi;
pub mod rubygems;
use crate::{
SysexitsError::{self},
registry,
};
use asimov_env::{
env::Env,
envs::{PythonEnv, RubyEnv},
};
use derive_more::Display;
#[derive(Clone, Debug)]
pub struct ModuleMetadata {
pub name: String,
pub version: String,
pub r#type: ModuleType,
pub url: String,
}
impl ModuleMetadata {
pub fn is_installed(&self) -> std::io::Result<bool> {
match self.r#type {
ModuleType::Rust => {
let command_name = format!("{}-module", self.name); // FIXME
Ok(clientele::SubcommandsProvider::find("asimov-", &command_name).is_some())
},
ModuleType::Ruby => RubyEnv::default().is_module_installed(&self.name),
ModuleType::Python => PythonEnv::default().is_module_installed(&self.name),
}
}
}
#[derive(Clone, Display, Debug)]
pub enum ModuleType {
#[display("rust")]
Rust,
#[display("ruby")]
Ruby,
#[display("python")]
Python,
}
impl ModuleType {
pub fn origin(&self) -> &'static str {
use ModuleType::*;
match self {
Rust => "Cargo",
Ruby => "RubyGems",
Python => "PyPI",
}
}
}
pub fn is_enabled(_module_name: &str) -> bool {
true // TODO
}
pub async fn fetch_module(module_name: &str) -> Option<ModuleMetadata> {
let modules = registry::fetch_modules().await.ok()?;
modules.into_iter().find(|m| m.name == module_name)
}
pub async fn fetch_modules() -> Result<Vec<ModuleMetadata>, SysexitsError> {
// Disable registry modules temporarily.
Ok(Vec::new())
// // Spawn tasks to fetch module package metadata:
// let rust_task = task::spawn(async {
// let result = registry::crates::fetch_current_modules()
// .await
// .map_err(|e| {
// tracing::error!("failed to fetch Rust module metadata: {e}");
// EX_UNAVAILABLE
// })?;
// registry::crates::extract_module_names(result).map_err(|e| {
// tracing::error!("failed to parse Rust module metadata: {e}");
// EX_DATAERR
// })
// });
// let ruby_task = task::spawn(async {
// let result = registry::rubygems::fetch_current_modules()
// .await
// .map_err(|e| {
// tracing::error!("failed to fetch Ruby module metadata: {e}");
// EX_UNAVAILABLE
// })?;
// registry::rubygems::extract_module_names(result).map_err(|e| {
// tracing::error!("failed to parse Ruby module metadata: {e}");
// EX_DATAERR
// })
// });
// let python_task = task::spawn(async {
// let result = registry::pypi::fetch_current_modules().await.map_err(|e| {
// tracing::error!("failed to fetch Python module metadata: {e}");
// EX_UNAVAILABLE
// })?;
// registry::pypi::extract_module_names(result).map_err(|e| {
// tracing::error!("failed to parse Python module metadata: {e}");
// EX_DATAERR
// })
// });
// // Await all tasks; note the double ?? to handle both `JoinError` and the
// // `Result` from the task:
// let rust_modules = rust_task.await.map_err(|e| {
// tracing::error!("failed to join Rust module task: {e}");
// EX_SOFTWARE
// })??;
// let ruby_modules = ruby_task.await.map_err(|e| {
// tracing::error!("failed to join Ruby module task: {e}");
// EX_SOFTWARE
// })??;
// let python_modules = python_task.await.map_err(|e| {
// tracing::error!("failed to join Python module task: {e}");
// EX_SOFTWARE
// })??;
// let mut all_modules: Vec<ModuleMetadata> = rust_modules
// .iter()
// .chain(ruby_modules.iter())
// .chain(python_modules.iter())
// .cloned()
// .collect();
// all_modules.sort_by_key(|m| m.name.clone());
// Ok(all_modules)
}