in cmd/go/functions_framework/main.go [151:224]
func createMainGoMod(ctx *gcp.Context, fn fnInfo) error {
l, err := ctx.Layer(gopathLayerName, gcp.BuildLayer)
if err != nil {
return fmt.Errorf("creating %v layer: %w", gopathLayerName, err)
}
l.BuildEnvironment.Override("GOPATH", l.Path)
if err := ctx.Setenv("GOPATH", l.Path); err != nil {
return err
}
goSumExists, err := ctx.FileExists(fn.Source, "go.sum")
if err != nil {
return err
}
// If the function source does not include a go.sum, `go list` will fail under Go 1.16+.
if !goSumExists {
ctx.Logf(`go.sum not found, generating using "go mod tidy"`)
if _, err := golang.ExecWithGoproxyFallback(ctx, []string{"go", "mod", "tidy"}, gcp.WithWorkDir(fn.Source), gcp.WithUserAttribution); err != nil {
return fmt.Errorf("running go mod tiny: %w", err)
}
}
_, fnPackage, err := moduleAndPackageNames(ctx, fn)
if err != nil {
return fmt.Errorf("extracting module and package names: %w", err)
}
fn.Package = fnPackage
// If the framework is not present in the function's go.mod, we require the current version.
version, err := frameworkSpecifiedVersion(ctx, fn.Source)
if err != nil {
return fmt.Errorf("checking for functions framework dependency in go.mod: %w", err)
}
injected := false
if version == "" {
if err := cloudfunctions.AssertFrameworkInjectionAllowed(); err != nil {
return err
}
if _, err := ctx.Exec([]string{"go", "mod", "edit", "-require", fmt.Sprintf("%s@%s", functionsFrameworkModule, functionsFrameworkVersion)}, gcp.WithWorkDir(fn.Source), gcp.WithLogCommand(true)); err != nil {
return err
}
version = functionsFrameworkVersion
injected = true
}
cloudfunctions.AddFrameworkVersionLabel(ctx, &cloudfunctions.FrameworkVersionInfo{
Runtime: "go",
Version: version,
Injected: injected,
})
mainPackageDirectory := filepath.Join(fn.Source, appModule)
if err := ctx.MkdirAll(mainPackageDirectory, 0755); err != nil {
return err
}
fnSourceMain := filepath.Join(mainPackageDirectory, "main.go")
if err := createMainGoFile(ctx, fn, fnSourceMain, version); err != nil {
return err
}
// Generate a go.sum entry which is required starting with Go 1.16.
// We generate a go.mod file dynamically since the function may request a specific version of
// the framework, in which case we want to import that version. For that reason we cannot
// include a pre-generated go.sum file.
if _, err := golang.ExecWithGoproxyFallback(ctx, []string{"go", "mod", "tidy"}, gcp.WithUserAttribution, gcp.WithWorkDir(fn.Source)); err != nil {
return fmt.Errorf("running go mod tidy: %w", err)
}
// Make function's source the work directory when running go build
l.BuildEnvironment.Override(golang.BuildDirEnv, fn.Source)
// Specify what to build in the go build buildpack
l.BuildEnvironment.Override(env.Buildable, mainPackageDirectory)
return nil
}