Gcloud 函数部署找不到 Golang 模板文件

Gcloud functions deployment doesn't find Golang template files

我写了一些 Golang 代码,在我的本地机器上测试时可以正常工作。当我将其部署为 Google 云函数时,它失败了,因为它无法打开模板文件。失败的代码行是:

    t, err := template.New("list.gohtml").ParseFiles("list.gohtml")

此调用后 err 设置为 open list.gohtml: no such file or directory

该文件与go源文件在同一目录下,未在.gcloudignore.gitignore中列出。 gcloud 函数文档说目录中的所有文件都将被上传,除非在这些忽略文件之一中列出,如果我 运行 gcloud meta list-files-for-upload 那么文件 list.gohtml 包含在显示的列表中。

是否有一些神奇的文件夹布局可以实现此功能,或者 gcloud functions deploy 命令的选项?

我创建了一个枚举上传文件的函数:

func L(w http.ResponseWriter, r *http.Request) {
    var files []string

    err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
        files = append(files, path)
        return nil
    })
    if err != nil {
        panic(err)
    }
    for _, file := range files {
        fmt.Fprintln(w, file)
    }
}

输出:

.
go.mod
go.sum
main.go
serverless_function_source_code
serverless_function_source_code/f.go
serverless_function_source_code/go.mod
serverless_function_source_code/test.tmpl

重写使用模板的函数:

tmpl, err := template.New("test.tmpl").ParseFiles("serverless_function_source_code/test.tmpl")

有效!

但是,这是未记录的并且是黑客 :-(

另一种方法是将模板作为字符串嵌入到 Golang 文件中。

我建议在 Google 的 Cloud Functions

问题跟踪器上提交功能请求

根据@DazWilkin 的回复,我现在在服务函数开始时调用下面的函数。

而不是将路径硬连接到模板文件名中(这会导致在本地测试时失败),这只是检查当前文件下面是否存在 Gcloud source file directory,如果存在,则将其设为工作目录,因此文件解析现在将与在本地测试时完全一样。

import "os"

const gcloudFuncSourceDir = "serverless_function_source_code"

func fixDir() {
    fileInfo, err := os.Stat(gcloudFuncSourceDir)
    if err == nil && fileInfo.IsDir() {
        _ = os.Chdir(gcloudFuncSourceDir)
    }
}

如果没有 go.mod 文件(换句话说,如果未启用模块),则行为会改变并且文件位于 src/<package-name>/ 下,而不是 serverless_function_source_code/ 下。用于驱动云函数的 main.go 文件位于 src/serverless_function_app/main/main.go.

例如:

我有一个包含以下两个文件的 Go 应用程序:

listfiles/file_system.go
listfiles/tmpl/letter.html

我用这些命令部署了它:

cd listfiles
gcloud functions deploy ListFiles --runtime go113 --trigger-http --allow-unauthenticated

结果是当前目录设置为/srv/srv 下面是一个典型的 GOROOT 树,其中包含 src/pkg/ 目录。例如:

.googlebuild
.googlebuild/source-code.tar.gz
pkg
pkg/linux_amd64
pkg/linux_amd64/github.com
pkg/linux_amd64/github.com/GoogleCloudPlatform
pkg/linux_amd64/github.com/GoogleCloudPlatform/functions-framework-go
pkg/linux_amd64/github.com/GoogleCloudPlatform/functions-framework-go/funcframework.a
src
src/cloud.google.com
src/cloud.google.com/go
src/cloud.google.com/go/.git
src/cloud.google.com/go/.git/HEAD
src/cloud.google.com/go/.git/branches
[... snip...]
src/go.uber.org/zap/zaptest/testingt_test.go
src/go.uber.org/zap/zaptest/timeout.go
src/go.uber.org/zap/zaptest/timeout_test.go
src/go.uber.org/zap/zaptest/writer.go
src/go.uber.org/zap/zaptest/writer_test.go
src/listfiles
src/listfiles/file_system.go
src/listfiles/tmpl
src/listfiles/tmpl/letter.html
src/serverless_function_app
src/serverless_function_app/main
src/serverless_function_app/main/main.go