Skip to content

Commit

Permalink
Merge pull request #4449 from hashicorp/generator-go-sdk/optionally-d…
Browse files Browse the repository at this point in the history
…elete-definitions-for-version

generator-go-sdk: allow configurable deletion of existing resources within an API version prior to generation, and enable for Microsoft Graph
  • Loading branch information
manicminer authored Sep 26, 2024
2 parents f93bb90 + 3b6a655 commit e8ce64f
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 28 deletions.
13 changes: 13 additions & 0 deletions tools/generator-go-sdk/internal/cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func (g GenerateCommand) Run(args []string) int {

if g.sourceDataType == models.MicrosoftGraphSourceDataType {
input.settings.AllowOmittingDiscriminatedValue = true
input.settings.DeleteExistingResourcesForVersion = true
input.settings.GenerateDescriptionsForModels = true
input.settings.RecurseParentModels = false

Expand All @@ -73,6 +74,7 @@ func (g GenerateCommand) Run(args []string) int {
}
} else if g.sourceDataType == models.ResourceManagerSourceDataType {
input.settings.AllowOmittingDiscriminatedValue = false
input.settings.DeleteExistingResourcesForVersion = false
input.settings.GenerateDescriptionsForModels = false
input.settings.RecurseParentModels = true

Expand Down Expand Up @@ -170,6 +172,17 @@ func (g GenerateCommand) run(ctx context.Context, input GeneratorInput) error {
commonTypes = v
}

if input.settings.DeleteExistingResourcesForVersion {
logging.Debugf("Deleting existing definitions for Service %q / Version %q", serviceName, versionNumber)
servicePackageName := strings.ToLower(serviceName)
versionDirectoryName := strings.ToLower(versionNumber)
versionOutputPath := filepath.Join(input.outputDirectory, servicePackageName, versionDirectoryName)
if err = generator.CleanAndRecreateWorkingDirectory(versionOutputPath); err != nil {
addErr(fmt.Errorf("cleaning/recreating working directory %q: %+v", versionOutputPath, err))
return
}
}

for resourceName, resourceDetails := range versionDetails.Resources {
logging.Debugf(" Resource %q", resourceName)
serviceGeneratorInput := generator.ServiceGeneratorInput{
Expand Down
20 changes: 20 additions & 0 deletions tools/generator-go-sdk/internal/generator/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,31 @@ package generator

import (
"fmt"
"os"
"strings"

"github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
)

func CleanAndRecreateWorkingDirectory(path string) error {
// rm -r 💥
if err := os.RemoveAll(path); err != nil {
return fmt.Errorf("deleting %q: %+v", path, err)
}

return EnsureWorkingDirectoryExists(path)
}

func EnsureWorkingDirectoryExists(path string) error {
if err := os.MkdirAll(path, 0777); err != nil {
if !os.IsExist(err) {
return fmt.Errorf("creating %q: %+v", path, err)
}
}

return nil
}

func alternateCasingOnEveryLetter(input string) string {
output := ""
caps := false
Expand Down
24 changes: 2 additions & 22 deletions tools/generator-go-sdk/internal/generator/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package generator

import (
"fmt"
"os"
"os/exec"

"github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
Expand Down Expand Up @@ -38,7 +37,7 @@ type ServiceGeneratorInput struct {
func (s *Generator) Generate(input ServiceGeneratorInput) error {
data := input.generatorData(s.settings)

if err := cleanAndRecreateWorkingDirectory(data.resourceOutputPath); err != nil {
if err := CleanAndRecreateWorkingDirectory(data.resourceOutputPath); err != nil {
return fmt.Errorf("cleaning/recreating working directory %q: %+v", data.resourceOutputPath, err)
}

Expand Down Expand Up @@ -98,7 +97,7 @@ func (s *Generator) GenerateForVersion(input VersionGeneratorInput) error {
func (s *Generator) GenerateCommonTypes(input VersionGeneratorInput) error {
data := input.generatorData(s.settings)

if err := cleanAndRecreateWorkingDirectory(data.commonTypesOutputPath); err != nil {
if err := CleanAndRecreateWorkingDirectory(data.commonTypesOutputPath); err != nil {
return fmt.Errorf("cleaning/recreating working directory %q: %+v", data.commonTypesOutputPath, err)
}

Expand Down Expand Up @@ -131,22 +130,3 @@ func runGoImports(path string) {
_ = cmd.Start()
_ = cmd.Wait()
}

func cleanAndRecreateWorkingDirectory(path string) error {
// rm -r 💥
if err := os.RemoveAll(path); err != nil {
return fmt.Errorf("deleting %q: %+v", path, err)
}

return ensureWorkingDirectoryExists(path)
}

func ensureWorkingDirectoryExists(path string) error {
if err := os.MkdirAll(path, 0777); err != nil {
if !os.IsExist(err) {
return fmt.Errorf("creating %q: %+v", path, err)
}
}

return nil
}
37 changes: 31 additions & 6 deletions tools/generator-go-sdk/internal/generator/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,38 @@ import (
)

type Settings struct {
CanonicalApiVersions map[string]string
CommonTypesPackageName string
// Whether model structs should have an `OmitDiscriminatedValue` field, to allow the caller to omit the
// discriminated type value when marhalling. Used in Microsoft Graph for buggy APIs that don't parse this.
AllowOmittingDiscriminatedValue bool
GenerateDescriptionsForModels bool
RecurseParentModels bool
VersionsToGenerateCommonTypes map[string]models.SourceDataOrigin
servicesUsingOldBaseLayer map[string]struct{}

// CanonicalApiVersions is a map of API version names to use in the SDK, where the key is the SDK-friendly
// name, and the value is the upstream API version. Used in Microsoft Graph to translate `v1.0` to `stable`.
CanonicalApiVersions map[string]string

// CommonTypesPackageName is the name of the Go package that should be output with common models, constants
// and resource IDs. Each API version will get a package below this containing the respective types. Used
// in Microsoft Graph. Could be used in Resource Manager or other SDKs.
CommonTypesPackageName string

// DeleteExistingResourcesForVersion toggles whether any existing resources within a given API version should
// be removed prior to generating. This is not compatible when more than one SourceDataType is being used to
// generate an SDK. Used in Microsoft Graph because breaking removals are allowed.
DeleteExistingResourcesForVersion bool

// GenerateDescriptionsForModels enables nicely-formatted Go comments for model fields to be generated.
GenerateDescriptionsForModels bool

// RecurseParentModels is a behavioral toggle for discriminated types. When true, the full ancestry for child
// models will be output in the SDK. When false, only the youngest ancestor containing the necessary type
// information will be output. Used in Microsoft Graph to properly express model inheritance.
RecurseParentModels bool

// VersionsToGenerateCommonTypes is a map of API versions to SourceDataOrigin, to specify the API versions
// for which common types should be generated. This is necessary because common types are enumerated separately
// from service definitions. Used in Microsoft Graph.
VersionsToGenerateCommonTypes map[string]models.SourceDataOrigin

servicesUsingOldBaseLayer map[string]struct{}
}

func (s *Settings) CanonicalApiVersion(version string) *string {
Expand Down

0 comments on commit e8ce64f

Please sign in to comment.