Skip to content

Commit fdec66a

Browse files
author
高魏洪
committed
fix: code support http url
1 parent d4940bc commit fdec66a

File tree

2 files changed

+82
-5
lines changed

2 files changed

+82
-5
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@
2626
"@alicloud/fc2": "^2.6.6",
2727
"@alicloud/fc20230330": "4.6.7",
2828
"@alicloud/pop-core": "^1.8.0",
29+
"@serverless-cd/srm-aliyun-oss": "^0.0.1-beta.8",
2930
"@serverless-cd/srm-aliyun-pop-core": "^0.0.8-beta.1",
3031
"@serverless-cd/srm-aliyun-ram20150501": "^0.0.2-beta.9",
3132
"@serverless-cd/srm-aliyun-sls20201230": "0.0.5-beta.3",
32-
"@serverless-cd/srm-aliyun-oss": "^0.0.1-beta.8",
3333
"@serverless-devs/diff": "^0.0.3-beta.6",
3434
"@serverless-devs/downloads": "^0.0.7",
3535
"@serverless-devs/load-component": "^0.0.9",
@@ -38,6 +38,7 @@
3838
"ajv": "^8.17.1",
3939
"ali-oss": "6.18.1",
4040
"aliyun-sdk": "^1.12.10",
41+
"axios": "^1.13.5",
4142
"chalk": "^4.1.0",
4243
"crc64-ecma182.js": "^2.0.2",
4344
"decompress": "^4.2.1",

src/subCommands/deploy/impl/function.ts

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import _ from 'lodash';
22
import { diffConvertYaml } from '@serverless-devs/diff';
33
import inquirer from 'inquirer';
44
import fs from 'fs';
5+
import os from 'os';
6+
import axios from 'axios';
57
import assert from 'assert';
68
import path from 'path';
79
import { yellow } from 'chalk';
@@ -277,12 +279,16 @@ export default class Service extends Base {
277279
return true;
278280
}
279281

280-
let zipPath: string = path.isAbsolute(codeUri)
281-
? codeUri
282-
: path.join(this.inputs.baseDir, codeUri);
282+
let zipPath: string;
283+
// 处理不同类型的 codeUri
284+
if (codeUri.startsWith('http://') || codeUri.startsWith('https://')) {
285+
zipPath = await this._downloadFromUrl(codeUri);
286+
} else {
287+
zipPath = path.isAbsolute(codeUri) ? codeUri : path.join(this.inputs.baseDir, codeUri);
288+
}
283289
logger.debug(`Code path absolute path: ${zipPath}`);
284290

285-
const needZip = this._assertNeedZip(codeUri);
291+
const needZip = this._assertNeedZip(zipPath);
286292
logger.debug(`Need zip file: ${needZip}`);
287293

288294
let generateZipFilePath = '';
@@ -313,6 +319,15 @@ export default class Service extends Base {
313319
logger.debug(
314320
yellow(`skip uploadCode because code is no changed, codeChecksum=${crc64Value}`),
315321
);
322+
// 清理临时文件
323+
if (generateZipFilePath) {
324+
try {
325+
fs.rmSync(generateZipFilePath);
326+
} catch (ex) {
327+
logger.debug(`Unable to remove zip file: ${zipPath}`);
328+
}
329+
}
330+
316331
return false;
317332
} else {
318333
logger.debug(`\x1b[33mcodeChecksum from ${this.codeChecksum} to ${crc64Value}\x1b[0m`);
@@ -333,6 +348,67 @@ export default class Service extends Base {
333348
return true;
334349
}
335350

351+
/**
352+
* 从URL下载文件到本地临时目录
353+
*/
354+
private async _downloadFromUrl(url: string): Promise<string> {
355+
logger.warn(`Downloading code from URL: ${url}`);
356+
357+
// 创建临时目录
358+
const tempDir = path.join(os.tmpdir(), 'fc_code_download', Date.now().toString());
359+
fs.mkdirSync(tempDir, { recursive: true });
360+
let downloadPath: string;
361+
362+
try {
363+
// 从URL获取文件名
364+
const urlPath = new URL(url).pathname;
365+
const filename = path.basename(urlPath) || `downloaded_code_${Date.now()}`;
366+
downloadPath = path.join(tempDir, filename);
367+
368+
// 下载文件
369+
const response = await axios({
370+
method: 'GET',
371+
url,
372+
responseType: 'stream',
373+
});
374+
375+
const writer = fs.createWriteStream(downloadPath);
376+
377+
// 创建一个 Promise 来处理流操作
378+
await new Promise<void>((resolve, reject) => {
379+
response.data.on('error', (err) => {
380+
reject(new Error(`Source stream error: ${err.message}`));
381+
// 确保 writer 被关闭
382+
writer.destroy(err);
383+
});
384+
385+
writer.on('finish', resolve);
386+
387+
writer.on('error', (err) => {
388+
reject(new Error(`Write stream error: ${err.message}`));
389+
response.data.destroy();
390+
});
391+
392+
response.data.pipe(writer);
393+
});
394+
395+
logger.debug(`Downloaded file to: ${downloadPath}`);
396+
397+
// 返回下载文件路径,由主流程决定是否需要压缩
398+
return downloadPath;
399+
} catch (error) {
400+
// 如果下载失败,清理临时目录
401+
try {
402+
fs.rmSync(tempDir, { recursive: true, force: true });
403+
logger.debug(`Cleaned up temporary directory after error: ${tempDir}`);
404+
} catch (cleanupError) {
405+
logger.debug(`Failed to clean up temporary directory: ${cleanupError.message}`);
406+
}
407+
408+
throw new Error(`Failed to download code from URL: ${error.message}`);
409+
}
410+
}
411+
336412
/**
337413
* 生成 auto 资源,非 FC 资源,主要指 vpc、nas、log、role(oss mount 挂载点才有)
338414
*/

0 commit comments

Comments
 (0)