v0.2.2 : suggestions d'installation selon l'OS (scoop/winget/apt/dnf/pacman/apk/brew) + README remanie
This commit is contained in:
+49
-6
@@ -63,6 +63,7 @@ pub fn run(app: &App, runner: &dyn Runner) -> DoctorReport {
|
||||
("uv", false),
|
||||
("docker", false),
|
||||
];
|
||||
let os = crate::toolchain::OsInfo::detect();
|
||||
for (tool, required) in tools {
|
||||
match runner.which(tool) {
|
||||
Some(path) => {
|
||||
@@ -84,14 +85,20 @@ pub fn run(app: &App, runner: &dyn Runner) -> DoctorReport {
|
||||
});
|
||||
}
|
||||
None => {
|
||||
let (status, detail) = if *required {
|
||||
(
|
||||
Status::Error,
|
||||
"required but not found on PATH".to_string(),
|
||||
)
|
||||
let mut detail = if *required {
|
||||
"required but not found on PATH".to_string()
|
||||
} else {
|
||||
(Status::Ok, "not installed".to_string())
|
||||
"not installed".to_string()
|
||||
};
|
||||
let cmds = crate::toolchain::install_commands(tool, &os);
|
||||
if !cmds.is_empty() {
|
||||
detail.push_str(&format!(
|
||||
" — on {}: {}",
|
||||
os.name,
|
||||
cmds.join(" | ")
|
||||
));
|
||||
}
|
||||
let status = if *required { Status::Error } else { Status::Ok };
|
||||
checks.push(Check {
|
||||
name: tool.to_string(),
|
||||
status,
|
||||
@@ -199,6 +206,42 @@ fn is_on_path(dir: &std::path::Path) -> bool {
|
||||
})
|
||||
}
|
||||
|
||||
/// Offer to install the missing optional tools (node, python, ...) with
|
||||
/// the command detected for the current OS. Returns what was repaired.
|
||||
pub fn install_missing_tools(app: &App, runner: &dyn Runner) -> Result<Vec<String>> {
|
||||
let mut installed = Vec::new();
|
||||
let os = crate::toolchain::OsInfo::detect();
|
||||
for tool in ["node", "python", "cargo", "go", "bun", "uv", "docker"] {
|
||||
if runner.which(tool).is_some() {
|
||||
continue;
|
||||
}
|
||||
let cmds = crate::toolchain::install_commands(tool, &os);
|
||||
let Some(cmd) = cmds.first() else {
|
||||
continue;
|
||||
};
|
||||
if !app.confirm(&format!(
|
||||
"'{tool}' is missing — run the detected installer for {}? -> {cmd}",
|
||||
os.name
|
||||
))? {
|
||||
continue;
|
||||
}
|
||||
if let Ok(tokens) = shell_words::split(cmd) {
|
||||
if !tokens.is_empty() {
|
||||
let prog = tokens[0].clone();
|
||||
let args: Vec<String> = tokens[1..].to_vec();
|
||||
let empty = BTreeMap::new();
|
||||
let out = runner.run(&prog, &args, &empty, None, false)?;
|
||||
installed.push(if out.code == 0 {
|
||||
format!("installed '{tool}' ({cmd})")
|
||||
} else {
|
||||
format!("failed to install '{tool}' (exit code {})", out.code)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(installed)
|
||||
}
|
||||
|
||||
/// Repair what can be repaired: create directories, fix a corrupt state file.
|
||||
pub fn fix(app: &App) -> Result<Vec<String>> {
|
||||
let mut repaired = Vec::new();
|
||||
|
||||
Reference in New Issue
Block a user