Skip to content

Commit

Permalink
fix: handle projects using Go module vendoring
Browse files Browse the repository at this point in the history
The call to install `github.com/icarus-sullivan/mock-lambda` will fail
in a Go project that is using vendoring
(https://go.dev/ref/mod#vendoring) as the subsequent `go build` command
will error like so:

    go: inconsistent vendoring in /path/dev/nimble:
        github.com/icarus-sullivan/mock-lambda@v0.0.0-20220115083805-e065469e964a: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt

        To ignore the vendor directory, use -mod=readonly or -mod=mod.
        To sync the vendor directory, run:
                go mod vendor

This change detects if `vendor/` is present and then will re-run
`go mod vendor` after the installation of `mock-lambda` to ensure that
building succeeds.

This also raises any exceptions that occur within either of these
install/build commands so it is obvious what problem is occurring.
Previously, this error was swallowed and passed silently, until causing
a failure to call the non-existent `./tmp`
executable with `execa(`./tmp`)`:

    Error: Command failed with ENOENT: ./tmp  spawn ./tmp ENOENT

With this PR, the above error for `go mod vendor` is outputted instead.
  • Loading branch information
davidjb committed Mar 7, 2023
1 parent 5b198a7 commit c9c23e2
Showing 1 changed file with 19 additions and 4 deletions.
23 changes: 19 additions & 4 deletions src/lambda/handler-runner/go-runner/GoRunner.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { mkdir, readFile, rm, rmdir, writeFile } from 'node:fs/promises'
import { access, mkdir, readFile, rm, rmdir, writeFile } from 'node:fs/promises'
import { EOL } from 'node:os'
import process, { chdir, cwd } from 'node:process'
import { parse as pathParse, resolve, sep } from 'node:path'
import { parse as pathParse, join as pathJoin, resolve, sep } from 'node:path'
import { log } from '@serverless/utils/log.js'
import { execa } from 'execa'
import { splitHandlerPathAndName } from '../../../utils/index.js'
Expand Down Expand Up @@ -119,6 +119,15 @@ export default class GoRunner {
}, {})
}

// Check if Go vendoring is enabled for modules
let goVendoringEnabled = false
try {
await access(pathJoin(cwd(), 'vendor'))
goVendoringEnabled = true
} catch {
// @ignore
}

// Remove our root, since we want to invoke go relatively
const cwdPath = `${this.#tmpFile}`.replace(`${cwd()}${sep}`, '')

Expand All @@ -130,9 +139,15 @@ export default class GoRunner {
'get',
'github.com/icarus-sullivan/mock-lambda@e065469',
])
if (goVendoringEnabled) {
await execa('go', ['mod', 'vendor'])
}

await execa('go', ['build'])
} catch {
// @ignore
} catch (err) {
log.error(err.stderr)

throw err
}

const { stdout, stderr } = await execa(`./tmp`, {
Expand Down

0 comments on commit c9c23e2

Please sign in to comment.