Skip to content

Commit 69db76d

Browse files
authored
Merge pull request #876 from FatalTouch/non-node-packaging-fix-2021-06-10
Fix packaging for non-node functions
2 parents dab8ef3 + b4a7014 commit 69db76d

File tree

8 files changed

+92
-32
lines changed

8 files changed

+92
-32
lines changed

index.test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ describe('ServerlessWebpack', () => {
145145

146146
before(() => {
147147
slsw = new ServerlessWebpack(serverless, rawOptions);
148-
if(serverless.processedInput) { // serverless.processedInput does not exist in serverless@<2.0.0
148+
if (serverless.processedInput) {
149+
// serverless.processedInput does not exist in serverless@<2.0.0
149150
serverless.processedInput.options = processedOptions;
150151
}
151152
sandbox.stub(slsw, 'cleanup').returns(BbPromise.resolve());
@@ -477,7 +478,7 @@ describe('ServerlessWebpack', () => {
477478
test: () => {
478479
it('should override the raw options with the processed ones', () => {
479480
slsw.hooks.initialize();
480-
if(serverless.processedInput) {
481+
if (serverless.processedInput) {
481482
expect(slsw.options).to.equal(processedOptions);
482483
} else {
483484
// serverless.processedInput does not exist in serverless@<2.0.0

lib/packageModules.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const { nativeZip, nodeZip, hasNativeZip } = require('bestzip');
77
const glob = require('glob');
88
const semver = require('semver');
99
const fs = require('fs');
10+
const { getAllNodeFunctions } = require('./utils');
1011

1112
function setArtifactPath(funcName, func, artifactPath) {
1213
const version = this.serverless.getVersion();
@@ -150,7 +151,7 @@ module.exports = {
150151
this.serverless.cli.log('Copying existing artifacts...');
151152
// When invoked as a part of `deploy function`,
152153
// only function passed with `-f` flag should be processed.
153-
const functionNames = this.options.function ? [this.options.function] : this.serverless.service.getAllFunctions();
154+
const functionNames = this.options.function ? [this.options.function] : getAllNodeFunctions.call(this);
154155

155156
// Copy artifacts to package location
156157
if (isIndividialPackaging.call(this)) {

lib/utils.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,22 @@ function splitLines(str) {
108108
return _.split(str, /\r?\n/);
109109
}
110110

111+
function getAllNodeFunctions() {
112+
const functions = this.serverless.service.getAllFunctions();
113+
return _.filter(functions, funcName => {
114+
const func = this.serverless.service.getFunction(funcName);
115+
const runtime = func.runtime || this.serverless.service.provider.runtime || 'nodejs';
116+
return runtime.match(/node/);
117+
});
118+
}
119+
111120
module.exports = {
112121
guid,
113122
purgeCache,
114123
searchAndProcessCache,
115124
SpawnError,
116125
spawnProcess,
117126
safeJsonParse,
118-
splitLines
127+
splitLines,
128+
getAllNodeFunctions
119129
};

lib/validate.js

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const glob = require('glob');
77
const lib = require('./index');
88
const _ = require('lodash');
99
const Configuration = require('./Configuration');
10+
const { getAllNodeFunctions } = require('./utils');
1011

1112
/**
1213
* For automatic entry detection we sort the found files to solve ambiguities.
@@ -109,7 +110,7 @@ module.exports = {
109110
// Expose entries - must be done before requiring the webpack configuration
110111
const entries = {};
111112

112-
const functions = this.serverless.service.getAllFunctions();
113+
const functions = getAllNodeFunctions.call(this);
113114
if (this.options.function) {
114115
const serverlessFunction = this.serverless.service.getFunction(this.options.function);
115116
const entry = getEntryForFunction.call(this, this.options.function, serverlessFunction);
@@ -222,23 +223,16 @@ module.exports = {
222223
}
223224

224225
// Lookup associated Serverless functions
225-
const allEntryFunctions = _.map(
226-
_.filter(this.serverless.service.getAllFunctions(), funcName => {
227-
const func = this.serverless.service.getFunction(funcName);
228-
const runtime = func.runtime || this.serverless.service.provider.runtime || 'nodejs';
229-
return runtime.match(/node/);
230-
}),
231-
funcName => {
232-
const func = this.serverless.service.getFunction(funcName);
233-
const handler = getHandlerFileAndFunctionName(func);
234-
const handlerFile = path.relative('.', getHandlerFile(handler));
235-
return {
236-
handlerFile,
237-
funcName,
238-
func
239-
};
240-
}
241-
);
226+
const allEntryFunctions = _.map(getAllNodeFunctions.call(this), funcName => {
227+
const func = this.serverless.service.getFunction(funcName);
228+
const handler = getHandlerFileAndFunctionName(func);
229+
const handlerFile = path.relative('.', getHandlerFile(handler));
230+
return {
231+
handlerFile,
232+
funcName,
233+
func
234+
};
235+
});
242236

243237
this.entryFunctions = _.flatMap(entries, (value, key) => {
244238
const entry = path.relative('.', value);

lib/wpwatch.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ module.exports = {
110110
callback();
111111
} else if (canEmit && currentCompileWatch === null) {
112112
// eslint-disable-next-line promise/no-promise-in-callback
113-
currentCompileWatch = BbPromise.resolve(
114-
this.serverless.pluginManager.spawn('webpack:compile:watch')
115-
).then(() => this.serverless.cli.log('Watching for changes...'));
113+
currentCompileWatch = BbPromise.resolve(this.serverless.pluginManager.spawn('webpack:compile:watch')).then(
114+
() => this.serverless.cli.log('Watching for changes...')
115+
);
116116
}
117117
});
118118
};

tests/compile.test.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,6 @@ describe('compile', () => {
256256
webpackMock.compilerMock.run.reset();
257257
webpackMock.compilerMock.run.yields(null, multiStats);
258258
return expect(module.compile()).to.be.fulfilled.then(() => {
259-
console.log(JSON.stringify(module.compileStats.stats[0].externalModules));
260259
expect(module.compileStats.stats[0].externalModules).to.eql([
261260
{ external: '@scoped/vendor', origin: undefined },
262261
{ external: 'uuid', origin: undefined },

tests/packageModules.test.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -445,14 +445,21 @@ describe('packageModules', () => {
445445
});
446446

447447
describe('copyExistingArtifacts()', () => {
448-
const allFunctions = [ 'func1', 'func2' ];
448+
const allFunctions = [ 'func1', 'func2', 'funcPython' ];
449449
const func1 = {
450450
handler: 'src/handler1',
451451
events: []
452452
};
453453
const func2 = {
454454
handler: 'src/handler2',
455-
events: []
455+
events: [],
456+
runtime: 'node14'
457+
};
458+
459+
const funcPython = {
460+
handler: 'src/handlerPython',
461+
events: [],
462+
runtime: 'python3.7'
456463
};
457464

458465
const entryFunctions = [
@@ -465,6 +472,11 @@ describe('packageModules', () => {
465472
handlerFile: 'src/handler2.js',
466473
funcName: 'func2',
467474
func: func2
475+
},
476+
{
477+
handlerFile: 'src/handlerPython.js',
478+
funcName: 'funcPython',
479+
func: funcPython
468480
}
469481
];
470482

@@ -483,6 +495,7 @@ describe('packageModules', () => {
483495
getAllFunctionsStub.returns(allFunctions);
484496
getFunctionStub.withArgs('func1').returns(func1);
485497
getFunctionStub.withArgs('func2').returns(func2);
498+
getFunctionStub.withArgs('funcPython').returns(funcPython);
486499
});
487500

488501
it('copies the artifact', () => {
@@ -624,9 +637,10 @@ describe('packageModules', () => {
624637
getAllFunctionsStub.returns(allFunctions);
625638
getFunctionStub.withArgs('func1').returns(func1);
626639
getFunctionStub.withArgs('func2').returns(func2);
640+
getFunctionStub.withArgs('funcPython').returns(funcPython);
627641
});
628642

629-
it('copies each artifact', () => {
643+
it('copies each node artifact', () => {
630644
const expectedFunc1Destination = path.join('.serverless', 'func1.zip');
631645
const expectedFunc2Destination = path.join('.serverless', 'func2.zip');
632646

tests/validate.test.js

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ describe('validate', () => {
596596
});
597597
});
598598

599-
it('should allow custom runtime', () => {
599+
it('should ignore non-node runtimes', () => {
600600
const testOutPath = 'test';
601601
const testFunctionsConfig = {
602602
func1: {
@@ -683,17 +683,58 @@ describe('validate', () => {
683683
const lib = require('../lib/index');
684684
const expectedLibEntries = {
685685
module1: './module1.js',
686-
module2: './module2.js',
687686
module4: './module4.js'
688687
};
689688

690689
expect(lib.entries).to.deep.equal(expectedLibEntries);
691-
expect(globSyncStub).to.have.callCount(3);
690+
expect(globSyncStub).to.have.callCount(2);
692691
expect(serverless.cli.log).to.not.have.been.called;
693692
return null;
694693
});
695694
});
696695

696+
it('should throw error if container image is not well defined', () => {
697+
const testOutPath = 'test';
698+
const testFunctionsConfig = {
699+
func1: {
700+
artifact: 'artifact-func1.zip',
701+
events: [
702+
{
703+
http: {
704+
method: 'POST',
705+
path: 'func1path'
706+
}
707+
},
708+
{
709+
nonhttp: 'non-http'
710+
}
711+
],
712+
image: {
713+
name: 'custom-image',
714+
command: []
715+
}
716+
}
717+
};
718+
719+
const testConfig = {
720+
entry: 'test',
721+
context: 'testcontext',
722+
output: {
723+
path: testOutPath
724+
},
725+
getFunction: func => {
726+
return testFunctionsConfig[func];
727+
}
728+
};
729+
730+
_.set(module.serverless.service, 'custom.webpack.config', testConfig);
731+
module.serverless.service.functions = testFunctionsConfig;
732+
globSyncStub.callsFake(filename => [_.replace(filename, '*', 'js')]);
733+
expect(() => {
734+
module.validate();
735+
}).to.throw(/Either function.handler or function.image must be defined/);
736+
});
737+
697738
describe('google provider', () => {
698739
beforeEach(() => {
699740
_.set(module.serverless, 'service.provider.name', 'google');

0 commit comments

Comments
 (0)