Skip to content

Commit 96ea58f

Browse files
authored
Merge pull request #10 from scaleway/update_runtime_exported_functions
[Runtimes] Update documentation and examples to support new exported …
2 parents c93ff2a + abfc148 commit 96ea58f

File tree

13 files changed

+147
-107
lines changed

13 files changed

+147
-107
lines changed

deploy/scalewayDeploy.js

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,54 +17,54 @@ class ScalewayDeploy {
1717
this.provider = this.serverless.getProvider('scaleway');
1818

1919
Object.assign(
20-
this,
21-
validate,
22-
setUpDeployment,
23-
createNamespace,
24-
createFunctions,
25-
createContainers,
26-
pushContainers,
27-
uploadCode,
28-
deployFunctions,
29-
deployContainers,
30-
namespaceUtils,
20+
this,
21+
validate,
22+
setUpDeployment,
23+
createNamespace,
24+
createFunctions,
25+
createContainers,
26+
pushContainers,
27+
uploadCode,
28+
deployFunctions,
29+
deployContainers,
30+
namespaceUtils,
3131
);
3232

3333
function chainContainers() {
34-
if (this.provider.serverless.service.custom &&
35-
this.provider.serverless.service.custom.containers &&
36-
Object.keys(this.provider.serverless.service.custom.containers).length !== 0) {
34+
if (this.provider.serverless.service.custom
35+
&& this.provider.serverless.service.custom.containers
36+
&& Object.keys(this.provider.serverless.service.custom.containers).length !== 0) {
3737
return this.createContainers()
38-
.then(this.pushContainers)
39-
.then(this.deployContainers)
38+
.then(this.pushContainers)
39+
.then(this.deployContainers);
4040
}
41-
};
41+
}
4242

4343
function chainFunctions() {
44-
if (this.provider.serverless.service.functions &&
45-
Object.keys(this.provider.serverless.service.functions).length !== 0) {
44+
if (this.provider.serverless.service.functions
45+
&& Object.keys(this.provider.serverless.service.functions).length !== 0) {
4646
return this.createFunctions()
47-
.then(this.uploadCode)
48-
.then(this.deployFunctions)
47+
.then(this.uploadCode)
48+
.then(this.deployFunctions);
4949
}
50-
};
50+
}
5151

5252
this.hooks = {
5353
// Validate serverless.yml, set up default values, configure deployment...
5454
'before:deploy:deploy': () => BbPromise.bind(this)
5555
.then(this.provider.initialize(this.serverless, this.options))
56-
.then(this.validate)
57-
.then(this.setUpDeployment),
56+
.then(this.setUpDeployment)
57+
.then(this.validate),
5858
// Every tasks related to functions deployment:
5959
// - Create a namespace if it does not exist
6060
// - Create each functions in API if it does not exist
6161
// - Zip code - zip each function
6262
// - Get Presigned URL and Push code for each function to S3
6363
// - Deploy each function / container
6464
'deploy:deploy': () => BbPromise.bind(this)
65-
.then(this.createNamespace)
66-
.then(chainContainers)
67-
.then(chainFunctions)
65+
.then(this.createNamespace)
66+
.then(chainContainers)
67+
.then(chainFunctions),
6868
};
6969
}
7070
}

docs/README.md

Lines changed: 60 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -164,67 +164,67 @@ Available runtimes are:
164164
#### Functions Handler
165165
166166
Based on the chosen runtime, the `handler` variable on function might vary:
167-
- `node` (8 or 10): Path to your handler file (from serverless.yml), omit `./`, `../`.
168-
```
169-
- src
170-
- handlers
171-
- firstHandler.js
172-
- secondHandler.js
173-
- serverless.yml
174-
```
175-
Inside serverless.yml:
176-
```yml
177-
provider:
178-
# ...
179-
runtime: node8 # or node10
180-
functions:
181-
first:
182-
handler: src/handlers/firstHandler.js
183-
second:
184-
handler: src/handlers/secondHandler.js
185-
```
186-
- `python` (2.7 and 3.7): Similar to `node`, path to handler file `src/testing/handler.py`:
187-
```
188-
- src
189-
- handlers
190-
- firstHandler.py
191-
- secondHandler.py
192-
- serverless.yml
193-
```
194-
Inside serverless.yml:
195-
```yml
196-
provider:
197-
# ...
198-
runtime: python3 # or python for python 2.7
199-
functions:
200-
first:
201-
handler: src/handlers/firstHandler.py
202-
second:
203-
handler: src/handlers/secondHandler.py
204-
```
167+
- `node` (8 or 10): Path to your handler file (from serverless.yml), omit `./`, `../`, suffixed by the exported function to use (example: `myFunction.handle` => file `myFunction.js` exports a function `handle`).
168+
```
169+
- src
170+
- handlers
171+
- firstHandler.js => module.exports.myFirstHandler
172+
- secondHandler.js => module.exports.mySecondHandler
173+
- serverless.yml
174+
```
175+
Inside serverless.yml:
176+
```yml
177+
provider:
178+
# ...
179+
runtime: node8 # or node10
180+
functions:
181+
first:
182+
handler: src/handlers/firstHandler.myFirstHandler
183+
second:
184+
handler: src/handlers/secondHandler.mySecondHandler
185+
```
186+
- `python` (2.7 and 3.7): Similar to `node`, path to handler file, suffixed with exported function to use: `src/testing/handler.handle` => file `handler.py` defines a method `handle`, inside directory `src/testing`.
187+
```
188+
- src
189+
- handlers
190+
- firstHandler.py => def my_first_handler
191+
- secondHandler.py => def my_second_handler
192+
- serverless.yml
193+
```
194+
Inside serverless.yml:
195+
```yml
196+
provider:
197+
# ...
198+
runtime: python3 # or python for python 2.7
199+
functions:
200+
first:
201+
handler: src/handlers/firstHandler.my_first_handler
202+
second:
203+
handler: src/handlers/secondHandler.my_second_handler
204+
```
205205
- `golang`: Path to your handler's **package**, for example if I have the following structure:
206-
```
207-
- src
208-
- testing
209-
- handler.go -> package main inside "src/testing" directory
210-
- second
211-
- handler.go -> package main inside "src/second" directory
212-
- handler.go -> package main at the root of the project
213-
- serverless.yml
214-
```
215-
Your serverless.yml `functions` should look something like this:
216-
```yml
217-
provider:
218-
# ...
219-
runtime: golang
220-
functions:
221-
root:
222-
handler: "."
223-
testing:
224-
handler: src/testing
225-
second:
226-
handler: src/second
227-
```
206+
```
207+
- src
208+
- testing
209+
- handler.go -> package main inside "src/testing" directory
210+
- second
211+
- handler.go -> package main inside "src/second" directory
212+
- handler.go -> package main at the root of the project
213+
- serverless.yml
214+
```
215+
Your serverless.yml `functions` should look something like this:
216+
```yml
217+
provider:
218+
# ...
219+
runtime: golang
220+
functions:
221+
root:
222+
handler: "."
223+
testing:
224+
handler: src/testing
225+
second:
226+
handler: src/second
227+
```
228228

229229
### Environment Variables
230230

examples/nodejs10/handler.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module.exports = (event, context, callback) => {
1+
module.exports.handle = (event, context, callback) => {
22
const result = {
33
message: 'Hello from Serverless Framework and Scaleway Functions :D',
44
};

examples/nodejs10/serverless.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ package:
2121

2222
functions:
2323
first:
24-
handler: handler.js
24+
handler: handler.handle
2525
# Local environment variables - used only in given function
2626
env:
2727
local: local

examples/nodejs8/handler.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module.exports = (event, context, callback) => {
1+
module.exports.handle = (event, context, callback) => {
22
const result = {
33
message: 'Hello from Serverless Framework and Scaleway Functions :D',
44
};

examples/nodejs8/serverless.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ package:
2121

2222
functions:
2323
first:
24-
handler: handler.js
24+
handler: handler.handle
2525
# Local environment variables - used only in given function
2626
env:
2727
local: local

examples/python2/serverless.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ package:
2222

2323
functions:
2424
first:
25-
handler: handler.py
25+
handler: handler.handle
2626
# Local environment variables - used only in given function
2727
env:
2828
local: local

examples/python3/serverless.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ package:
2222

2323
functions:
2424
first:
25-
handler: handler.py
25+
handler: handler.handle
2626
# Local environment variables - used only in given function
2727
env:
2828
local: local

examples/typescript/serverless.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ functions:
2424
first:
2525
# Path to compiled JavaScript Handler
2626
# Note that this must be a `.js` file even though you are using .ts
27-
handler: src/handler.js
27+
handler: .webpack/handler.myHandler
2828
# Local environment variables - used only in given function
2929
env:
3030
local: local

examples/typescript/src/handler.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { APIGatewayProxyEvent, APIGatewayProxyResult, APIGatewayProxyHandler } from 'scaleway-functions-typescript';
22

3-
const handler: APIGatewayProxyHandler = (event, context, callback) => {
3+
export const myHandler: APIGatewayProxyHandler = (event, context, callback) => {
44
const result = {
55
message: 'Hello from Node w/ TypeScript on Scaleway Functions !',
66
};
@@ -11,4 +11,3 @@ const handler: APIGatewayProxyHandler = (event, context, callback) => {
1111
};
1212
};
1313

14-
export default handler;

remove/scalewayRemove.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ class ScalewayDeploy {
1111
this.provider = this.serverless.getProvider('scaleway');
1212

1313
Object.assign(
14-
this,
15-
setUpDeployment,
16-
removeNamespace,
17-
namespaceUtils,
18-
validate,
14+
this,
15+
setUpDeployment,
16+
removeNamespace,
17+
namespaceUtils,
18+
validate,
1919
);
2020

2121
this.hooks = {
2222
// Validate serverless.yml, set up default values, configure deployment...
2323
'before:remove:remove': () => BbPromise.bind(this)
2424
.then(this.provider.initialize(this.serverless, this.options))
25-
.then(this.validate)
26-
.then(this.setUpDeployment),
25+
.then(this.setUpDeployment)
26+
.then(this.validate),
2727
// Every tasks related to space deletion:
2828
// - Delete given space if it exists
2929
'remove:remove': () => BbPromise.bind(this)

shared/setUpDeployment.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module.exports = {
22
setUpDeployment() {
3-
const service = this.provider.serverless.service;
4-
const provider = service.provider;
3+
const { service } = this.provider.serverless;
4+
const { provider } = service;
55
this.namespaceName = service.service;
66
this.namespaceVariables = provider.env || {};
77
this.runtime = provider.runtime;

shared/validate.js

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ const BbPromise = require('bluebird');
44
const fs = require('fs');
55
const path = require('path');
66

7+
const RUNTIMES_EXTENSIONS = {
8+
node8: ['ts', 'js'],
9+
node10: ['ts', 'js'],
10+
python: ['py'],
11+
python3: ['py'],
12+
golang: ['go'],
13+
};
14+
715
module.exports = {
816
validate() {
917
return BbPromise.bind(this)
@@ -55,6 +63,20 @@ module.exports = {
5563
let containerNames = [];
5664

5765
const currentErrors = Array.isArray(errors) ? errors : [];
66+
const functionErrors = [];
67+
let containers = [];
68+
69+
const { functions } = this.serverless.service;
70+
if (functions && Object.keys(functions).length !== 0) {
71+
functionNames = Object.keys(functions);
72+
73+
// Check that runtime is authorized
74+
const extensions = RUNTIMES_EXTENSIONS[this.runtime];
75+
if (!extensions) {
76+
const availableRuntimesMessage = Object.keys(RUNTIMES_EXTENSIONS).join(', ');
77+
functionErrors.push(`Runtime ${this.runtime} is not supported. Function runtime must be one of the following: ${availableRuntimesMessage}`);
78+
}
79+
5880
let functionErrors = [];
5981
let containers = [];
6082

@@ -66,17 +88,36 @@ module.exports = {
6688
const func = functions[functionName];
6789
// Check if function handler exists
6890
try {
69-
if (!fs.existsSync(path.resolve('./', func.handler))) {
91+
// get handler file => path/to/file.handler => split ['path/to/file', 'handler']
92+
const splitHandlerPath = func.handler.split('.');
93+
if (splitHandlerPath.length !== 2) {
94+
throw new Error(`Handler is malformatted for ${functionName}: handler should be path/to/file.functionInsideFile`);
95+
}
96+
const handlerPath = splitHandlerPath[0];
97+
98+
// For each extensions linked to a language (node: .ts,.js, python: .py ...),
99+
// check that a handler file exists with one of the extensions
100+
let handlerFileExists = false;
101+
for (let i = 0; i < extensions.length; i += 1) {
102+
const extension = extensions[i];
103+
const handler = `${handlerPath}.${extension}`;
104+
if (fs.existsSync(path.resolve('./', handler))) {
105+
handlerFileExists = true;
106+
}
107+
}
108+
// If Handler file does not exist, throw an error
109+
if (!handlerFileExists) {
70110
throw new Error('File does not exists');
71111
}
72112
} catch (error) {
73-
const message = `Handler defined for function ${functionName} does not exist.`;
113+
const message = `Handler file defined for function ${functionName} does not exist (${func.handler}).`;
74114
functionErrors.push(message);
75115
}
76116
});
77117
}
78118

79119
if (this.serverless.service.custom) {
120+
// eslint-disable-next-line prefer-destructuring
80121
containers = this.serverless.service.custom.containers;
81122
}
82123
if (containers && Object.keys(containers).length !== 0) {

0 commit comments

Comments
 (0)