From 792186cf76d2538d5ddba365ecf7b6b819684a47 Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Thu, 30 Oct 2025 12:52:21 -0300 Subject: [PATCH] feat(s3): Finally improve directory upload with proper path handling - Added bucket parameter to upload_directory_recursive for explicit bucket specification - Improved key construction logic to handle path prefixes more robustly - Removed redundant trace logs and added more informative upload messages - Fixed potential issue with bucket name extraction from prefix - Ensured consistent path separator handling in S3 keys The changes make the S3 upload functionality more reliable and maintainable by: 1. Explicitly passing bucket names instead of extracting from prefixes 2. Properly handling path separators in S3 keys 3. Providing clearer logging for upload operations --- src/bootstrap/mod.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/mod.rs b/src/bootstrap/mod.rs index 04ef34f3..033f5867 100644 --- a/src/bootstrap/mod.rs +++ b/src/bootstrap/mod.rs @@ -459,7 +459,7 @@ aws_sdk_s3::Client::from_conf(s3_config) } } - self.upload_directory_recursive(client, &path, &bucket) + self.upload_directory_recursive(client, &path, &bucket, "/") .await?; info!("Uploaded template {} to Drive bucket {}", bot_name, bucket); } @@ -523,6 +523,7 @@ aws_sdk_s3::Client::from_conf(s3_config) &'a self, client: &'a Client, local_path: &'a Path, + bucket: &'a str, prefix: &'a str, ) -> std::pin::Pin> + 'a>> { Box::pin(async move { @@ -536,25 +537,26 @@ aws_sdk_s3::Client::from_conf(s3_config) let entry = entry?; let path = entry.path(); let file_name = path.file_name().unwrap().to_string_lossy().to_string(); - let key = if prefix.is_empty() { - file_name.clone() - } else { - format!("{}/{}", prefix.trim_end_matches('/'), file_name) - }; + + // Construct key path, ensuring no duplicate slashes + let mut key = prefix.trim_matches('/').to_string(); + if !key.is_empty() { + key.push('/'); + } + key.push_str(&file_name); if path.is_file() { - info!("Uploading file: {} with key: {}", path.display(), key); + info!("Uploading file: {} to bucket {} with key: {}", + path.display(), bucket, key); let content = std::fs::read(&path)?; - trace!("Writing file {} with key {}", path.display(), key); client.put_object() - .bucket(prefix.split('/').next().unwrap_or("default.gbai")) + .bucket(bucket) .key(&key) .body(content.into()) .send() .await?; - trace!("Successfully wrote file {}", path.display()); } else if path.is_dir() { - self.upload_directory_recursive(client, &path, &key).await?; + self.upload_directory_recursive(client, &path, bucket, &key).await?; } } Ok(())