Detect Pi from PATH inventory candidates
Prefer user and PATH candidates before system defaults, fall back to package.json discovery, and accept version output from stderr for shims. --- Build: pass — cargo build --release Tests: pass — cargo test (0 tests)
This commit is contained in:
parent
247ffc76a1
commit
6269030424
1 changed files with 54 additions and 13 deletions
|
|
@ -3,7 +3,7 @@
|
|||
//! Matches the TypeScript `clawdie.runtime-version-inventory.v1` schema in
|
||||
//! `clawdie-ai/src/colibri-runtime-inventory.ts`.
|
||||
|
||||
use std::{collections::BTreeMap, env, fs, process::Command};
|
||||
use std::{collections::BTreeMap, env, fs, path::Path, process::Command};
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
|
|
@ -38,6 +38,9 @@ fn command_candidates(program: &str) -> Vec<String> {
|
|||
candidates.push(format!("{home}/.npm-global/bin/{program}"));
|
||||
candidates.push(format!("{home}/.local/bin/{program}"));
|
||||
}
|
||||
if let Ok(path) = env::var("PATH") {
|
||||
candidates.extend(path.split(':').map(|dir| format!("{dir}/{program}")));
|
||||
}
|
||||
for dir in [
|
||||
"/usr/local/sbin",
|
||||
"/usr/local/bin",
|
||||
|
|
@ -48,9 +51,6 @@ fn command_candidates(program: &str) -> Vec<String> {
|
|||
] {
|
||||
candidates.push(format!("{dir}/{program}"));
|
||||
}
|
||||
if let Ok(path) = env::var("PATH") {
|
||||
candidates.extend(path.split(':').map(|dir| format!("{dir}/{program}")));
|
||||
}
|
||||
candidates.push(program.to_string());
|
||||
candidates
|
||||
}
|
||||
|
|
@ -64,7 +64,13 @@ fn command_output(program: &str, args: &[&str]) -> Option<String> {
|
|||
.output()
|
||||
.ok()
|
||||
.filter(|output| output.status.success())
|
||||
.and_then(|output| String::from_utf8(output.stdout).ok())
|
||||
.and_then(|output| {
|
||||
if !output.stdout.is_empty() {
|
||||
String::from_utf8(output.stdout).ok()
|
||||
} else {
|
||||
String::from_utf8(output.stderr).ok()
|
||||
}
|
||||
})
|
||||
.map(|value| value.trim().to_string())
|
||||
.filter(|value| !value.is_empty())
|
||||
})
|
||||
|
|
@ -93,26 +99,61 @@ fn command_exists(program: &str) -> bool {
|
|||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn package_json_version(path: impl AsRef<Path>) -> Option<String> {
|
||||
let raw = fs::read_to_string(path).ok()?;
|
||||
let parsed = serde_json::from_str::<serde_json::Value>(&raw).ok()?;
|
||||
parsed
|
||||
.get("version")
|
||||
.and_then(|value| value.as_str())
|
||||
.map(|value| value.to_string())
|
||||
}
|
||||
|
||||
fn pi_package_version_from_bin(candidate: &str) -> Option<String> {
|
||||
let canonical = fs::canonicalize(candidate).ok()?;
|
||||
for dir in canonical.ancestors() {
|
||||
let package_json = dir.join("package.json");
|
||||
if let Some(version) = package_json_version(package_json) {
|
||||
let dir_text = dir.to_string_lossy();
|
||||
if dir_text.contains("pi-coding-agent") {
|
||||
return Some(version);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn detect_pi_version() -> Option<String> {
|
||||
if let Ok(pi_bin) = env::var("PI_BIN") {
|
||||
if let Some(version) =
|
||||
command_output(&pi_bin, &["--version"]).or_else(|| pi_package_version_from_bin(&pi_bin))
|
||||
{
|
||||
return Some(version);
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(home) = env::var("HOME") {
|
||||
let pi_bin = format!("{home}/.npm-global/bin/pi");
|
||||
if let Some(version) = command_output(&pi_bin, &["--version"]) {
|
||||
if let Some(version) =
|
||||
command_output(&pi_bin, &["--version"]).or_else(|| pi_package_version_from_bin(&pi_bin))
|
||||
{
|
||||
return Some(version);
|
||||
}
|
||||
|
||||
let package_json = format!(
|
||||
"{home}/.npm-global/lib/node_modules/@earendil-works/pi-coding-agent/package.json"
|
||||
);
|
||||
if let Ok(raw) = fs::read_to_string(package_json) {
|
||||
if let Ok(parsed) = serde_json::from_str::<serde_json::Value>(&raw) {
|
||||
if let Some(version) = parsed.get("version").and_then(|value| value.as_str()) {
|
||||
return Some(version.to_string());
|
||||
}
|
||||
}
|
||||
if let Some(version) = package_json_version(package_json) {
|
||||
return Some(version);
|
||||
}
|
||||
}
|
||||
|
||||
command_output("pi", &["--version"])
|
||||
if let Some(version) = command_output("pi", &["--version"]) {
|
||||
return Some(version);
|
||||
}
|
||||
|
||||
command_candidates("pi")
|
||||
.into_iter()
|
||||
.find_map(|candidate| pi_package_version_from_bin(&candidate))
|
||||
}
|
||||
|
||||
fn detect_package_manager() -> Option<String> {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue