From 16938246ac6ef41b1b30a8440f98d32199d9be8f Mon Sep 17 00:00:00 2001 From: Karagulamos Date: Tue, 29 Mar 2022 18:52:13 +0100 Subject: [PATCH] feat: add local dev support for Go scheduled functions (#4491) * fix: detection for Go scheduled functions * fix: incompatible fs import * chore: fix conventional message error * fix: parse schedule from config * fix: unsupported optional chaining * fix: broken function test without config * chore: fix prettier warnings * fix: additional checks in NetlifyFunction * feat: assert valid next_run in test * chore: update names and tests --- src/lib/functions/netlify-function.js | 6 +- src/lib/functions/registry.js | 1 + .../integration/20.command.functions.test.js | 1 + .../630.serving-functions-go.test.js | 74 +++++++++++++++++++ 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/lib/functions/netlify-function.js b/src/lib/functions/netlify-function.js index 29a4a06320c..15c93d22bf8 100644 --- a/src/lib/functions/netlify-function.js +++ b/src/lib/functions/netlify-function.js @@ -41,7 +41,9 @@ class NetlifyFunction { // Determines whether this is a background function based on the function // name. this.isBackground = name.endsWith(BACKGROUND_SUFFIX) - this.schedule = null + + const functionConfig = config.functions && config.functions[name] + this.schedule = functionConfig && functionConfig.schedule // List of the function's source files. This starts out as an empty set // and will get populated on every build. @@ -91,7 +93,7 @@ class NetlifyFunction { this.buildData = buildData this.srcFiles = srcFilesSet - this.schedule = schedule + this.schedule = schedule || this.schedule return { srcFilesDiff } } catch (error) { diff --git a/src/lib/functions/registry.js b/src/lib/functions/registry.js index 01a937d1053..c6e44d1d98e 100644 --- a/src/lib/functions/registry.js +++ b/src/lib/functions/registry.js @@ -177,6 +177,7 @@ class FunctionsRegistry { buildGoSource: true, buildRustSource: env.NETLIFY_EXPERIMENTAL_BUILD_RUST_SOURCE === 'true', }, + config: this.config, }) // Before registering any functions, we look for any functions that were on diff --git a/tests/integration/20.command.functions.test.js b/tests/integration/20.command.functions.test.js index d35271adcb4..d492aada239 100644 --- a/tests/integration/20.command.functions.test.js +++ b/tests/integration/20.command.functions.test.js @@ -31,6 +31,7 @@ test('should return the correct function url for a NetlifyFunction object', (t) const ntlFunction = new NetlifyFunction({ name: functionName, settings: { functionsPort: port }, + config: { functions: { [functionName]: {} } }, }) t.is(ntlFunction.url, functionUrl) diff --git a/tests/integration/630.serving-functions-go.test.js b/tests/integration/630.serving-functions-go.test.js index ef26622386a..8229b691fa1 100644 --- a/tests/integration/630.serving-functions-go.test.js +++ b/tests/integration/630.serving-functions-go.test.js @@ -112,3 +112,77 @@ test('Updates a Go function when a file is modified', async (t) => { } }) }) + +// Reproduction test to verify the abscence/presence of a Go scheduled function +test('Detects a Go scheduled function using netlify-toml config', async (t) => { + const [execaMock, removeExecaMock] = await createExecaMock(` + const assert = require('assert') + + const handler = (...args) => { + if (args[0].includes('local-functions-proxy')) { + const { body } = JSON.parse(args[1][1]) + const { next_run } = JSON.parse(body) + + assert.ok(next_run) + + const response = { + statusCode: 200 + } + + return { + stderr: '', + stdout: JSON.stringify(response) + } + } + } + + module.exports = (...args) => ({ + ...handler(...args) || {}, + stderr: { pipe: () => {} } + }) + `) + + await withSiteBuilder('go-scheduled-function', async (builder) => { + try { + await builder + .withNetlifyToml({ + config: { + build: { publish: 'public' }, + functions: { directory: 'src/', 'go-scheduled-function': { schedule: '@daily' } }, + }, + }) + .withContentFiles([ + { + path: 'go.mod', + content: ``, + }, + { + path: 'go.sum', + content: ``, + }, + { + path: 'src/go-scheduled-function/main.go', + content: ``, + }, + ]) + .buildAsync() + + await withDevServer( + { + cwd: builder.directory, + env: execaMock, + }, + async ({ port }) => { + const response = await got(`http://localhost:${port}/.netlify/functions/go-scheduled-function`) + + t.regex(response.body, /You performed an HTTP request/) + t.regex(response.body, /Your function returned `body`/) + + t.is(response.statusCode, 200) + }, + ) + } finally { + await removeExecaMock() + } + }) +})