Some basic capabilities with a bungled trait implementation

I would like these traits to make this more dynamic or compact, but I don't have
the time to get it right today
This commit is contained in:
R Tyler Croy 2023-01-28 16:35:28 -08:00
parent 5494a54483
commit ed96899c6c
No known key found for this signature in database
GPG Key ID: E5C92681BEF6CEA2
2 changed files with 110 additions and 1 deletions

96
src/agent/caps.rs Normal file
View File

@ -0,0 +1,96 @@
use std::collections::HashMap;
use std::path::PathBuf;
use serde::Serialize;
/*
* The Capability trait defines the interface for determining
* whether the given agent's execution environment has a capability
* or not
*/
pub trait Capability {
fn has_capability() -> Option<Self>
where
Self: Sized + Serialize,
{
match locate_on_path(&Self::binary_name()) {
Some(pathbuf) => Self::from(pathbuf),
None => None,
}
}
fn binary_name() -> String
where
Self: Sized;
fn from(pathbuf: PathBuf) -> Option<Self>
where
Self: Sized;
}
/*
* Locate a binary given the name on the search path
*/
fn locate_on_path(bin: &str) -> Option<PathBuf> {
if let Ok(path) = std::env::var("PATH") {
for path_dir in std::env::split_paths(&path) {
let full_path = path_dir.join(bin);
if full_path.is_file() {
// TODO: Should check to see if the path is executable
return Some(PathBuf::from(full_path));
}
}
}
None
}
/*
* Git capability will determine whether `git` exists on the system
*/
#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "name")]
pub struct Git {
path: PathBuf,
data: Option<HashMap<String, String>>,
}
impl Capability for Git {
fn binary_name() -> String {
"git".into()
}
fn from(pb: PathBuf) -> Option<Self> {
Some(Self {
path: pb,
data: None,
})
}
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "name")]
pub struct Cargo {
path: PathBuf,
data: Option<HashMap<String, String>>,
}
impl Capability for Cargo {
fn binary_name() -> String {
"cargo".into()
}
fn from(pb: PathBuf) -> Option<Self> {
Some(Self {
path: pb,
data: None,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_has_git_capability() {
let cap = Git::has_capability();
assert!(cap.is_some(), "Somehow this machine doesn't have Git?");
}
}

View File

@ -1,6 +1,11 @@
#[macro_use]
extern crate serde_json;
use dotenv::dotenv;
use log::*;
mod caps;
mod routes {
use tide::{Body, Request};
@ -12,6 +17,7 @@ mod routes {
}
pub mod api {
use crate::caps::*;
use tide::{Body, Request};
pub fn register(app: &mut tide::Server<()>) {
@ -19,7 +25,14 @@ mod routes {
}
pub async fn get_caps(_req: Request<()>) -> Result<Body, tide::Error> {
Ok("{}".into())
let response = json!({
"caps" : [
Git::has_capability(),
Cargo::has_capability(),
],
});
Ok(response.into())
}
}
}