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
}