diff --git a/lib/main.js b/lib/main.js index 59b0a09a..a86bcc41 100644 --- a/lib/main.js +++ b/lib/main.js @@ -197,17 +197,26 @@ Lambda.prototype._fileCopy = function (program, src, dest, excludeNodeModules, c '.editorconfig', 'deploy.env', '*.log', - '/build/' + path.join(path.sep, 'build', path.sep) ] .concat(program.excludeGlobs ? program.excludeGlobs.split(' ') : []) - .concat(excludeNodeModules ? ['/node_modules'] : []); + .concat(excludeNodeModules ? [path.join(path.sep, 'node_modules')] : []); })(); + // Formatting for `filter` of `fs.copy` + const dirBlobs = []; const pattern = '{' + excludes.map(function (str) { - if (str.charAt(0) == '/') + if (str.charAt(str.length - 1) == path.sep) { + str = str.substr(0, str.length - 1); + dirBlobs.push(str); + } + if (str.charAt(0) == path.sep) return path.join(srcAbsolutePath, str); + if (str.indexOf(path.sep) >= 0) + return path.join(path.resolve('/**'), str); return str; - }).join(',') + '}' + }).join(',') + '}'; + const dirPatternRegExp = new RegExp(`(${dirBlobs.join('|')})$`); fs.mkdirs(dest, function (err) { if (err) { @@ -220,7 +229,13 @@ Lambda.prototype._fileCopy = function (program, src, dest, excludeNodeModules, c // include package.json unless prebuiltDirectory is set return true; } - return !minimatch(src, pattern, { matchBase: true }); + + if (!minimatch(src, pattern, { matchBase: true })) + return true; + // Directory check. Even if `src` is a directory it will not end with '/'. + if (!dirPatternRegExp.test(src)) + return false; + return !fs.statSync(src).isDirectory(); } }; fs.copy(src, dest, options, function (err) { diff --git a/test/main.js b/test/main.js index e1e016ec..ff9b2014 100644 --- a/test/main.js +++ b/test/main.js @@ -176,6 +176,19 @@ describe('node-lambda', function () { }); function rsyncTests(funcName) { + before(function () { + fs.mkdirSync('build'); + fs.mkdirsSync(path.join('__unittest', 'hoge')); + fs.mkdirsSync(path.join('__unittest', 'fuga')); + fs.writeFileSync(path.join('__unittest', 'hoge', 'piyo')); + fs.writeFileSync('fuga'); + }); + after(function () { + ['build', 'fuga', '__unittest'].forEach(function (path) { + fs.removeSync(path); + }); + }); + beforeEach(function (done) { lambda._cleanDirectory(codeDirectory, done); }); @@ -186,7 +199,7 @@ describe('node-lambda', function () { ['index.js', 'package.json'].forEach(function (needle) { assert.include(contents, needle, `Target: "${needle}"`); }); - ['node_modules'].forEach(function (needle) { + ['node_modules', 'build'].forEach(function (needle) { assert.notInclude(contents, needle, `Target: "${needle}"`); }); done(); @@ -197,7 +210,13 @@ describe('node-lambda', function () { beforeEach(function (done) { // *main* => lib/main.js // In case of specifying files under the directory with wildcards - program.excludeGlobs = '*.png test *main*'; + program.excludeGlobs = [ + '*.png', + 'test', + '*main*', + path.join('__unittest', 'hoge', '*'), + path.join('fuga', path.sep) + ].join(' '); done(); }); @@ -214,11 +233,23 @@ describe('node-lambda', function () { it(funcName + ' excludes files matching excludeGlobs', function (done) { lambda[funcName](program, '.', codeDirectory, true, function (err, result) { var contents = fs.readdirSync(codeDirectory); + ['__unittest', 'fuga'].forEach(function (needle) { + assert.include(contents, needle, `Target: "${needle}"`); + }); + ['node-lambda.png', 'test'].forEach(function (needle) { assert.notInclude(contents, needle, `Target: "${needle}"`); }); + contents = fs.readdirSync(path.join(codeDirectory, 'lib')); assert.notInclude(contents, 'main.js', 'Target: "lib/main.js"'); + + contents = fs.readdirSync(path.join(codeDirectory, '__unittest')); + assert.include(contents, 'hoge', 'Target: "__unittest/hoge"'); + assert.notInclude(contents, 'fuga', 'Target: "__unittest/fuga"'); + + contents = fs.readdirSync(path.join(codeDirectory, '__unittest', 'hoge')); + assert.isTrue(contents.length == 0, 'directory:__unittest/hoge is empty'); done(); }); });