func()

in generate/generate.go [276:396]


func (rg *ResourceGenerator) generateResources(name string, resource Resource, isCustomProperty bool, spec *CloudFormationResourceSpecification) error {

	// Open the resource template
	tmpl, err := template.ParseFiles("generate/templates/resource.template")
	if err != nil {
		return fmt.Errorf("failed to load resource template: %s", err)
	}

	// Check if this resource type allows specifying a CloudFormation UpdatePolicy
	hasUpdatePolicy := false
	for _, res := range ResourcesThatSupportUpdatePolicies {
		if name == res {
			hasUpdatePolicy = true
			break
		}
	}

	// Check if this resource type allows specifying a CloudFormation CreationPolicy
	hasCreationPolicy := false
	for _, res := range ResourcesThatSupportCreationPolicies {
		if name == res {
			hasCreationPolicy = true
			break
		}
	}

	// Check if this resource has any tag properties
	// note: the property might not always be called 'Tags'
	// see: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-schedule.html#cfn-dlm-lifecyclepolicy-schedule-tagstoadd
	hasTags := false
	for _, property := range resource.Properties {
		if property.ItemType == "Tag" {
			hasTags = true
			break
		}
	}

	// Pass in the following information into the template
	sname, err := structName(name)
	if err != nil {
		return err
	}

	pname, err := packageName(name, true)
	if err != nil {
		return err
	}

	nameParts := strings.Split(name, "::")
	nameParts = strings.Split(nameParts[len(nameParts)-1], ".")
	basename := nameParts[0]

	templateData := struct {
		Name              string
		PackageName       string
		StructName        string
		Basename          string
		Resource          Resource
		IsCustomProperty  bool
		Version           string
		HasUpdatePolicy   bool
		HasCreationPolicy bool
		HasTags           bool
	}{
		Name:              name,
		PackageName:       pname,
		StructName:        sname,
		Basename:          basename,
		Resource:          resource,
		IsCustomProperty:  isCustomProperty,
		Version:           spec.ResourceSpecificationVersion,
		HasUpdatePolicy:   hasUpdatePolicy,
		HasCreationPolicy: hasCreationPolicy,
		HasTags:           hasTags,
	}

	// Execute the template, writing it to a buffer
	var buf bytes.Buffer
	err = tmpl.Execute(&buf, templateData)
	if err != nil {
		return fmt.Errorf("failed to generate resource %s: %s", name, err)
	}

	// Format the generated Go code with gofmt
	formatted, err := format.Source(buf.Bytes())
	if err != nil {
		fmt.Println(string(buf.Bytes()))
		return fmt.Errorf("failed to format Go file for resource %s: %s", name, err)
	}

	// Check if the file has changed since the last time generate ran
	dir := "cloudformation/" + pname
	fn := dir + "/" + filename(name)
	current, err := ioutil.ReadFile(fn)

	if err != nil || bytes.Compare(formatted, current) != 0 {

		// Create the directory if it doesn't exist
		if _, err := os.Stat(dir); os.IsNotExist(err) {
			os.Mkdir(dir, 0755)
		}

		// Write the file contents out
		if err := ioutil.WriteFile(fn, formatted, 0644); err != nil {
			return fmt.Errorf("failed to write resource file %s: %s", fn, err)
		}
		// Log the updated resource name to the results
		rg.Results.UpdatedResources = append(rg.Results.UpdatedResources, GeneratedResource{
			Name:        name,
			BaseName:    basename,
			PackageName: pname,
			StructName:  sname,
		})

	}

	rg.Results.ProcessedCount++

	return nil

}