Repository: aliyun/fun (js)

Issue:
CodeUri 设置不正确，导致的函数依赖找不到的问题
执行 fun deploy、fun local invoke、fun local start 时，检查函数的 CodeUri，如果设置的是单文件，且所在目录包含 node_moduels（nodejs）、或其他的 pip、php 特征的库（根据 runtime 类型检测），就提示用户，是否忘记将该库的目录放置在 template.yml 所对应的 CodeUri 中了？

执行 fun install 时，如果发现当前当前安装的 .fun 目录，不被任何函数索引，那么提示用户是否有配置正确 CodeUri （也可以根据已有的 CodeUri，根据匹配度，推荐用户怎么设置）？

fun local invoke、start 时，识别错误中的 ModuleNotFoundError，提示用户 CodeUri 的设置的问题。

sumary 加上告诉用户打包多少个文件。



Pull request description:
sunfeiyu/add_number_of_packaged_files
#245  add the number of package files  

Patch:
diff --git a/lib/deploy/deploy-support.js b/lib/deploy/deploy-support.js
index c58293d..c377c18 100644
--- a/lib/deploy/deploy-support.js
+++ b/lib/deploy/deploy-support.js
@@ -28,11 +28,10 @@ const ram = require('../ram');
 
 const readFile = util.promisify(fs.readFile);
 
-const { green, red } = require('colors');
+const { green, red, yellow } = require('colors');
 const { addEnv } = require('../install/env');
 
 const _ = require('lodash');
-
 const getFcClient = async () => {
   const profile = await getProfile();
 
@@ -436,9 +435,8 @@ async function makeFunction(baseDir, {
     code = extractOssCodeUri(codeUri);
   } else {
     console.log(`\t\tWaiting for packaging function ${functionName} code...`);
-    const base64 = await getFunCodeAsBase64(baseDir, codeUri);
-    console.log(green(`\t\tpackage function ${functionName} code done`));
-
+    const {base64, count} = await getFunCodeAsBase64(baseDir, codeUri, runtime);
+    console.log(green(`\t\tpackage function ${functionName} code done, the number of files you have packaged is：` + yellow(`${count}`)));
     code = {
       zipFile: base64
     };
diff --git a/lib/package/zip.js b/lib/package/zip.js
index 664f5c0..be98355 100644
--- a/lib/package/zip.js
+++ b/lib/package/zip.js
@@ -76,6 +76,9 @@ exports.compress = async function (func, rootDir, type) {
 async function zipFolder(zip, folder, folders, funignore) {
   folders.push(folder);
   const dir = path.join(...folders);
+
+  let count = 0;
+  
   await Promise.all((await readdir(dir)).map(async (f) => {
 
     const fPath = path.join(dir, f);
@@ -97,12 +100,14 @@ async function zipFolder(zip, folder, folders, funignore) {
     }
 
     if (s.isFile()) {
+      count++;
       zip.file(f, fs.createReadStream(fPath), {
         unixPermissions: permStr(s.mode)
       });
     } else if (s.isDirectory()) {
       const zFolder = zip.folder(f);
-      await zipFolder(zFolder, f, folders.slice(), funignore);
+      let folderFilesCount = await zipFolder(zFolder, f, folders.slice(), funignore);
+      count += folderFilesCount;
     } else if (s.isSymbolicLink()) {
       // see https://github.com/Stuk/jszip/issues/428
       zip.file(f, await readlink(fPath), {
@@ -110,6 +115,7 @@ async function zipFolder(zip, folder, folders, funignore) {
       });
     }  
   }));
+  return count;
 }
 
 exports.pack = async function (file, funignore) {
@@ -127,17 +133,19 @@ exports.pack = async function (file, funignore) {
     throw new Error('file %s is ignored.', file);
   }
 
+  let count = 0;
+
   if (stats.isFile()) {
     debug('append file: %s', file);
     zip.file(path.basename(file), fs.createReadStream(file));
+    count++;
   } else if (stats.isDirectory()) {
     debug('append folder: %s, absolute path is %s', file, path.resolve(file));
-    await zipFolder(zip, file, [], funignore);
+    count = await zipFolder(zip, file, [], funignore);
   } else {
     throw new Error('file %s must be a regular file or directory.', file);
   }
-
-  return zip.generateAsync({
+  const base64 = await zip.generateAsync({
     type: 'base64',
     platform: 'UNIX',
     compression: 'DEFLATE',
@@ -145,4 +153,6 @@ exports.pack = async function (file, funignore) {
       level: 9
     }
   });
+
+  return { base64, count };
 };


Test patch:
diff --git a/test/deploy/deploy-support.test.js b/test/deploy/deploy-support.test.js
index fb3c7a0..0d049a9 100644
--- a/test/deploy/deploy-support.test.js
+++ b/test/deploy/deploy-support.test.js
@@ -313,7 +313,7 @@ describe('Incorrect environmental variables', ()=> {
   beforeEach(async () => {
     sandbox.stub(FC.prototype, 'getFunction').resolves({});
     sandbox.stub(FC.prototype, 'updateFunction').resolves({});
-    sandbox.stub(zip, 'pack').resolves('');
+    sandbox.stub(zip, 'pack').resolves({});
 
     deploySupport = await proxyquire('../../lib/deploy/deploy-support', {
       '../package/zip': zip,
@@ -361,7 +361,7 @@ describe('Incorrect environmental variables', ()=> {
         memorySize: 128,
         runtime: 'nodejs6',
         code: {
-          zipFile: ''
+          zipFile: undefined
         },
         environmentVariables: {
           StringTypeValue1: '123',
diff --git a/test/package/zip.test.js b/test/package/zip.test.js
index 00ed38a..b933d77 100644
--- a/test/package/zip.test.js
+++ b/test/package/zip.test.js
@@ -47,8 +47,8 @@ describe('zip', () => {
 
   it('.funignore', async function() {
     var basePath = path.join('examples', 'package', 'funignore');
-    var b64string = await zip.pack(basePath, funignore(basePath));
-    var zipfile = await JSZip.loadAsync(b64string, { base64: true });
+    var { base64 } = await zip.pack(basePath, funignore(basePath));
+    var zipfile = await JSZip.loadAsync(base64, { base64: true });
       
     expect(zipfile.files).to.only.have.keys('example.pdf', 'lib/', 'package.json', 'lib/.keep');
   });