From ae1e53b574cc1418f0dcb48f0abbfa0e151b544c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Nicodemos=20Maia=20Neto?= Date: Tue, 27 Jun 2017 21:52:05 -0300 Subject: [PATCH 1/3] Copy node_modules folder when symlink fails The "solution" is to copy the entire folder when symlink fails. Solution for #23 --- src/index.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 0025e213..65f03347 100644 --- a/src/index.ts +++ b/src/index.ts @@ -88,7 +88,16 @@ class ServerlessPlugin { // include node_modules into build if (!fs.existsSync(path.resolve(path.join(buildFolder, 'node_modules')))) { - fs.symlinkSync(path.resolve('node_modules'), path.resolve(path.join(buildFolder, 'node_modules'))) + try { + fs.symlinkSync(path.resolve('node_modules'), path.resolve(path.join(buildFolder, 'node_modules'))) + } catch(error) { + // copy the folder when symlink failed + if(error.errno == -4048 && error.code == 'EPERM') { + fs.copySync(path.resolve('node_modules'), path.resolve(path.join(buildFolder, 'node_modules'))); + } else { + throw error; + } + } } // include any "extras" from the "include" section From 8ce0bebcf1355e1f02057988be1012f65c3c690a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Nicodemos=20Maia=20Neto?= Date: Thu, 29 Jun 2017 16:15:56 -0300 Subject: [PATCH 2/3] - Partially refactored the deployment builder - Added an information comment about the windows issue --- src/deploy-builder.ts | 42 ++++++++++++++++++++++++++++++++++++++++++ src/index.ts | 20 ++++++-------------- 2 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 src/deploy-builder.ts diff --git a/src/deploy-builder.ts b/src/deploy-builder.ts new file mode 100644 index 00000000..3049ecb3 --- /dev/null +++ b/src/deploy-builder.ts @@ -0,0 +1,42 @@ +import * as path from 'path' +import * as fs from 'fs-p' + +export class DeployBuilder { + build(buildFolder: string) { + const buildPath = path.resolve(buildFolder) + + if (this.isNodeModulesAbsent(buildPath)) { + this.createNodeModulesFolder(buildPath) + } + } + + private isNodeModulesAbsent(buildPath: string): boolean { + return !fs.existsSync(path.join(buildPath, 'node_modules')) + } + + private createNodeModulesFolder(buildPath: string) { + try { + fs.symlinkSync(path.resolve('node_modules'), path.join(buildPath, 'node_modules')) + } catch (error) { + this.copyIfMissingSymlinkPermission(buildPath, error) + } + } + + private copyIfMissingSymlinkPermission(buildPath: string, error: SymlinkException) { + if (this.isMissingSymlinkPermission(error)) { + fs.copySync(path.resolve('node_modules'), path.join(buildPath, 'node_modules')) + } else { + throw error + } + } + + private isMissingSymlinkPermission(error: SymlinkException): boolean { + // Generally happens when no admin rights with UAC enabled on Windows. + return error.code === 'EPERM' && error.errno === -4048 + } +} + +export interface SymlinkException { + code: string + errno: number +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 65f03347..418e862b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,7 @@ import * as fs from 'fs-p' import * as _ from 'lodash' import * as globby from 'globby' +import { DeployBuilder } from './deploy-builder' import { ServerlessOptions, ServerlessInstance, ServerlessFunction } from './types' import * as typescript from './typescript' @@ -11,7 +12,6 @@ const serverlessFolder = '.serverless' const buildFolder = '.build' class ServerlessPlugin { - private originalServicePath: string private originalFunctions: { [key: string]: ServerlessFunction } | {} @@ -20,6 +20,8 @@ class ServerlessPlugin { commands: { [key: string]: any } hooks: { [key: string]: Function } + private deployBuilder: DeployBuilder + constructor(serverless: ServerlessInstance, options: ServerlessOptions) { this.serverless = serverless this.options = options @@ -56,6 +58,8 @@ class ServerlessPlugin { }, }, } + + this.deployBuilder = new DeployBuilder() } async beforeCreateDeploymentArtifacts(type: string): Promise { @@ -86,19 +90,7 @@ class ServerlessPlugin { await typescript.run(tsFileNames, tsconfig) - // include node_modules into build - if (!fs.existsSync(path.resolve(path.join(buildFolder, 'node_modules')))) { - try { - fs.symlinkSync(path.resolve('node_modules'), path.resolve(path.join(buildFolder, 'node_modules'))) - } catch(error) { - // copy the folder when symlink failed - if(error.errno == -4048 && error.code == 'EPERM') { - fs.copySync(path.resolve('node_modules'), path.resolve(path.join(buildFolder, 'node_modules'))); - } else { - throw error; - } - } - } + this.deployBuilder.build(buildFolder) // include any "extras" from the "include" section if (this.serverless.service.package.include && this.serverless.service.package.include.length > 0) { From 7d51bd3551fc30392b596a3eb4a53b402ce8c5e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Nicodemos=20Maia=20Neto?= Date: Thu, 29 Jun 2017 16:23:56 -0300 Subject: [PATCH 3/3] Added new line at the end of file --- src/deploy-builder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deploy-builder.ts b/src/deploy-builder.ts index 3049ecb3..b99003da 100644 --- a/src/deploy-builder.ts +++ b/src/deploy-builder.ts @@ -39,4 +39,4 @@ export class DeployBuilder { export interface SymlinkException { code: string errno: number -} \ No newline at end of file +}