func main()

in tools/lambda-compat/cmd/lambda-build/main.go [249:379]


func main() {
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})

	exe, err := os.Executable()
	if err != nil {
		log.Fatal().Err(err).Msg("unable to determine binary location")
	}
	templateDir = fmt.Sprintf("%s/templates/", filepath.Dir(exe))

	log.Info().Msg("Lambda compatibility tool for Cloud Run")

	flag.StringVar(&templateDir, "template-dir", templateDir, "location of Dockerfile and Terraform templates")
	flag.StringVar(&targetDir, "target-dir", targetDir, "directory to create Dockerfile and Terraform files in")
	flag.BoolVar(&generateDockerfile, "dockerfile", true, "generate Dockerfile")
	flag.StringVar(&dockerfilePath, "dockerfile-path", dockerfilePath, "path and filename for Dockerfile")
	flag.BoolVar(&generateTerraform, "terraform", true, "generate Terraform files")
	flag.StringVar(&terraformPath, "terraform-path", terraformPath, "path for Terraform files")
	flag.StringVar(&projectId, "project-id", projectId, "GCP project ID")
	flag.StringVar(&containerRegistry, "registry", containerRegistry, "Container registry to use (eg. docker.pkg.dev/project-id/registry)")
	flag.StringVar(&containerTag, "tag", containerTag, "Container image tag")
	flag.Var(&additionalVars, "var", "Additional template variable (key=value)")
	flag.Var(&additionalVarsJson, "var-json", "Additional template variable in JSON (key={\"foo\":\"bar\"})")
	flag.Parse()

	if !strings.HasSuffix(templateDir, "/") {
		templateDir = templateDir + "/"
	}

	if _, err := os.Stat(templateDir + "common.tpl"); errors.Is(err, os.ErrNotExist) {
		if _, err := os.Stat(templateDir + "common.tpl"); errors.Is(err, os.ErrNotExist) {
			log.Info().Str("directory", templateDir).Msg("Creating template directory")
			err = os.MkdirAll(templateDir, 0770)
			if err != nil {
				log.Fatal().Err(err).Str("directory", templateDir).Msg("Failed to create template directory")
			}
		}
		templates := []string{
			"common.tpl",
			"dotnetcore.tpl",
			"go.tpl",
			"java.tpl",
			"nodejs.tpl",
			"python.tpl",
			"ruby.tpl",
			"terraform_main.tf.tpl",
			"terraform_outputs.tf.tpl",
			"terraform_variables.tf.tpl",
			"terraform_versions.tf.tpl",
		}
		log.Info().Str("directory", templateDir).Msg("Writing embedded templates to disk")
		for _, tpl := range templates {
			contents, err := fs.ReadFile(fmt.Sprintf("templates/%s", tpl))
			if err != nil {
				log.Fatal().Err(err).Msg("Failed to retrieve embedded template")
			}
			err = ioutil.WriteFile(fmt.Sprintf("%s/%s", templateDir, tpl), contents, 0664)
			if err != nil {
				log.Fatal().Err(err).Msg("Failed to write embedded template")
			}
		}

	}

	var containerBuilders []string = []string{
		"buildah",
		"podman",
		"nerdctl",
	}
	var containerBuilder string = "docker"
	for _, bin := range containerBuilders {
		_, err := exec.LookPath(bin)
		if err == nil {
			containerBuilder = bin
			break
		}
	}

	if !strings.HasSuffix(containerRegistry, "/") {
		containerRegistry = strings.TrimSuffix(containerRegistry, "/")
	}

	if len(flag.Args()) == 0 {
		log.Fatal().Msg("Specify at least one template to process")
	}

	for _, fileName := range flag.Args() {
		var template SamTemplate
		yamlFile, err := ioutil.ReadFile(fileName)
		if err != nil {
			log.Fatal().Str("file", fileName).Err(err).Msg("Failed to load configuration file")
		}
		err = yaml.Unmarshal(yamlFile, &template)
		if err != nil {
			log.Fatal().Str("file", fileName).Err(err).Msg("Failed to decode YAML")
		}
		log.Info().Str("file", fileName).Msg("Processing SAM template file")

		for name, resource := range template.Resources {
			if resource.Type == "AWS::Serverless::Function" {
				subdir := filepath.Clean(fmt.Sprintf("%s/%s", filepath.Clean(targetDir), name)) + "/"
				if generateDockerfile {
					ensureDirectory(subdir)
					dockerfile := fmt.Sprintf("%s%s", subdir, dockerfilePath)

					err := resource.renderDockerfile(name, dockerfile)
					if err != nil {
						log.Fatal().Str("file", fileName).Str("resource", name).Err(err).Msg("Failed to render Dockerfile for resource")
					}
					if containerRegistry != "" {
						log.Info().Msg("To build container, run:")
						log.Info().Msg(fmt.Sprintf("  %s build -t %s/%s:%s -f %s/Dockerfile .", containerBuilder, containerRegistry, strings.ToLower(name), containerTag, name))
					}
				}

				if generateTerraform {
					terraformSubdir := fmt.Sprintf("%s%s", subdir, terraformPath)
					ensureDirectory(terraformSubdir)

					err := resource.renderTerraform(name, terraformSubdir)
					if err != nil {
						log.Fatal().Str("file", fileName).Str("resource", name).Err(err).Msg("Failed to render Terraform for resource")
					}
				}

			} else {
				log.Debug().Str("type", resource.Type).Msg("Unknown resource type ignored")
			}
		}

	}
}