Skip to content

Commit 91dc54f

Browse files
Enhance S3 download functionality to support compressed files (#639)
- Updated the ProjectStore class to include an option for downloading a single compressed zip file from S3, extracting it upon download. - Modified the downloadS3Directory method to accept an isCompressedFile parameter, allowing for conditional handling of zip files. - Added logging for successful downloads of both directories and compressed files. These changes improve the flexibility of the S3 download process, accommodating different project structures. Signed-off-by: Sagar Swami Rao Kulkarni <sagarswamirao@gmail.com>
1 parent c29acc5 commit 91dc54f

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

packages/server/src/controller/package.controller.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ export class PackageController {
113113
packageLocation,
114114
projectName,
115115
absoluteTargetPath,
116+
isCompressedFile,
116117
);
117118
}
118119

packages/server/src/service/project_store.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1112,7 +1112,12 @@ export class ProjectStore {
11121112
logger.info(
11131113
`Downloading S3 directory from "${location}" to "${targetPath}"`,
11141114
);
1115-
await this.downloadS3Directory(location, projectName, targetPath);
1115+
await this.downloadS3Directory(
1116+
location,
1117+
projectName,
1118+
targetPath,
1119+
isCompressedFile,
1120+
);
11161121
return;
11171122
} catch (error) {
11181123
const errorData = this.extractErrorDataFromError(error);
@@ -1242,10 +1247,43 @@ export class ProjectStore {
12421247
s3Path: string,
12431248
projectName: string,
12441249
absoluteDirPath: string,
1250+
isCompressedFile: boolean = false,
12451251
) {
12461252
const trimmedPath = s3Path.slice(5);
12471253
const [bucketName, ...prefixParts] = trimmedPath.split("/");
12481254
const prefix = prefixParts.join("/");
1255+
1256+
if (isCompressedFile) {
1257+
// Download the single zip file
1258+
const zipFilePath = `${absoluteDirPath}.zip`;
1259+
await fs.promises.mkdir(path.dirname(zipFilePath), {
1260+
recursive: true,
1261+
});
1262+
1263+
const command = new GetObjectCommand({
1264+
Bucket: bucketName,
1265+
Key: prefix,
1266+
});
1267+
const item = await this.s3Client.send(command);
1268+
if (!item.Body) {
1269+
throw new ProjectNotFoundError(
1270+
`Project ${projectName} not found in ${s3Path}`,
1271+
);
1272+
}
1273+
const file = fs.createWriteStream(zipFilePath);
1274+
item.Body.transformToWebStream().pipeTo(Writable.toWeb(file));
1275+
await new Promise<void>((resolve, reject) => {
1276+
file.on("error", reject);
1277+
file.on("finish", resolve);
1278+
});
1279+
1280+
// Extract the zip file
1281+
await this.unzipProject(zipFilePath);
1282+
logger.info(`Downloaded S3 zip file ${s3Path} to ${absoluteDirPath}`);
1283+
return;
1284+
}
1285+
1286+
// Original behavior: download directory contents
12491287
const objects = await this.s3Client.listObjectsV2({
12501288
Bucket: bucketName,
12511289
Prefix: prefix,
@@ -1291,6 +1329,7 @@ export class ProjectStore {
12911329
});
12921330
}),
12931331
);
1332+
logger.info(`Downloaded S3 directory ${s3Path} to ${absoluteDirPath}`);
12941333
}
12951334

12961335
private parseGitHubUrl(

0 commit comments

Comments
 (0)