Repository: aliyun/fun
Pull request #230 (2019-05-22 07:00:33)

Sunfeiyu/yml overwrite online config
#193 


Patch:
diff --git a/README-en.md b/README-en.md
index bef558e..4dcd27a 100644
--- a/README-en.md
+++ b/README-en.md
@@ -20,7 +20,10 @@ We have prepared a series of tutorials to help you use the Fun tool more easily:
 
 - [Installation](https://github.com/aliyun/fun/blob/master/docs/usage/installation.md): Learn how to install Fun on Mac, Linux or Windows.
 - [Getting Started](https://github.com/aliyun/fun/blob/master/docs/usage/getting_started.md): The basic usage of Fun is introduced with a simple example.
+- [Specification](https://github.com/aliyun/fun/blob/master/docs/specs/2018-04-03.md): Introduces the syntax of the fun's template.yml file.
 - **Series articles**:
+  - **Grammar Validation**：Fun provides a powerful grammar validation function, and allows users to easily correct it by accurately reporting error information.
+    - [开发函数计算的正确姿势 —— Fun validate 语法校验排错指南](https://yq.aliyun.com/articles/703144)：Introduced how to modify the error grammar description in template.yml according to the error information.
   - **Custom templates**: Articles on how to quickly build a project using `fun init`.
     - [开发函数计算的正确姿势 —— 使用 Fun Init 初始化项目](https://yq.aliyun.com/articles/674363): Introduced the basic usage of `fun init`.
     - [Fun Init 自定义模板](https://yq.aliyun.com/articles/674364): Introduce how to develop a `fun init` template.
@@ -55,7 +58,6 @@ We have prepared a series of tutorials to help you use the Fun tool more easily:
     - [用函数计算搭建微服务——云客服访客名片](https://yq.aliyun.com/articles/674378): Introduce how to use the Function Compute to build a micro service of visitor card.
     - [三分钟学会如何在函数计算中使用 puppeteer](https://yq.aliyun.com/articles/602877): Introduce how to use puppeteer in Function Compute.
     - [函数计算部署机器学习遇到的问题和解法](https://yq.aliyun.com/articles/630289)：Some problems that may be encountered when machine learning is deployed to Function Compute and some solutions to related problems.
-- [Specification](https://github.com/aliyun/fun/blob/master/docs/specs/2018-04-03.md): Introduces the syntax of the fun's template.yml file.
 - [FAQ](https://github.com/aliyun/fun/blob/master/docs/usage/faq.md): Frequently asked questions and answers when using fun.
 - [More Examples](https://github.com/aliyun/fun/tree/master/examples)
 
diff --git a/README.md b/README.md
index 4cb5fd6..0bfac71 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,10 @@ Fun 作为一个命令行工具，内置了多个子命令，比如 config、loc
 
 - [安装教程](https://github.com/aliyun/fun/blob/master/docs/usage/installation-zh.md)：介绍了如何在 Mac、Linux 或者 Windows 上安装 Fun。
 - [使用](https://github.com/aliyun/fun/blob/master/docs/usage/getting_started-zh.md)：通过一个简单的示例介绍了 Fun 的基本用法。
+- [Fun 规范文档](https://github.com/aliyun/fun/blob/master/docs/specs/2018-04-03-zh-cn.md): 详细介绍了 Fun 规范文档的细节。
 - **系列文章**：
+  - **语法校验**：Fun 提供了比较强大的语法校验功能，并通过精准的报错信息，让用户可以方便的将其修正。
+    - [开发函数计算的正确姿势 —— Fun validate 语法校验排错指南](https://yq.aliyun.com/articles/703144)：介绍了根据报错信息修正 template.yml 中的错误语法描述。
   - **自定义模板**：关于如何使用 fun init 快速构建项目的文章。
     - [开发函数计算的正确姿势 —— 使用 Fun Init 初始化项目](https://yq.aliyun.com/articles/674363)：介绍了 fun init 的基本用法。
     - [Fun Init 自定义模板](https://yq.aliyun.com/articles/674364)：介绍了如何开发 fun init 模板。
@@ -56,7 +59,6 @@ Fun 作为一个命令行工具，内置了多个子命令，比如 config、loc
     - [三分钟学会如何在函数计算中使用 puppeteer](https://yq.aliyun.com/articles/602877)：介绍了如何在函数计算中使用 puppeteer。
     - [函数计算部署机器学习遇到的问题和解法](https://yq.aliyun.com/articles/630289)：介绍了机器学习部署到函数计算时可能会遇到的一些问题以及相关问的解法。
 
-- [Fun 规范文档](https://github.com/aliyun/fun/blob/master/docs/specs/2018-04-03-zh-cn.md): 详细介绍了 Fun 规范文档的细节。
 - [常见问题与解答](https://github.com/aliyun/fun/blob/master/docs/usage/faq-zh.md): 使用 Fun 时的常见问题与解答。
 - [更多示例](https://github.com/aliyun/fun/tree/master/examples)
 
diff --git a/lib/deploy/deploy-by-tpl.js b/lib/deploy/deploy-by-tpl.js
index f38c69f..d584581 100644
--- a/lib/deploy/deploy-by-tpl.js
+++ b/lib/deploy/deploy-by-tpl.js
@@ -172,10 +172,20 @@ async function deployService(baseDir, serviceName, serviceRes) {
   const internetAccess = 'InternetAccess' in properties ? properties.InternetAccess : null;
   
   const policies = properties.Policies;
+  const defaultVpcConfig = {
+    securityGroupId: '',
+    vSwitchIds: [],
+    vpcId: ''
+  };
+  const defaultNasConfig = {
+    UserId: -1,
+    GroupId: -1,
+    MountPoints: []
+  };
+  const vpcConfig = properties.VpcConfig;
+  const nasConfig = properties.NasConfig;
 
-  const vpcConfig = properties.VpcConfig || {};
   const logConfig = properties.LogConfig || {};
-  const nasConfig = properties.NasConfig || {};
 
   let roleName;
   let createRoleIfNotExist;
@@ -229,14 +239,15 @@ async function deployService(baseDir, serviceName, serviceRes) {
   } else if (logConfig.LogStore || logConfig.Project) {
     throw new Error('LogStore and Project must both exist');
   }
+
   await makeService({
     serviceName,
     role: ((role || {}).Role || {}).Arn || roleArn || '',
     internetAccess,
     description: (serviceRes.Properties || {}).Description,
     logConfig,
-    vpcConfig,
-    nasConfig
+    vpcConfig: vpcConfig || defaultVpcConfig,
+    nasConfig: nasConfig || defaultNasConfig
   });
 
   await deployFunctions(baseDir, serviceName, serviceRes);
diff --git a/lib/deploy/deploy-support.js b/lib/deploy/deploy-support.js
index ca4859c..a9ae0c8 100644
--- a/lib/deploy/deploy-support.js
+++ b/lib/deploy/deploy-support.js
@@ -398,7 +398,7 @@ async function makeFunction(baseDir, {
   functionName,
   description = '',
   handler,
-  initializer = null,
+  initializer = '',
   timeout = 3,
   initializationTimeout = 3,
   memorySize = 128,


Test patch:
diff --git a/test/deploy/deploy-by-tpl.test.js b/test/deploy/deploy-by-tpl.test.js
index f200140..123fcc9 100644
--- a/test/deploy/deploy-by-tpl.test.js
+++ b/test/deploy/deploy-by-tpl.test.js
@@ -9,6 +9,16 @@ const deploySupport = require('../../lib/deploy/deploy-support');
 const ram = require('../../lib/ram');
 const { setProcess } = require('../test-utils');
 const { red } = require('colors');
+const defaultVpcConfig = {
+  securityGroupId: '',
+  vSwitchIds: [],
+  vpcId: ''
+};
+const defaultNasConfig = {
+  UserId: -1,
+  GroupId: -1,
+  MountPoints: []
+};
 
 describe('deploy service role ', () => {
   let restoreProcess;
@@ -141,8 +151,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'MyService',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
 
     assert.calledWith(deploySupport.makeFunction,
@@ -170,8 +180,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'fc',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
     assert.calledWith(deploySupport.makeFunction,
       path.join(process.cwd(), 'examples', 'helloworld'), {
@@ -198,8 +208,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'java',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
     assert.calledWith(deploySupport.makeFunction,
       path.join(process.cwd(), 'examples', 'java'), {
@@ -282,8 +292,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'fc',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
 
     assert.calledWith(deploySupport.makeFunction,
@@ -344,8 +354,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'test-tableStore-service',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
     assert.calledWith(deploySupport.makeFunction,
       path.join(process.cwd(), 'examples', 'tablestore-trigger'), {
@@ -382,8 +392,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'log-compute',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
     assert.calledWith(deploySupport.makeFunction,
       path.join(process.cwd(), 'examples', 'sls_demo'), {
@@ -422,8 +432,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'rds-service',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
     assert.calledWith(deploySupport.makeFunction,
       path.join(process.cwd(), 'examples', 'rds-trigger'), {
@@ -463,8 +473,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'oss-test-service',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
     assert.calledWith(deploySupport.makeFunction,
       path.join(process.cwd(), 'examples', 'oss-trigger'), {
@@ -506,8 +516,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'cdn-test-service',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
     assert.calledWith(deploySupport.makeFunction,
       path.join(process.cwd(), 'examples', 'cdn-trigger'), {
@@ -553,8 +563,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'mnsTopic-service',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
     assert.calledWith(deploySupport.makeFunction,
       path.join(process.cwd(), 'examples', 'mnsTopic-trigger'), {
@@ -593,8 +603,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'pythondemo',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
     assert.calledWith(deploySupport.makeFunction,
       path.join(process.cwd(), 'examples', 'python'), {
@@ -645,8 +655,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'maas',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
 
     assert.calledWith(deploySupport.makeFunction,
@@ -696,8 +706,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'MyService',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
     assert.calledWith(deploySupport.makeFunction,
       path.join(process.cwd(), 'examples', 'timer'), {
@@ -734,8 +744,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'wechat',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
     assert.calledWith(deploySupport.makeFunction.firstCall,
       path.join(process.cwd(), 'examples', 'wechat'), {
@@ -852,8 +862,8 @@ describe('deploy', () => {
       logConfig: {},
       role: '',
       serviceName: 'initializerdemo',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
     assert.calledWith(deploySupport.makeFunction,
       path.join(process.cwd(), 'examples', 'initializer'), {
@@ -905,8 +915,8 @@ describe('deploy', () => {
       logConfig: {},
       role: 'acs:ram::123:role/aliyunfcgeneratedrole-fc',
       serviceName: 'localdemo',
-      vpcConfig: {},
-      nasConfig: {}
+      vpcConfig: defaultVpcConfig,
+      nasConfig: defaultNasConfig
     });
 
     assert.calledWith(deploySupport.makeFunction,