func createMainGoMod()

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
}