Skip to content

Commit fbd2b89

Browse files
committed
chore: apply cargo fmt
1 parent 92b0218 commit fbd2b89

6 files changed

Lines changed: 162 additions & 105 deletions

File tree

src/agent.rs

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1+
use crate::cli::ForceOption;
2+
use crate::registry::{Agent, BinaryDist};
13
use std::path::PathBuf;
24
use std::process::Stdio;
35
use tokio::process::Command;
4-
use crate::cli::ForceOption;
5-
use crate::registry::{Agent, BinaryDist};
66
use tracing::{debug, info};
77

8-
pub async fn run_agent(agent: &Agent, cache_dir: &PathBuf, force: Option<&ForceOption>) -> Result<(), Box<dyn std::error::Error>> {
8+
pub async fn run_agent(
9+
agent: &Agent,
10+
cache_dir: &PathBuf,
11+
force: Option<&ForceOption>,
12+
) -> Result<(), Box<dyn std::error::Error>> {
913
debug!("Running agent: {}", agent.id);
10-
14+
1115
if let Some(npx) = &agent.distribution.npx {
1216
info!("Executing npx package: {}", npx.package);
1317
let mut cmd = Command::new("npx");
@@ -19,14 +23,18 @@ pub async fn run_agent(agent: &Agent, cache_dir: &PathBuf, force: Option<&ForceO
1923
};
2024
cmd.arg(package_arg);
2125
cmd.args(&npx.args);
22-
cmd.stdin(Stdio::inherit()).stdout(Stdio::inherit()).stderr(Stdio::inherit());
26+
cmd.stdin(Stdio::inherit())
27+
.stdout(Stdio::inherit())
28+
.stderr(Stdio::inherit());
2329
cmd.status().await?;
2430
} else if let Some(uvx) = &agent.distribution.uvx {
2531
info!("Executing uvx package: {}", uvx.package);
2632
let mut cmd = Command::new("uvx");
2733
cmd.arg(format!("{}@latest", uvx.package));
2834
cmd.args(&uvx.args);
29-
cmd.stdin(Stdio::inherit()).stdout(Stdio::inherit()).stderr(Stdio::inherit());
35+
cmd.stdin(Stdio::inherit())
36+
.stdout(Stdio::inherit())
37+
.stderr(Stdio::inherit());
3038
cmd.status().await?;
3139
} else if !agent.distribution.binary.is_empty() {
3240
let platform = get_platform();
@@ -36,7 +44,9 @@ pub async fn run_agent(agent: &Agent, cache_dir: &PathBuf, force: Option<&ForceO
3644
info!("Executing binary: {:?}", binary_path);
3745
let mut cmd = Command::new(&binary_path);
3846
cmd.args(&binary_dist.args);
39-
cmd.stdin(Stdio::inherit()).stdout(Stdio::inherit()).stderr(Stdio::inherit());
47+
cmd.stdin(Stdio::inherit())
48+
.stdout(Stdio::inherit())
49+
.stderr(Stdio::inherit());
4050
cmd.status().await?;
4151
} else {
4252
return Err(format!("No binary available for platform: {}", platform).into());
@@ -58,45 +68,52 @@ pub fn get_platform() -> String {
5868
("windows", "aarch64") => "windows-aarch64",
5969
("windows", "x86_64") => "windows-x86_64",
6070
_ => "unknown",
61-
}.to_string()
71+
}
72+
.to_string()
6273
}
6374

64-
pub async fn download_binary(agent: &Agent, binary_dist: &BinaryDist, cache_dir: &PathBuf, force: Option<&ForceOption>) -> Result<PathBuf, Box<dyn std::error::Error>> {
75+
pub async fn download_binary(
76+
agent: &Agent,
77+
binary_dist: &BinaryDist,
78+
cache_dir: &PathBuf,
79+
force: Option<&ForceOption>,
80+
) -> Result<PathBuf, Box<dyn std::error::Error>> {
6581
let agent_cache_dir = cache_dir.join(&agent.id);
6682
tokio::fs::create_dir_all(&agent_cache_dir).await?;
67-
83+
6884
let binary_name = binary_dist.cmd.trim_start_matches("./");
6985
let binary_path = agent_cache_dir.join(binary_name);
70-
86+
7187
let should_download = match force {
7288
Some(ForceOption::All | ForceOption::Binary) => {
7389
debug!("Force download requested for binary");
7490
true
75-
},
91+
}
7692
_ => {
7793
let exists = binary_path.exists();
7894
debug!("Binary exists at {:?}: {}", binary_path, exists);
7995
!exists
80-
},
96+
}
8197
};
82-
98+
8399
if should_download {
84100
info!("Downloading binary from: {}", binary_dist.archive);
85101
let response = reqwest::get(&binary_dist.archive).await?;
86102
let archive_data = response.bytes().await?;
87103
debug!("Downloaded {} bytes", archive_data.len());
88-
104+
89105
if binary_dist.archive.ends_with(".zip") {
90106
debug!("Extracting zip archive");
91107
extract_zip(&archive_data, &agent_cache_dir).await?;
92-
} else if binary_dist.archive.ends_with(".tar.gz") || binary_dist.archive.ends_with(".tgz") {
108+
} else if binary_dist.archive.ends_with(".tar.gz") || binary_dist.archive.ends_with(".tgz")
109+
{
93110
debug!("Extracting tar.gz archive");
94111
extract_tar_gz(&archive_data, &agent_cache_dir).await?;
95112
} else {
96113
debug!("Writing raw binary");
97114
tokio::fs::write(&binary_path, &archive_data).await?;
98115
}
99-
116+
100117
#[cfg(unix)]
101118
{
102119
use std::os::unix::fs::PermissionsExt;
@@ -105,27 +122,27 @@ pub async fn download_binary(agent: &Agent, binary_dist: &BinaryDist, cache_dir:
105122
tokio::fs::set_permissions(&binary_path, perms).await?;
106123
debug!("Set executable permissions on binary");
107124
}
108-
125+
109126
info!("Binary ready at: {:?}", binary_path);
110127
} else {
111128
debug!("Using cached binary: {:?}", binary_path);
112129
}
113-
130+
114131
Ok(binary_path)
115132
}
116133

117134
async fn extract_zip(data: &[u8], dest: &PathBuf) -> Result<(), Box<dyn std::error::Error>> {
118135
let data = data.to_vec();
119136
let dest = dest.clone();
120-
137+
121138
tokio::task::spawn_blocking(move || -> Result<(), String> {
122139
let cursor = std::io::Cursor::new(data);
123140
let mut archive = zip::ZipArchive::new(cursor).map_err(|e| e.to_string())?;
124-
141+
125142
for i in 0..archive.len() {
126143
let mut file = archive.by_index(i).map_err(|e| e.to_string())?;
127144
let outpath = dest.join(file.name());
128-
145+
129146
if file.is_dir() {
130147
std::fs::create_dir_all(&outpath).map_err(|e| e.to_string())?;
131148
} else {
@@ -137,21 +154,25 @@ async fn extract_zip(data: &[u8], dest: &PathBuf) -> Result<(), Box<dyn std::err
137154
}
138155
}
139156
Ok(())
140-
}).await.map_err(|e| e.to_string())??;
141-
157+
})
158+
.await
159+
.map_err(|e| e.to_string())??;
160+
142161
Ok(())
143162
}
144163

145164
async fn extract_tar_gz(data: &[u8], dest: &PathBuf) -> Result<(), Box<dyn std::error::Error>> {
146165
let data = data.to_vec();
147166
let dest = dest.clone();
148-
167+
149168
tokio::task::spawn_blocking(move || -> Result<(), String> {
150169
let decoder = flate2::read::GzDecoder::new(&data[..]);
151170
let mut archive = tar::Archive::new(decoder);
152171
archive.unpack(&dest).map_err(|e| e.to_string())?;
153172
Ok(())
154-
}).await.map_err(|e| e.to_string())??;
155-
173+
})
174+
.await
175+
.map_err(|e| e.to_string())??;
176+
156177
Ok(())
157-
}
178+
}

src/cli.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ pub enum ForceOption {
2222
All,
2323
Registry,
2424
Binary,
25-
}
25+
}

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
pub mod agent;
12
pub mod cli;
23
pub mod registry;
3-
pub mod agent;
44

5+
pub use agent::*;
56
pub use cli::*;
67
pub use registry::*;
7-
pub use agent::*;

src/main.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,42 @@
1+
use acpr::{Cli, fetch_registry, list_agents, run_agent};
12
use clap::Parser;
2-
use acpr::{Cli, fetch_registry, run_agent, list_agents};
33
use tracing_subscriber;
44

55
#[tokio::main]
66
async fn main() -> Result<(), Box<dyn std::error::Error>> {
77
let cli = Cli::parse();
8-
8+
99
if cli.debug {
1010
tracing_subscriber::fmt()
1111
.with_writer(std::io::stderr)
1212
.with_max_level(tracing::Level::DEBUG)
1313
.init();
1414
}
15-
15+
1616
let cache_dir = cli.cache_dir.unwrap_or_else(|| {
1717
dirs::cache_dir()
1818
.expect("No cache directory found")
1919
.join("acpr")
2020
});
21-
21+
2222
tokio::fs::create_dir_all(&cache_dir).await?;
23-
23+
2424
let registry = fetch_registry(&cache_dir, cli.force.as_ref(), cli.registry.as_ref()).await?;
25-
25+
2626
if cli.list {
2727
list_agents(&registry);
2828
return Ok(());
2929
}
30-
31-
let agent_name = cli.agent_name.ok_or("Agent name is required when not using --list")?;
32-
let agent = registry.agents.iter()
30+
31+
let agent_name = cli
32+
.agent_name
33+
.ok_or("Agent name is required when not using --list")?;
34+
let agent = registry
35+
.agents
36+
.iter()
3337
.find(|a| a.id == agent_name)
3438
.ok_or("Agent not found")?;
35-
39+
3640
run_agent(agent, &cache_dir, cli.force.as_ref()).await?;
3741
Ok(())
38-
}
42+
}

src/registry.rs

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
use crate::cli::ForceOption;
2+
use anstyle::{Color, Style};
13
use serde::{Deserialize, Serialize};
24
use std::collections::HashMap;
35
use std::path::PathBuf;
4-
use crate::cli::ForceOption;
5-
use anstyle::{Color, Style};
66
use tracing::{debug, info};
77

88
#[derive(Deserialize)]
@@ -54,21 +54,25 @@ pub struct CacheInfo {
5454
pub version: String,
5555
}
5656

57-
pub async fn fetch_registry(cache_dir: &PathBuf, force: Option<&ForceOption>, registry_file: Option<&PathBuf>) -> Result<Registry, Box<dyn std::error::Error>> {
57+
pub async fn fetch_registry(
58+
cache_dir: &PathBuf,
59+
force: Option<&ForceOption>,
60+
registry_file: Option<&PathBuf>,
61+
) -> Result<Registry, Box<dyn std::error::Error>> {
5862
if let Some(file_path) = registry_file {
5963
debug!("Using custom registry file: {:?}", file_path);
6064
let registry_content = tokio::fs::read_to_string(file_path).await?;
6165
return Ok(serde_json::from_str(&registry_content)?);
6266
}
63-
67+
6468
let registry_file = cache_dir.join("registry.json");
6569
let cache_info_file = cache_dir.join("registry_cache.json");
66-
70+
6771
let should_fetch = match force {
6872
Some(ForceOption::All | ForceOption::Registry) => {
6973
debug!("Force refresh requested for registry");
7074
true
71-
},
75+
}
7276
_ => {
7377
if let Ok(info_content) = tokio::fs::read_to_string(&cache_info_file).await {
7478
if let Ok(cache_info) = serde_json::from_str::<CacheInfo>(&info_content) {
@@ -78,24 +82,26 @@ pub async fn fetch_registry(cache_dir: &PathBuf, force: Option<&ForceOption>, re
7882
let age_hours = (now - cache_info.timestamp) / 3600;
7983
debug!("Registry cache age: {} hours", age_hours);
8084
now - cache_info.timestamp > 3 * 3600 // 3 hours
81-
} else {
85+
} else {
8286
debug!("Invalid cache info file, will fetch");
83-
true
87+
true
8488
}
85-
} else {
89+
} else {
8690
debug!("No cache info file found, will fetch");
87-
true
91+
true
8892
}
8993
}
9094
};
91-
95+
9296
if should_fetch {
9397
info!("Fetching registry from ACP...");
94-
let response = reqwest::get("https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json").await?;
98+
let response =
99+
reqwest::get("https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json")
100+
.await?;
95101
let registry_content = response.text().await?;
96102
debug!("Writing registry to cache: {:?}", registry_file);
97103
tokio::fs::write(&registry_file, &registry_content).await?;
98-
104+
99105
let cache_info = CacheInfo {
100106
timestamp: std::time::SystemTime::now()
101107
.duration_since(std::time::UNIX_EPOCH)?
@@ -107,33 +113,43 @@ pub async fn fetch_registry(cache_dir: &PathBuf, force: Option<&ForceOption>, re
107113
} else {
108114
debug!("Using cached registry: {:?}", registry_file);
109115
}
110-
116+
111117
let registry_content = tokio::fs::read_to_string(&registry_file).await?;
112118
let registry: Registry = serde_json::from_str(&registry_content)?;
113119
debug!("Loaded {} agents from registry", registry.agents.len());
114120
Ok(registry)
115121
}
116122

117123
pub fn list_agents(registry: &Registry) {
118-
let header_style = Style::new().fg_color(Some(Color::Ansi(anstyle::AnsiColor::Cyan))).bold();
124+
let header_style = Style::new()
125+
.fg_color(Some(Color::Ansi(anstyle::AnsiColor::Cyan)))
126+
.bold();
119127
let name_style = Style::new().fg_color(Some(Color::Ansi(anstyle::AnsiColor::Green)));
120128
let desc_style = Style::new().fg_color(Some(Color::Ansi(anstyle::AnsiColor::White)));
121-
129+
122130
println!("{header_style}Available ACP Agents:{header_style:#}");
123131
println!();
124-
132+
125133
for agent in &registry.agents {
126134
let dist_types = get_distribution_types(&agent.distribution);
127-
println!("{name_style}{}{name_style:#} {desc_style}({}){desc_style:#}",
128-
agent.id,
129-
dist_types.join(", "));
135+
println!(
136+
"{name_style}{}{name_style:#} {desc_style}({}){desc_style:#}",
137+
agent.id,
138+
dist_types.join(", ")
139+
);
130140
}
131141
}
132142

133143
fn get_distribution_types(dist: &Distribution) -> Vec<&'static str> {
134144
let mut types = Vec::new();
135-
if !dist.binary.is_empty() { types.push("binary"); }
136-
if dist.npx.is_some() { types.push("npx"); }
137-
if dist.uvx.is_some() { types.push("uvx"); }
145+
if !dist.binary.is_empty() {
146+
types.push("binary");
147+
}
148+
if dist.npx.is_some() {
149+
types.push("npx");
150+
}
151+
if dist.uvx.is_some() {
152+
types.push("uvx");
153+
}
138154
types
139-
}
155+
}

0 commit comments

Comments
 (0)