1+ use crate :: cli:: ForceOption ;
2+ use crate :: registry:: { Agent , BinaryDist } ;
13use std:: path:: PathBuf ;
24use std:: process:: Stdio ;
35use tokio:: process:: Command ;
4- use crate :: cli:: ForceOption ;
5- use crate :: registry:: { Agent , BinaryDist } ;
66use 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
117134async 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
145164async 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+ }
0 commit comments