From 61cbeb1645945edb58d7ea4bab2ad3daf6834d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christophe=20Boug=C3=A8re?= Date: Thu, 14 Dec 2017 13:46:11 +0100 Subject: [PATCH] - adding a `--template-url` option for `sls create` - update `walkDirSync` to ignore symbolic links (now ignore node_modules linked via `npm link`) --- docs/providers/aws/cli-reference/create.md | 13 +++++++-- lib/plugins/create/create.js | 18 +++++++++++++ lib/plugins/create/create.test.js | 31 ++++++++++++++++++++++ lib/utils/fs/walkDirSync.js | 2 +- 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/docs/providers/aws/cli-reference/create.md b/docs/providers/aws/cli-reference/create.md index fc38bf9cd..73421f725 100644 --- a/docs/providers/aws/cli-reference/create.md +++ b/docs/providers/aws/cli-reference/create.md @@ -33,8 +33,9 @@ serverless create --template-url https://github.com/serverless/serverless/tree/m ``` ## Options -- `--template` or `-t` The name of one of the available templates. **Required if --template-url is not present**. -- `--template-url` or `-u` The name of one of the available templates. **Required if --template is not present**. +- `--template` or `-t` The name of one of the available templates. **Required if --template-url and --template-path are not present**. +- `--template-url` or `-u` The name of one of the available templates. **Required if --template and --template-path are not present**. +- `--template-path` The local path of your template. **Required if --template and --template-url are not present**. - `--path` or `-p` The path where the service should be created. - `--name` or `-n` the name of the service in `serverless.yml`. @@ -90,6 +91,14 @@ will use the already present directory. Additionally Serverless will rename the service according to the path you provide. In this example the service will be renamed to `my-new-service`. +### Creating a new service using a local template + +```bash +serverless create --template-path path/to/my/template/folder --path path/to/my/service --name my-new-service +``` + +This will copy the `path/to/my/template/folder` folder into `path/to/my/service` and rename the service to `my-new-service`. + ### Creating a new plugin ``` diff --git a/lib/plugins/create/create.js b/lib/plugins/create/create.js index eaa3a6783..3e4f39f02 100644 --- a/lib/plugins/create/create.js +++ b/lib/plugins/create/create.js @@ -5,8 +5,12 @@ const path = require('path'); const fse = require('fs-extra'); const _ = require('lodash'); +const ServerlessError = require('../../classes/Error').ServerlessError; const userStats = require('../../utils/userStats'); const download = require('../../utils/downloadTemplateFromRepo'); +const renameService = require('../../utils/renameService').renameService; +const copyDirContentsSync = require('../../utils/fs/copyDirContentsSync'); +const dirExistsSync = require('../../utils/fs/dirExistsSync'); // class wide constants const validTemplates = [ @@ -66,6 +70,9 @@ class Create { usage: 'Template URL for the service. Supports: GitHub, BitBucket', shortcut: 'u', }, + 'template-path': { + usage: 'Template local path for the service.', + }, path: { usage: 'The path where the service should be created (e.g. --path my-service)', shortcut: 'p', @@ -111,6 +118,17 @@ class Create { .catch(err => { throw new this.serverless.classes.Error(err); }); + } else if ('template-path' in this.options) { + // Copying template from a local directory + const servicePath = this.options.path || path.join(process.cwd(), this.options.name); + if (dirExistsSync(servicePath)) { + const errorMessage = `A folder named "${servicePath}" already exists.`; + throw new ServerlessError(errorMessage); + } + copyDirContentsSync(this.options['template-path'], servicePath); + if (this.options.name) { + renameService(this.options.name, servicePath); + } } else { const errorMessage = [ 'You must either pass a template name (--template) or a ', diff --git a/lib/plugins/create/create.test.js b/lib/plugins/create/create.test.js index df578b493..fdd986eb0 100644 --- a/lib/plugins/create/create.test.js +++ b/lib/plugins/create/create.test.js @@ -666,5 +666,36 @@ describe('Create', () => { return create.create().catch(() => download.downloadTemplateFromRepo.restore()); }); + + it('should copy "aws-nodejs" template from local path', () => { + process.chdir(tmpDir); + const distDir = path.join(tmpDir, 'my-awesome-service'); + create.options = {}; + create.options.path = distDir; + create.options['template-path'] = path.join(__dirname, 'templates/aws-nodejs'); + + return create.create().then(() => { + const dirContent = fs.readdirSync(distDir); + + expect(dirContent).to.include('serverless.yml'); + expect(dirContent).to.include('handler.js'); + expect(dirContent).to.include('gitignore'); + }); + }); + + it('should copy "aws-nodejs" template from local path with a custom name', () => { + process.chdir(tmpDir); + create.options = {}; + create.options['template-path'] = path.join(__dirname, 'templates/aws-nodejs'); + create.options.name = 'my-awesome-service'; + + return create.create().then(() => { + const dirContent = fs.readdirSync(path.join(tmpDir, 'my-awesome-service')); + + expect(dirContent).to.include('serverless.yml'); + expect(dirContent).to.include('handler.js'); + expect(dirContent).to.include('gitignore'); + }); + }); }); }); diff --git a/lib/utils/fs/walkDirSync.js b/lib/utils/fs/walkDirSync.js index 0e4615272..d9aa3a049 100644 --- a/lib/utils/fs/walkDirSync.js +++ b/lib/utils/fs/walkDirSync.js @@ -9,7 +9,7 @@ function walkDirSync(dirPath) { list.forEach((filePathParam) => { let filePath = filePathParam; filePath = path.join(dirPath, filePath); - const stat = fs.statSync(filePath); + const stat = fs.lstatSync(filePath); if (stat && stat.isDirectory()) { filePaths = filePaths.concat(walkDirSync(filePath)); } else {