Skip to main content

resolve_tool/
resolve_tool.rs

1//! Resolve a caller-selected local executable without executing or admitting it.
2
3#[cfg(unix)]
4#[expect(
5    clippy::unnecessary_debug_formatting,
6    reason = "literal path bytes must stay escaped rather than become terminal control characters"
7)]
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9    use ic_host_tools::tool::resolve_executable;
10    use std::{io, path::PathBuf};
11
12    let mut args = std::env::args_os().skip(1);
13    let mut required = || {
14        args.next().map(PathBuf::from).ok_or_else(|| {
15            io::Error::new(
16                io::ErrorKind::InvalidInput,
17                "usage: resolve_tool REQUEST ABSOLUTE_WORKDIR [SEARCH_DIRECTORY ...]",
18            )
19        })
20    };
21    let requested = required()?;
22    let current_dir = required()?;
23    let directories = args.map(PathBuf::from).collect::<Vec<_>>();
24    let selected = resolve_executable(&requested, &current_dir, &directories)?;
25    // Debug quoting preserves non-UTF-8 paths and prevents control characters
26    // from becoming additional terminal lines. This example intentionally prints
27    // the selected path, not a trust or executable identity claim.
28    println!("candidate={:?}", selected.as_os_str());
29    Ok(())
30}
31
32#[cfg(not(unix))]
33fn main() -> Result<(), Box<dyn std::error::Error>> {
34    Err(std::io::Error::new(
35        std::io::ErrorKind::Unsupported,
36        "tool resolution requires a Unix host",
37    )
38    .into())
39}