diff --git a/Gopkg.lock b/Gopkg.lock index eaa5233..6d0675f 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -15,8 +15,8 @@ "services/resources/mgmt/2017-05-10/resources", "version" ] - revision = "cd93ccfe0395e70031704ca68f14606588eec120" - version = "v17.3.0" + revision = "7971189ecf5a584b9211f2527737f94bb979644e" + version = "v17.4.0" [[projects]] name = "github.com/Azure/go-autorest" @@ -28,8 +28,8 @@ "autorest/to", "autorest/validation" ] - revision = "76796dcb80ab6491bf22e344402023c081a7a282" - version = "v10.11.1" + revision = "1f7cd6cfe0adea687ad44a512dfe76140f804318" + version = "v10.12.0" [[projects]] branch = "master" @@ -90,8 +90,17 @@ [[projects]] name = "github.com/gobuffalo/envy" packages = ["."] - revision = "ef60bfc50c8f92d1ee64674d8ce7a48f1f67625e" - version = "v1.6.2" + revision = "2d0f467653f3d961ce9ada4d32a230bdcb3bfe11" + version = "v1.6.3" + +[[projects]] + name = "github.com/gobuffalo/fizz" + packages = [ + ".", + "translators" + ] + revision = "25461ee937655cd1136523f6653d5bd15343cc48" + version = "v1.0.1" [[projects]] name = "github.com/gobuffalo/makr" @@ -114,8 +123,8 @@ "parser", "token" ] - revision = "b0b0a05f963a529b49d835f868fa1e2b92f4b144" - version = "v3.7.4" + revision = "2ec029f415ed9a8a1448a5bb389d79084d606035" + version = "v3.7.7" [[projects]] name = "github.com/gobuffalo/pop" @@ -123,12 +132,11 @@ ".", "associations", "columns", - "fizz", - "fizz/translators", + "fix", "nulls" ] - revision = "9985012f32f5e36b1a10e9191ee460daac4a9bc7" - version = "v4.5.9" + revision = "66130dbcd030ea900e35e45e03dd1a59577d2e99" + version = "v4.5.12" [[projects]] name = "github.com/gobuffalo/tags" @@ -137,8 +145,8 @@ "form", "form/bootstrap" ] - revision = "82cd7696c84aba829b74e81814ff489b64e7b56a" - version = "v2.0.5" + revision = "96c7cdfcadcb28eb1b42b9080ba7f93936ffc5c5" + version = "v2.0.7" [[projects]] name = "github.com/gobuffalo/uuid" @@ -221,7 +229,7 @@ ".", "reflectx" ] - revision = "2aeb6a910c2b94f2d5eb53d9895d80e27264ec41" + revision = "0dae4fefe7c0e190f7b5a78dac28a1c82cc8d849" [[projects]] name = "github.com/joho/godotenv" @@ -245,7 +253,6 @@ version = "v1.8.0" [[projects]] - branch = "master" name = "github.com/markbates/going" packages = [ "defaults", @@ -253,18 +260,19 @@ "wait" ] revision = "0576708c56cea02331f864fe6e157ac7841923e4" + version = "v1.0.0" [[projects]] - branch = "master" name = "github.com/markbates/grift" packages = ["grift"] revision = "76f93617a788d350124f749acb3790276a436cc0" + version = "v1.0.0" [[projects]] - branch = "master" name = "github.com/markbates/inflect" packages = ["."] revision = "dd7de90c06bca70f18136e59dec2270c19a401e7" + version = "v1.0.0" [[projects]] name = "github.com/markbates/refresh" @@ -293,17 +301,6 @@ packages = ["."] revision = "48a63b6052f1f9373db9388a658da30c6ab53db1" -[[projects]] - name = "github.com/mattn/anko" - packages = [ - "ast", - "core", - "parser", - "vm" - ] - revision = "e9c5c0ca86cf129292c56ddbddc4fff027844d65" - version = "v0.0.4" - [[projects]] name = "github.com/mattn/go-colorable" packages = ["."] @@ -319,14 +316,14 @@ [[projects]] name = "github.com/mattn/go-sqlite3" packages = ["."] - revision = "323a32be5a2421b8c7087225079c6c900ec397cd" - version = "v1.7.0" + revision = "25ecb14adfc7543176f7d85291ec7dba82c6f7e4" + version = "v1.9.0" [[projects]] branch = "master" name = "github.com/microcosm-cc/bluemonday" packages = ["."] - revision = "995366fdf961d03629cd17361bddd32745718e2c" + revision = "f0761eb8ed07c1cc892ef631b00c33463b9b6868" [[projects]] branch = "master" @@ -494,7 +491,7 @@ "blowfish", "ssh/terminal" ] - revision = "8ac0e0d97ce45cd83d1d7243c060cb8461dda5e9" + revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602" [[projects]] branch = "master" @@ -504,7 +501,7 @@ "html", "html/atom" ] - revision = "db08ff08e8622530d9ed3a0e8ac279f6d4c02196" + revision = "87b3feba568e144938625fc5d80ec92566c1a8fe" [[projects]] branch = "master" @@ -519,7 +516,7 @@ "unix", "windows" ] - revision = "bff228c7b664c5fce602223a05fb708fd8654986" + revision = "7138fd3d9dc8335c567ca206f4333fb75eb05d56" [[projects]] name = "golang.org/x/text" @@ -537,8 +534,8 @@ [[projects]] name = "google.golang.org/appengine" packages = ["cloudsql"] - revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a" - version = "v1.0.0" + revision = "b1f26356af11148e710935ed1ac8a7f5702c7612" + version = "v1.1.0" [[projects]] name = "gopkg.in/yaml.v2" @@ -549,6 +546,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "b735a8f4099268006777df3205705fac3423a7666a61f92eeba515d365aac5b7" + inputs-digest = "0ca276e99bfba052cf9d07bc5e408c494fce5cc8b82106feec5601f108cd5b4d" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 7810490..29b115b 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -27,11 +27,11 @@ [[constraint]] name = "github.com/gobuffalo/buffalo" - version = "0.11.0" + version = "~0.11.0" [[constraint]] name = "github.com/gobuffalo/uuid" - version = "2.0.0" + version = "^2.0.0" [[constraint]] branch = "master" @@ -43,7 +43,11 @@ [[constraint]] name = "github.com/spf13/viper" - version = "1.0.2" + version = "^1.0.2" + +[[constraint]] + name = "github.com/joho/godotenv" + version = "^1.2.0" [prune] go-tests = true diff --git a/cmd/provision.go b/cmd/provision.go index 24393ed..f029e6d 100644 --- a/cmd/provision.go +++ b/cmd/provision.go @@ -42,6 +42,7 @@ import ( "github.com/Azure/go-autorest/autorest/azure" "github.com/gobuffalo/buffalo/meta" "github.com/gobuffalo/pop" + "github.com/joho/godotenv" "github.com/marstr/randname" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -108,7 +109,7 @@ const ( const ( DatabaseAdminName = "db-admin" DatabaseAdminDefault = "buffaloAdmin" - databaseAdminUsage = "The user handle of the administratr account " + databaseAdminUsage = "The user handle of the administrator account." ) // These constants define a parameter which controls the password of the database provisioned. For marginal security, @@ -119,6 +120,7 @@ const ( DatabasePasswordShorthand = "w" DatabasePasswordDefault = "" databasePasswordUsage = "The administrator password for the database created. It is recommended you read this from a file instead of typing it in from your terminal." + DatabasePasswordEnvVar = "BUFFALO_AZURE_DATABASE_PASSWORD" ) // These constants define a parameter which allows control over the particular Azure cloud which should be used for @@ -255,8 +257,9 @@ const ( // These constants define a parameter which toggles whether or not to save the template used for deployment to disk. const ( - SkipTemplateCacheName = "skip-template-cache" - skipTemplateCacheUsage = "After downloading the default template, do NOT save it in the working directory." + SkipTemplateCacheName = "skip-template-cache" + SkipTemplateCacheShorthand = "z" + skipTemplateCacheUsage = "After downloading the default template, do NOT save it in the working directory." ) // These constants define a parameter which toggles whether or not to save the parameters used for deployment to disk. @@ -273,6 +276,41 @@ const ( skipDeploymentUsage = "Do not create an Azure deployment, do just the meta tasks." ) +// These constants define a parameter which controls the Docker registry that will be searched for the image provided. +const ( + DockerRegistryURLName = "docker-registry-url" + dockerRegistryURLUsage = "The URL for a private Docker Registry containing the image definition." +) + +// These constants define a parameter which allows the username to be set for Docker authentication. +const ( + DockerRegistryUsernameName = "docker-registry-username" + dockerRegistryUsernameUsage = "The user handle to allow access to a private docker registry." +) + +// These constants define a parameter which allows the password to be set for Docker authentication. +const ( + DockerRegistryPasswordName = "docker-registry-password" + dockerRegistryPasswordUsage = "The user password to allow access to a private docker registry." +) + +// DockerAccess is an enum that contains either "private" or "public" +type DockerAccess string + +// All (currently) possible value of DockerAccess +const ( + DockerAccessPublic = "public" + DockerAccessPrivate = "private" +) + +// These constants define a parameter which informs buffalo-azure whether the registry is public or +// private. +const ( + DockerRegistryAccessName = "docker-registry-access" + DockerRegistryAccessDefault = DockerAccessPublic + dockerRegistryAccessUsage = "Specifies whether the Docker registry targeted is " + DockerAccessPublic + " or " + DockerAccessPrivate +) + var status *log.Logger var errLog = newFormattedLog(os.Stderr, "error") var debugLog *log.Logger @@ -304,10 +342,15 @@ var provisionCmd = &cobra.Command{ ctx, cancel := context.WithTimeout(context.Background(), 45*time.Minute) defer cancel() - auth, err := getAuthorizer(ctx, subscriptionID, clientID, clientSecret, provisionConfig.GetString(TenantIDName)) - if err != nil { - errLog.Print("unable to authenticate: ", err) - return + var err error + var auth autorest.Authorizer + + if !provisionConfig.GetBool(SkipDeploymentName) { + auth, err = getAuthorizer(ctx, subscriptionID, clientID, clientSecret, provisionConfig.GetString(TenantIDName)) + if err != nil { + errLog.Print("unable to authenticate: ", err) + return + } } status.Print(TenantIDName+" selected: ", provisionConfig.GetString(TenantIDName)) status.Print(SubscriptionName+" selected: ", subscriptionID) @@ -317,34 +360,26 @@ var provisionCmd = &cobra.Command{ status.Println(DatabaseAdminName+" selected: ", databaseAdmin) if usingDB, dbPassword := !strings.EqualFold(provisionConfig.GetString(DatabaseTypeName), "none"), provisionConfig.GetString(DatabasePasswordName); usingDB && dbPassword == DatabasePasswordDefault { - provisionConfig.Set(DatabasePasswordName, randname.GenerateWithPrefix("MSFT+Buffalo-", 20)) + newPass := randname.GenerateWithPrefix("MSFT+Buffalo-", 20) + provisionConfig.Set(DatabasePasswordName, newPass) status.Println("generated database password") + var envMap map[string]string + const envFileLoc = "./.env" + if envMap, err = godotenv.Read(envFileLoc); err != nil { + envMap = make(map[string]string, 1) + } + envMap[DatabasePasswordEnvVar] = newPass + if err := godotenv.Write(envMap, envFileLoc); err == nil { + status.Printf("wrote database password to %q", envFileLoc) + } else { + errLog.Printf("unable to write database password to %q", envFileLoc) + } } else if usingDB { status.Println("using provided password") } status.Println(ImageName+" selected: ", image) - groups := resources.NewGroupsClient(subscriptionID) - groups.Authorizer = auth - groups.AddToUserAgent(userAgent) - - // Assert the presence of the specified Resource Group - rgName := provisionConfig.GetString(ResoureGroupName) - created, err := insertResourceGroup(ctx, groups, rgName, provisionConfig.GetString(LocationName)) - if err != nil { - errLog.Printf("unable to fetch or create resource group %s: %v\n", rgName, err) - return - } - if created { - status.Println("created resource group: ", rgName) - } else { - status.Println("found resource group: ", rgName) - } - status.Println("site name selected: ", siteName) - - pLink := portalLink(subscriptionID, rgName) - // Provision the necessary assets. deployParams.Parameters["name"] = DeploymentParameter{siteName} @@ -353,6 +388,10 @@ var provisionCmd = &cobra.Command{ deployParams.Parameters["imageName"] = DeploymentParameter{image} deployParams.Parameters["databaseAdministratorLogin"] = DeploymentParameter{databaseAdmin} deployParams.Parameters["databaseAdministratorLoginPassword"] = DeploymentParameter{provisionConfig.GetString(DatabasePasswordName)} + deployParams.Parameters["dockerRegistryAccess"] = DeploymentParameter{provisionConfig.GetString(DockerRegistryAccessName)} + deployParams.Parameters["dockerRegistryServerURL"] = DeploymentParameter{provisionConfig.GetString(DockerRegistryURLName)} + deployParams.Parameters["dockerRegistryServerUsername"] = DeploymentParameter{provisionConfig.GetString(DockerRegistryUsernameName)} + deployParams.Parameters["dockerRegistryServerPassword"] = DeploymentParameter{provisionConfig.GetString(DockerRegistryPasswordName)} template, err := getDeploymentTemplate(ctx, templateLocation) if err != nil { @@ -369,6 +408,27 @@ var provisionCmd = &cobra.Command{ } else { go func(errOut chan<- error) { defer close(errOut) + groups := resources.NewGroupsClient(subscriptionID) + groups.Authorizer = auth + groups.AddToUserAgent(userAgent) + + // Assert the presence of the specified Resource Group + rgName := provisionConfig.GetString(ResoureGroupName) + created, err := insertResourceGroup(ctx, groups, rgName, provisionConfig.GetString(LocationName)) + if err != nil { + errLog.Printf("unable to fetch or create resource group %s: %v\n", rgName, err) + errOut <- err + return + } + if created { + status.Println("created resource group: ", rgName) + } else { + status.Println("found resource group: ", rgName) + } + status.Println("site name selected: ", siteName) + + pLink := portalLink(subscriptionID, rgName) + status.Println("beginning deployment") if err := doDeployment(ctx, auth, subscriptionID, rgName, template); err == nil { fmt.Println("Check on your new Resource Group in the Azure Portal: ", pLink) @@ -404,7 +464,7 @@ var provisionCmd = &cobra.Command{ if provisionConfig.GetBool(SkipParameterCacheName) { close(parameterSaveResults) } else { - go doCache(ctx, parameterSaveResults, stripDBPassword(deployParams), TemplateParametersDefault, "parameters") + go doCache(ctx, parameterSaveResults, stripPasswords(deployParams), TemplateParametersDefault, "parameters") } waitOnResults := func(ctx context.Context, results <-chan error) error { @@ -480,7 +540,7 @@ var provisionCmd = &cobra.Command{ }, } -func stripDBPassword(original *DeploymentParameters) (copy *DeploymentParameters) { +func stripPasswords(original *DeploymentParameters) (copy *DeploymentParameters) { copy = NewDeploymentParameters() copy.Parameters = make(map[string]DeploymentParameter, len(original.Parameters)) copy.ContentVersion = original.ContentVersion @@ -490,6 +550,7 @@ func stripDBPassword(original *DeploymentParameters) (copy *DeploymentParameters copy.Parameters[k] = v } delete(copy.Parameters, "databaseAdministratorLoginPassword") + delete(copy.Parameters, "dockerRegistryServerPassword") return copy } @@ -498,6 +559,7 @@ func cache(ctx context.Context, contents interface{}, outputName string) error { defer handle.Close() enc := json.NewEncoder(handle) + enc.SetIndent("", " ") err = enc.Encode(contents) if err != nil { return err @@ -824,6 +886,22 @@ func setDefaults(conf *viper.Viper, params *DeploymentParameters) { if dbAdmin, ok := params.Parameters["databaseAdministratorLogin"]; ok { conf.SetDefault(DatabaseAdminName, dbAdmin.Value) } + + if dockerAccess, ok := params.Parameters["dockerRegistryAccess"]; ok { + conf.SetDefault(DockerRegistryAccessName, dockerAccess) + } + + if dockerURL, ok := params.Parameters["dockerRegistryServerURL"]; ok { + conf.SetDefault(DockerRegistryURLName, dockerURL) + } + + if dockerUsername, ok := params.Parameters["dockerRegistryServerUsername"]; ok { + conf.SetDefault(DockerRegistryUsernameName, dockerUsername) + } + + if dockerPassword, ok := params.Parameters["dockerRegistryServerPassword"]; ok { + conf.SetDefault(DockerRegistryPasswordName, dockerPassword) + } } func loadFromParameterFile(paramFile string) (*DeploymentParameters, error) { @@ -844,6 +922,7 @@ func loadFromParameterFile(paramFile string) (*DeploymentParameters, error) { } func init() { + const redactedMessage = "[redacted]" var debugWriter io.Writer if debug == "" { debugWriter = ioutil.Discard @@ -854,6 +933,8 @@ func init() { azureCmd.AddCommand(provisionCmd) + godotenv.Load() + // Here you will define your flags and configuration settings. // Cobra supports Persistent Flags which will work for this command @@ -870,6 +951,7 @@ func init() { provisionConfig.BindEnv(TenantIDName, "AZURE_TENANT_ID", "AZ_TENANT_ID") provisionConfig.BindEnv(EnvironmentName, "AZURE_ENVIRONMENT", "AZ_ENVIRONMENT") provisionConfig.BindEnv(ProfileName, "GO_ENV") + provisionConfig.BindEnv(DatabasePasswordName, DatabasePasswordEnvVar, "BUFFALO_AZURE_DB_PASSWORD", "BUFFALO_AZ_DATABASE_PASSWORD", "BUFFALO_AZ_DB_PASSWORD") provisionConfig.SetDefault(ProfileName, "development") @@ -888,6 +970,7 @@ func init() { provisionConfig.SetDefault(LocationName, LocationDefaultText) provisionConfig.SetDefault(SiteName, siteDefaultMessage) provisionConfig.SetDefault(TemplateParametersName, TemplateParametersDefault) + provisionConfig.SetDefault(DockerRegistryAccessName, DockerRegistryAccessDefault) var sanitizedClientSecret string if rawSecret := provisionConfig.GetString(ClientSecretName); rawSecret != "" { @@ -895,7 +978,7 @@ func init() { if len(rawSecret) > safeCharCount { sanitizedClientSecret = fmt.Sprintf("...%s", rawSecret[len(rawSecret)-safeCharCount:]) } else { - sanitizedClientSecret = "[key hidden]" + sanitizedClientSecret = redactedMessage } } @@ -912,6 +995,19 @@ func init() { deployParams = NewDeploymentParameters() } + dbPassText := provisionConfig.GetString(DatabasePasswordName) + if dbPassText == "" { + dbPassText = DatabasePasswordDefault + provisionConfig.SetDefault(DatabasePasswordName, DatabasePasswordDefault) + } else { + dbPassText = redactedMessage + } + + dockerPassText := provisionConfig.GetString(DockerRegistryPasswordName) + if dockerPassText != "" { + dockerPassText = redactedMessage + } + provisionCmd.Flags().StringP(ImageName, ImageShorthand, provisionConfig.GetString(ImageName), imageUsage) provisionCmd.Flags().StringP(TemplateName, TemplateShorthand, provisionConfig.GetString(TemplateName), templateUsage) provisionCmd.Flags().StringP(SubscriptionName, SubscriptionShorthand, provisionConfig.GetString(SubscriptionName), subscriptionUsage) @@ -926,12 +1022,16 @@ func init() { provisionCmd.Flags().StringP(ResoureGroupName, ResourceGroupShorthand, provisionConfig.GetString(ResoureGroupName), resourceGroupUsage) provisionCmd.Flags().StringP(SiteName, SiteShorthand, provisionConfig.GetString(SiteName), siteUsage) provisionCmd.Flags().StringP(LocationName, LocationShorthand, provisionConfig.GetString(LocationName), locationUsage) - provisionCmd.Flags().Bool(SkipTemplateCacheName, false, skipTemplateCacheUsage) + provisionCmd.Flags().BoolP(SkipTemplateCacheName, SkipTemplateCacheShorthand, false, skipTemplateCacheUsage) provisionCmd.Flags().BoolP(SkipParameterCacheName, SkipParameterCacheShorthand, false, skipParameterCacheUsage) provisionCmd.Flags().BoolP(SkipDeploymentName, SkipDeploymentShorthand, false, skipDeploymentUsage) - provisionCmd.Flags().StringP(DatabasePasswordName, DatabasePasswordShorthand, DatabasePasswordDefault, databasePasswordUsage) + provisionCmd.Flags().StringP(DatabasePasswordName, DatabasePasswordShorthand, dbPassText, databasePasswordUsage) provisionCmd.Flags().String(DatabaseAdminName, provisionConfig.GetString(DatabaseAdminName), databaseAdminUsage) provisionCmd.Flags().StringP(TemplateParametersName, TemplateParametersShorthand, provisionConfig.GetString(TemplateParametersName), templateParametersUsage) + provisionCmd.Flags().String(DockerRegistryAccessName, provisionConfig.GetString(DockerRegistryAccessName), dockerRegistryAccessUsage) + provisionCmd.Flags().String(DockerRegistryURLName, provisionConfig.GetString(DockerRegistryURLName), dockerRegistryURLUsage) + provisionCmd.Flags().String(DockerRegistryUsernameName, provisionConfig.GetString(DockerRegistryUsernameName), dockerRegistryUsernameUsage) + provisionCmd.Flags().String(DockerRegistryPasswordName, dockerPassText, dockerRegistryPasswordUsage) provisionConfig.BindPFlags(provisionCmd.Flags()) diff --git a/generators/common/import_bag.go b/generators/common/import_bag.go new file mode 100644 index 0000000..4a5d0f1 --- /dev/null +++ b/generators/common/import_bag.go @@ -0,0 +1,234 @@ +package common + +import ( + "bytes" + "errors" + "fmt" + "go/ast" + "go/importer" + "go/parser" + "go/token" + "go/types" + "path" + "sort" + "strings" +) + +// PackageSpecifier is a string that represents the name that will be used to refer to +// exported functions and variables from a package. +type PackageSpecifier string + +// PackagePath is a string that refers to the location of Go package. +type PackagePath string + +// ImportBag captures all of the imports in a Go source file, and attempts +// to ease the process of working with them. +type ImportBag struct { + bySpec map[PackageSpecifier]PackagePath + blankIdent map[PackagePath]struct{} + localIdent map[PackagePath]struct{} +} + +// NewImportBag instantiates an empty ImportBag. +func NewImportBag() *ImportBag { + return &ImportBag{ + bySpec: make(map[PackageSpecifier]PackagePath), + blankIdent: make(map[PackagePath]struct{}), + localIdent: make(map[PackagePath]struct{}), + } +} + +// NewImportBagFromFile reads a Go source file, finds all imports, +// and returns them as an instantiated ImportBag. +func NewImportBagFromFile(filepath string) (*ImportBag, error) { + f, err := parser.ParseFile(token.NewFileSet(), filepath, nil, parser.ImportsOnly) + if err != nil { + return nil, err + } + + ib := NewImportBag() + + for _, spec := range f.Imports { + pkgPath := PackagePath(strings.Trim(spec.Path.Value, `"`)) + if spec.Name == nil { + ib.AddImport(pkgPath) + } else { + ib.AddImportWithSpecifier(pkgPath, PackageSpecifier(spec.Name.Name)) + } + } + + return ib, nil +} + +// AddImport includes a package, and returns the name that was selected to +// be the specified for working with this path. It first attempts to use the +// package name as the specifier. Should that cause a conflict, it determines +// a unique name to be used as the specifier. +// +// If the path provided has already been imported, the existing name for it +// is returned, but err is non-nil. +func (ib *ImportBag) AddImport(pkgPath PackagePath) PackageSpecifier { + spec, err := FindSpecifier(pkgPath) + if err != nil { + spec = PackageSpecifier(path.Base(string(pkgPath))) + } + specLen := len(spec) + suffix := uint(1) + for { + err = ib.AddImportWithSpecifier(pkgPath, spec) + if err == nil { + break + } else if err != ErrDuplicateImport { + panic(err) + } + spec = PackageSpecifier(fmt.Sprintf("%s%d", spec[:specLen], suffix)) + suffix++ + } + + return spec +} + +// ErrDuplicateImport is the error that will be returned when two packages are both requested +// to be imported using the same specifier. +var ErrDuplicateImport = errors.New("specifier already in use in ImportBag") + +// ErrMultipleLocalImport is the error that will be returned when the same package has been imported +// to the specifer "." more than once. +var ErrMultipleLocalImport = errors.New("package already imported into the local namespace") + +// AddImportWithSpecifier will add an import with a given name. If it would lead +// to conflicting package specifiers, it returns an error. +func (ib *ImportBag) AddImportWithSpecifier(pkgPath PackagePath, specifier PackageSpecifier) error { + if specifier == "_" { + ib.blankIdent[pkgPath] = struct{}{} + return nil + } + + if specifier == "." { + if _, ok := ib.localIdent[pkgPath]; ok { + return ErrMultipleLocalImport + } + ib.localIdent[pkgPath] = struct{}{} + return nil + } + + if impPath, ok := ib.bySpec[specifier]; ok && pkgPath != impPath { + return ErrDuplicateImport + } + + ib.bySpec[specifier] = pkgPath + return nil +} + +// FindSpecifier finds the specifier assocatied with a particular package. +// +// If the package was not imported, the empty string and false are returned. +// +// If multiple specifiers are assigned to the package, one is returned at +// random. +// +// If the same package is imported with a named specifier, and the blank +// identifier, the name is returned. +func (ib ImportBag) FindSpecifier(pkgPath PackagePath) (PackageSpecifier, bool) { + for k, v := range ib.bySpec { + if v == pkgPath { + return k, true + } + } + + if _, ok := ib.blankIdent[pkgPath]; ok { + return "_", true + } + + if _, ok := ib.localIdent[pkgPath]; ok { + return ".", true + } + + return "", false +} + +// List returns each import statement as a slice of strings sorted alphabetically by +// their import paths. +func (ib *ImportBag) List() []string { + specs := ib.ListAsImportSpec() + retval := make([]string, len(specs)) + + builder := bytes.NewBuffer([]byte{}) + + for i, s := range specs { + if s.Name != nil { + builder.WriteString(s.Name.Name) + builder.WriteRune(' ') + } + builder.WriteString(s.Path.Value) + retval[i] = builder.String() + builder.Reset() + } + return retval +} + +// ListAsImportSpec returns the imports from the ImportBag as a slice of ImportSpecs +// sorted alphabetically by their import paths. +func (ib *ImportBag) ListAsImportSpec() []*ast.ImportSpec { + retval := make([]*ast.ImportSpec, 0, len(ib.bySpec)+len(ib.localIdent)+len(ib.blankIdent)) + + getLit := func(pkgPath PackagePath) *ast.BasicLit { + return &ast.BasicLit{ + Kind: token.STRING, + Value: fmt.Sprintf("%q", string(pkgPath)), + } + } + + for k, v := range ib.bySpec { + var name *ast.Ident + + if path.Base(string(v)) != string(k) { + name = ast.NewIdent(string(k)) + } + + retval = append(retval, &ast.ImportSpec{ + Name: name, + Path: getLit(v), + }) + } + + for s := range ib.localIdent { + retval = append(retval, &ast.ImportSpec{ + Name: ast.NewIdent("."), + Path: getLit(s), + }) + } + + for s := range ib.blankIdent { + retval = append(retval, &ast.ImportSpec{ + Name: ast.NewIdent("_"), + Path: getLit(s), + }) + } + + sort.Slice(retval, func(i, j int) bool { + return strings.Compare(retval[i].Path.Value, retval[j].Path.Value) < 0 + }) + + return retval +} + +var impFinder = importer.Default() + +// FindSpecifier finds the name of a package by loading it in from GOPATH +// or a vendor folder. +func FindSpecifier(pkgPath PackagePath) (PackageSpecifier, error) { + var pkg *types.Package + var err error + + if cast, ok := impFinder.(types.ImporterFrom); ok { + pkg, err = cast.ImportFrom(string(pkgPath), "", 0) + } else { + pkg, err = impFinder.Import(string(pkgPath)) + } + + if err != nil { + return "", err + } + return PackageSpecifier(pkg.Name()), nil +} diff --git a/generators/common/import_bag_test.go b/generators/common/import_bag_test.go new file mode 100644 index 0000000..d91d667 --- /dev/null +++ b/generators/common/import_bag_test.go @@ -0,0 +1,144 @@ +package common_test + +import ( + "testing" + + . "github.com/Azure/buffalo-azure/generators/common" +) + +func TestImportBag_AddImport_Unique(t *testing.T) { + testCases := [][]PackagePath{ + { + "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid", + }, + { + "github.com/Azure/buffalo-azure/generators/common", + "github.com/Azure/buffalo-azure/sdk/eventgrid", + }, + { + "fmt", + "github.com/Azure/buffalo-azure/generators/common", + }, + } + + for _, tc := range testCases { + t.Run("", func(t *testing.T) { + + seen := map[PackageSpecifier]struct{}{} + subject := NewImportBag() + + for _, pkgPath := range tc { + spec := subject.AddImport(pkgPath) + if _, ok := seen[spec]; ok { + t.Logf("duplicate spec returned") + t.Fail() + } + } + }) + } +} + +func TestImportBag_List(t *testing.T) { + testCases := []struct { + inputs []PackagePath + expected []string + }{ + { + inputs: []PackagePath{ + "github.com/Azure/buffalo-azure/generators/common", + "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid", + }, + expected: []string{ + `"github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid"`, + `"github.com/Azure/buffalo-azure/generators/common"`, + }, + }, + { + inputs: []PackagePath{ + "github.com/Azure/buffalo-azure/sdk/eventgrid", + "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid", + }, + expected: []string{ + `eventgrid1 "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid"`, + `"github.com/Azure/buffalo-azure/sdk/eventgrid"`, + }, + }, + { + inputs: []PackagePath{ + "github.com/Azure/buffalo-azure/sdk/eventgrid", + "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid", + "github.com/Azure/buffalo-azure/generators/eventgrid", + }, + expected: []string{ + `eventgrid1 "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid"`, + `eventgrid2 "github.com/Azure/buffalo-azure/generators/eventgrid"`, + `"github.com/Azure/buffalo-azure/sdk/eventgrid"`, + }, + }, + { + inputs: []PackagePath{ + "github.com/Azure/buffalo-azure/sdk/eventgrid", + "github.com/Azure/buffalo-azure/sdk/eventgrid", + }, + expected: []string{ + `"github.com/Azure/buffalo-azure/sdk/eventgrid"`, + }, + }, + } + + for _, tc := range testCases { + t.Run("", func(t *testing.T) { + subject := NewImportBag() + for _, i := range tc.inputs { + subject.AddImport(i) + } + + got := subject.List() + + if len(got) != len(tc.expected) { + t.Logf("got: %d imports want: %d imports", len(got), len(tc.expected)) + t.Fail() + } + + for i, val := range tc.expected { + if got[i] != val { + t.Logf("at %d\n\tgot: %s\n\twant: %s", i, got[i], val) + t.Fail() + } + } + }) + } +} + +func TestImportBag_NewImportBagFromFile(t *testing.T) { + testCases := []struct { + inputFile string + expected []string + }{ + {"./testdata/main.go", []string{`"fmt"`, `_ "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid"`}}, + } + + for _, tc := range testCases { + t.Run("", func(t *testing.T) { + subject, err := NewImportBagFromFile(tc.inputFile) + if err != nil { + t.Error(err) + return + } + + got := subject.List() + + for i, imp := range tc.expected { + if imp != got[i] { + t.Logf("at: %d\n\tgot: %s\n\twant: %s", i, got[i], imp) + t.Fail() + } + } + + if len(got) != len(tc.expected) { + t.Logf("got: %d imports want: %d imports", len(got), len(tc.expected)) + t.Fail() + } + }) + } +} diff --git a/generators/common/testdata/main.go b/generators/common/testdata/main.go new file mode 100644 index 0000000..966381d --- /dev/null +++ b/generators/common/testdata/main.go @@ -0,0 +1,11 @@ +package main + +import ( + "fmt" + + _ "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid" +) + +func main() { + fmt.Println("Hello, world!!!") +} diff --git a/generators/eventgrid/generator.go b/generators/eventgrid/generator.go index 03231bd..92874b4 100644 --- a/generators/eventgrid/generator.go +++ b/generators/eventgrid/generator.go @@ -11,6 +11,8 @@ import ( "github.com/gobuffalo/buffalo/meta" "github.com/gobuffalo/makr" "github.com/markbates/inflect" + + "github.com/Azure/buffalo-azure/generators/common" ) //go:generate go run ./builder/builder.go -o ./static_templates.go ./templates @@ -26,15 +28,24 @@ func (eg *Generator) Run(app meta.App, name string, types map[string]reflect.Typ type TypeMapping struct { Identifier string inflect.Name - PackageSpecifier string + PkgPath string + PkgSpec common.PackageSpecifier } flatTypes := make([]TypeMapping, 0, len(types)) + ib := common.NewImportBag() + ib.AddImport("encoding/json") + ib.AddImport("errors") + ib.AddImport("net/http") + ib.AddImportWithSpecifier("github.com/Azure/buffalo-azure/sdk/eventgrid", "eg") + ib.AddImport("github.com/gobuffalo/buffalo") + for i, n := range types { flatTypes = append(flatTypes, TypeMapping{ - Identifier: i, - PackageSpecifier: path.Base(n.PkgPath()), - Name: inflect.Name(n.Name()), + Identifier: i, + PkgPath: n.PkgPath(), + PkgSpec: ib.AddImport(common.PackagePath(n.PkgPath())), + Name: inflect.Name(n.Name()), }) } @@ -60,6 +71,7 @@ func (eg *Generator) Run(app meta.App, name string, types map[string]reflect.Typ d := make(makr.Data) d["name"] = iName d["types"] = flatTypes + d["imports"] = ib.List() return g.Run(app.Root, d) } diff --git a/generators/eventgrid/static_templates.go b/generators/eventgrid/static_templates.go index 03a8e35..d19090d 100644 --- a/generators/eventgrid/static_templates.go +++ b/generators/eventgrid/static_templates.go @@ -6,5 +6,5 @@ package eventgrid var staticTemplates = make(TemplateCache) func init() { - staticTemplates["templates/actions/eventgrid_name.go.tmpl"] = []byte{112, 97, 99, 107, 97, 103, 101, 32, 97, 99, 116, 105, 111, 110, 115, 10, 10, 105, 109, 112, 111, 114, 116, 32, 40, 10, 9, 34, 101, 110, 99, 111, 100, 105, 110, 103, 47, 106, 115, 111, 110, 34, 10, 9, 34, 101, 114, 114, 111, 114, 115, 34, 10, 9, 34, 110, 101, 116, 47, 104, 116, 116, 112, 34, 10, 10, 9, 34, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 65, 122, 117, 114, 101, 47, 98, 117, 102, 102, 97, 108, 111, 45, 97, 122, 117, 114, 101, 47, 115, 100, 107, 47, 101, 118, 101, 110, 116, 103, 114, 105, 100, 34, 10, 9, 34, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 103, 111, 98, 117, 102, 102, 97, 108, 111, 47, 98, 117, 102, 102, 97, 108, 111, 34, 10, 41, 10, 10, 47, 47, 32, 77, 121, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 32, 103, 97, 116, 104, 101, 114, 115, 32, 114, 101, 115, 112, 111, 110, 100, 115, 32, 116, 111, 32, 97, 108, 108, 32, 82, 101, 113, 117, 101, 115, 116, 115, 32, 115, 101, 110, 116, 32, 116, 111, 32, 97, 32, 112, 97, 114, 116, 105, 99, 117, 108, 97, 114, 32, 101, 110, 100, 112, 111, 105, 110, 116, 46, 10, 116, 121, 112, 101, 32, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 32, 115, 116, 114, 117, 99, 116, 32, 123, 10, 9, 101, 118, 101, 110, 116, 103, 114, 105, 100, 46, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 10, 125, 10, 10, 47, 47, 32, 78, 101, 119, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 32, 105, 110, 115, 116, 97, 110, 116, 105, 97, 116, 101, 115, 32, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 32, 102, 111, 114, 32, 117, 115, 101, 32, 105, 110, 32, 97, 32, 96, 98, 117, 102, 102, 97, 108, 111, 46, 65, 112, 112, 96, 46, 10, 102, 117, 110, 99, 32, 78, 101, 119, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 40, 112, 97, 114, 101, 110, 116, 32, 101, 118, 101, 110, 116, 103, 114, 105, 100, 46, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 41, 32, 40, 99, 114, 101, 97, 116, 101, 100, 32, 42, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 41, 32, 123, 10, 9, 100, 105, 115, 112, 97, 116, 99, 104, 101, 114, 32, 58, 61, 32, 101, 118, 101, 110, 116, 103, 114, 105, 100, 46, 78, 101, 119, 84, 121, 112, 101, 68, 105, 115, 112, 97, 116, 99, 104, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 40, 112, 97, 114, 101, 110, 116, 41, 10, 10, 9, 99, 114, 101, 97, 116, 101, 100, 32, 61, 32, 38, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 123, 10, 9, 9, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 58, 32, 100, 105, 115, 112, 97, 116, 99, 104, 101, 114, 44, 10, 9, 125, 10, 10, 123, 123, 32, 114, 97, 110, 103, 101, 32, 36, 116, 32, 58, 61, 32, 46, 116, 121, 112, 101, 115, 125, 125, 10, 9, 100, 105, 115, 112, 97, 116, 99, 104, 101, 114, 46, 66, 105, 110, 100, 40, 34, 123, 123, 36, 116, 46, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 125, 125, 34, 44, 32, 99, 114, 101, 97, 116, 101, 100, 46, 82, 101, 99, 101, 105, 118, 101, 123, 123, 36, 116, 46, 78, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 41, 10, 123, 123, 101, 110, 100, 125, 125, 10, 9, 100, 105, 115, 112, 97, 116, 99, 104, 101, 114, 46, 66, 105, 110, 100, 40, 101, 118, 101, 110, 116, 103, 114, 105, 100, 46, 69, 118, 101, 110, 116, 84, 121, 112, 101, 87, 105, 108, 100, 99, 97, 114, 100, 44, 32, 99, 114, 101, 97, 116, 101, 100, 46, 82, 101, 99, 101, 105, 118, 101, 68, 101, 102, 97, 117, 108, 116, 41, 10, 10, 9, 114, 101, 116, 117, 114, 110, 10, 125, 10, 10, 123, 123, 32, 114, 97, 110, 103, 101, 32, 36, 116, 32, 58, 61, 32, 46, 116, 121, 112, 101, 115, 32, 125, 125, 10, 47, 47, 32, 82, 101, 99, 101, 105, 118, 101, 123, 123, 36, 116, 46, 78, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 32, 119, 105, 108, 108, 32, 114, 101, 115, 112, 111, 110, 100, 32, 116, 111, 32, 97, 110, 32, 96, 101, 118, 101, 110, 116, 103, 114, 105, 100, 46, 69, 118, 101, 110, 116, 96, 32, 99, 97, 114, 114, 121, 105, 110, 103, 32, 97, 32, 115, 101, 114, 105, 97, 108, 105, 122, 101, 100, 32, 96, 123, 123, 36, 116, 46, 78, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 96, 32, 97, 115, 32, 105, 116, 115, 32, 112, 97, 121, 108, 111, 97, 100, 46, 10, 102, 117, 110, 99, 32, 40, 115, 32, 42, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 41, 32, 82, 101, 99, 101, 105, 118, 101, 123, 123, 36, 116, 46, 78, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 40, 99, 32, 98, 117, 102, 102, 97, 108, 111, 46, 67, 111, 110, 116, 101, 120, 116, 44, 32, 101, 32, 101, 118, 101, 110, 116, 103, 114, 105, 100, 46, 69, 118, 101, 110, 116, 41, 32, 101, 114, 114, 111, 114, 32, 123, 10, 9, 118, 97, 114, 32, 112, 97, 121, 108, 111, 97, 100, 32, 123, 123, 36, 116, 46, 80, 97, 99, 107, 97, 103, 101, 83, 112, 101, 99, 105, 102, 105, 101, 114, 125, 125, 46, 123, 123, 36, 116, 46, 78, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 10, 9, 105, 102, 32, 101, 114, 114, 32, 58, 61, 32, 106, 115, 111, 110, 46, 85, 110, 109, 97, 114, 115, 104, 97, 108, 40, 101, 46, 68, 97, 116, 97, 44, 32, 38, 112, 97, 121, 108, 111, 97, 100, 41, 59, 32, 101, 114, 114, 32, 33, 61, 32, 110, 105, 108, 32, 123, 10, 9, 9, 114, 101, 116, 117, 114, 110, 32, 99, 46, 69, 114, 114, 111, 114, 40, 104, 116, 116, 112, 46, 83, 116, 97, 116, 117, 115, 66, 97, 100, 82, 101, 113, 117, 101, 115, 116, 44, 32, 101, 114, 114, 111, 114, 115, 46, 78, 101, 119, 40, 34, 117, 110, 97, 98, 108, 101, 32, 116, 111, 32, 117, 110, 109, 97, 114, 115, 104, 97, 108, 32, 114, 101, 113, 117, 101, 115, 116, 32, 100, 97, 116, 97, 34, 41, 41, 10, 9, 125, 10, 10, 9, 47, 47, 32, 82, 101, 112, 108, 97, 99, 101, 32, 116, 104, 101, 32, 99, 111, 100, 101, 32, 98, 101, 108, 111, 119, 32, 119, 105, 116, 104, 32, 121, 111, 117, 114, 32, 108, 111, 103, 105, 99, 10, 9, 114, 101, 116, 117, 114, 110, 32, 99, 46, 69, 114, 114, 111, 114, 40, 104, 116, 116, 112, 46, 83, 116, 97, 116, 117, 115, 73, 110, 116, 101, 114, 110, 97, 108, 83, 101, 114, 118, 101, 114, 69, 114, 114, 111, 114, 44, 32, 101, 114, 114, 111, 114, 115, 46, 78, 101, 119, 40, 34, 110, 111, 116, 32, 105, 109, 112, 108, 101, 109, 101, 110, 116, 101, 100, 34, 41, 41, 10, 125, 10, 123, 123, 101, 110, 100, 125, 125, 10, 10, 47, 47, 32, 82, 101, 99, 101, 105, 118, 101, 68, 101, 102, 97, 117, 108, 116, 32, 119, 105, 108, 108, 32, 114, 101, 115, 112, 111, 110, 100, 32, 116, 111, 32, 97, 110, 32, 96, 101, 118, 101, 110, 116, 103, 114, 105, 100, 46, 69, 118, 101, 110, 116, 96, 32, 99, 97, 114, 114, 121, 105, 110, 103, 32, 97, 110, 121, 32, 69, 118, 101, 110, 116, 84, 121, 112, 101, 32, 97, 115, 32, 105, 116, 115, 32, 112, 97, 121, 108, 111, 97, 100, 46, 10, 102, 117, 110, 99, 32, 40, 115, 32, 42, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 41, 32, 82, 101, 99, 101, 105, 118, 101, 68, 101, 102, 97, 117, 108, 116, 40, 99, 32, 98, 117, 102, 102, 97, 108, 111, 46, 67, 111, 110, 116, 101, 120, 116, 44, 32, 101, 32, 101, 118, 101, 110, 116, 103, 114, 105, 100, 46, 69, 118, 101, 110, 116, 41, 32, 101, 114, 114, 111, 114, 32, 123, 10, 9, 114, 101, 116, 117, 114, 110, 32, 99, 46, 69, 114, 114, 111, 114, 40, 104, 116, 116, 112, 46, 83, 116, 97, 116, 117, 115, 73, 110, 116, 101, 114, 110, 97, 108, 83, 101, 114, 118, 101, 114, 69, 114, 114, 111, 114, 44, 32, 101, 114, 114, 111, 114, 115, 46, 78, 101, 119, 40, 34, 110, 111, 116, 32, 105, 109, 112, 108, 101, 109, 101, 110, 116, 101, 100, 34, 41, 41, 10, 125, 10} + staticTemplates["templates/actions/eventgrid_name.go.tmpl"] = []byte{112, 97, 99, 107, 97, 103, 101, 32, 97, 99, 116, 105, 111, 110, 115, 10, 10, 105, 109, 112, 111, 114, 116, 32, 40, 10, 123, 123, 32, 114, 97, 110, 103, 101, 32, 36, 105, 32, 58, 61, 32, 46, 105, 109, 112, 111, 114, 116, 115, 32, 125, 125, 9, 123, 123, 36, 105, 125, 125, 10, 123, 123, 32, 101, 110, 100, 32, 125, 125, 10, 41, 10, 10, 47, 47, 32, 77, 121, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 32, 103, 97, 116, 104, 101, 114, 115, 32, 114, 101, 115, 112, 111, 110, 100, 115, 32, 116, 111, 32, 97, 108, 108, 32, 82, 101, 113, 117, 101, 115, 116, 115, 32, 115, 101, 110, 116, 32, 116, 111, 32, 97, 32, 112, 97, 114, 116, 105, 99, 117, 108, 97, 114, 32, 101, 110, 100, 112, 111, 105, 110, 116, 46, 10, 116, 121, 112, 101, 32, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 32, 115, 116, 114, 117, 99, 116, 32, 123, 10, 9, 101, 103, 46, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 10, 125, 10, 10, 47, 47, 32, 78, 101, 119, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 32, 105, 110, 115, 116, 97, 110, 116, 105, 97, 116, 101, 115, 32, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 32, 102, 111, 114, 32, 117, 115, 101, 32, 105, 110, 32, 97, 32, 96, 98, 117, 102, 102, 97, 108, 111, 46, 65, 112, 112, 96, 46, 10, 102, 117, 110, 99, 32, 78, 101, 119, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 40, 112, 97, 114, 101, 110, 116, 32, 101, 103, 46, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 41, 32, 40, 99, 114, 101, 97, 116, 101, 100, 32, 42, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 41, 32, 123, 10, 9, 100, 105, 115, 112, 97, 116, 99, 104, 101, 114, 32, 58, 61, 32, 101, 103, 46, 78, 101, 119, 84, 121, 112, 101, 68, 105, 115, 112, 97, 116, 99, 104, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 40, 112, 97, 114, 101, 110, 116, 41, 10, 10, 9, 99, 114, 101, 97, 116, 101, 100, 32, 61, 32, 38, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 123, 10, 9, 9, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 58, 32, 100, 105, 115, 112, 97, 116, 99, 104, 101, 114, 44, 10, 9, 125, 10, 10, 123, 123, 32, 114, 97, 110, 103, 101, 32, 36, 116, 32, 58, 61, 32, 46, 116, 121, 112, 101, 115, 125, 125, 10, 9, 100, 105, 115, 112, 97, 116, 99, 104, 101, 114, 46, 66, 105, 110, 100, 40, 34, 123, 123, 36, 116, 46, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 125, 125, 34, 44, 32, 99, 114, 101, 97, 116, 101, 100, 46, 82, 101, 99, 101, 105, 118, 101, 123, 123, 36, 116, 46, 78, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 41, 10, 123, 123, 101, 110, 100, 125, 125, 10, 9, 100, 105, 115, 112, 97, 116, 99, 104, 101, 114, 46, 66, 105, 110, 100, 40, 101, 103, 46, 69, 118, 101, 110, 116, 84, 121, 112, 101, 87, 105, 108, 100, 99, 97, 114, 100, 44, 32, 99, 114, 101, 97, 116, 101, 100, 46, 82, 101, 99, 101, 105, 118, 101, 68, 101, 102, 97, 117, 108, 116, 41, 10, 10, 9, 114, 101, 116, 117, 114, 110, 10, 125, 10, 10, 123, 123, 32, 114, 97, 110, 103, 101, 32, 36, 116, 32, 58, 61, 32, 46, 116, 121, 112, 101, 115, 32, 125, 125, 10, 47, 47, 32, 82, 101, 99, 101, 105, 118, 101, 123, 123, 36, 116, 46, 78, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 32, 119, 105, 108, 108, 32, 114, 101, 115, 112, 111, 110, 100, 32, 116, 111, 32, 97, 110, 32, 96, 101, 118, 101, 110, 116, 103, 114, 105, 100, 46, 69, 118, 101, 110, 116, 96, 32, 99, 97, 114, 114, 121, 105, 110, 103, 32, 97, 32, 115, 101, 114, 105, 97, 108, 105, 122, 101, 100, 32, 96, 123, 123, 36, 116, 46, 78, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 96, 32, 97, 115, 32, 105, 116, 115, 32, 112, 97, 121, 108, 111, 97, 100, 46, 10, 102, 117, 110, 99, 32, 40, 115, 32, 42, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 41, 32, 82, 101, 99, 101, 105, 118, 101, 123, 123, 36, 116, 46, 78, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 40, 99, 32, 98, 117, 102, 102, 97, 108, 111, 46, 67, 111, 110, 116, 101, 120, 116, 44, 32, 101, 32, 101, 103, 46, 69, 118, 101, 110, 116, 41, 32, 101, 114, 114, 111, 114, 32, 123, 10, 9, 118, 97, 114, 32, 112, 97, 121, 108, 111, 97, 100, 32, 123, 123, 36, 116, 46, 80, 107, 103, 83, 112, 101, 99, 125, 125, 46, 123, 123, 36, 116, 46, 78, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 10, 9, 105, 102, 32, 101, 114, 114, 32, 58, 61, 32, 106, 115, 111, 110, 46, 85, 110, 109, 97, 114, 115, 104, 97, 108, 40, 101, 46, 68, 97, 116, 97, 44, 32, 38, 112, 97, 121, 108, 111, 97, 100, 41, 59, 32, 101, 114, 114, 32, 33, 61, 32, 110, 105, 108, 32, 123, 10, 9, 9, 114, 101, 116, 117, 114, 110, 32, 99, 46, 69, 114, 114, 111, 114, 40, 104, 116, 116, 112, 46, 83, 116, 97, 116, 117, 115, 66, 97, 100, 82, 101, 113, 117, 101, 115, 116, 44, 32, 101, 114, 114, 111, 114, 115, 46, 78, 101, 119, 40, 34, 117, 110, 97, 98, 108, 101, 32, 116, 111, 32, 117, 110, 109, 97, 114, 115, 104, 97, 108, 32, 114, 101, 113, 117, 101, 115, 116, 32, 100, 97, 116, 97, 34, 41, 41, 10, 9, 125, 10, 10, 9, 47, 47, 32, 82, 101, 112, 108, 97, 99, 101, 32, 116, 104, 101, 32, 99, 111, 100, 101, 32, 98, 101, 108, 111, 119, 32, 119, 105, 116, 104, 32, 121, 111, 117, 114, 32, 108, 111, 103, 105, 99, 10, 9, 114, 101, 116, 117, 114, 110, 32, 99, 46, 69, 114, 114, 111, 114, 40, 104, 116, 116, 112, 46, 83, 116, 97, 116, 117, 115, 73, 110, 116, 101, 114, 110, 97, 108, 83, 101, 114, 118, 101, 114, 69, 114, 114, 111, 114, 44, 32, 101, 114, 114, 111, 114, 115, 46, 78, 101, 119, 40, 34, 110, 111, 116, 32, 105, 109, 112, 108, 101, 109, 101, 110, 116, 101, 100, 34, 41, 41, 10, 125, 10, 123, 123, 101, 110, 100, 125, 125, 10, 10, 47, 47, 32, 82, 101, 99, 101, 105, 118, 101, 68, 101, 102, 97, 117, 108, 116, 32, 119, 105, 108, 108, 32, 114, 101, 115, 112, 111, 110, 100, 32, 116, 111, 32, 97, 110, 32, 96, 101, 118, 101, 110, 116, 103, 114, 105, 100, 46, 69, 118, 101, 110, 116, 96, 32, 99, 97, 114, 114, 121, 105, 110, 103, 32, 97, 110, 121, 32, 69, 118, 101, 110, 116, 84, 121, 112, 101, 32, 97, 115, 32, 105, 116, 115, 32, 112, 97, 121, 108, 111, 97, 100, 46, 10, 102, 117, 110, 99, 32, 40, 115, 32, 42, 123, 123, 36, 46, 110, 97, 109, 101, 46, 67, 97, 109, 101, 108, 125, 125, 83, 117, 98, 115, 99, 114, 105, 98, 101, 114, 41, 32, 82, 101, 99, 101, 105, 118, 101, 68, 101, 102, 97, 117, 108, 116, 40, 99, 32, 98, 117, 102, 102, 97, 108, 111, 46, 67, 111, 110, 116, 101, 120, 116, 44, 32, 101, 32, 101, 103, 46, 69, 118, 101, 110, 116, 41, 32, 101, 114, 114, 111, 114, 32, 123, 10, 9, 114, 101, 116, 117, 114, 110, 32, 99, 46, 69, 114, 114, 111, 114, 40, 104, 116, 116, 112, 46, 83, 116, 97, 116, 117, 115, 73, 110, 116, 101, 114, 110, 97, 108, 83, 101, 114, 118, 101, 114, 69, 114, 114, 111, 114, 44, 32, 101, 114, 114, 111, 114, 115, 46, 78, 101, 119, 40, 34, 110, 111, 116, 32, 105, 109, 112, 108, 101, 109, 101, 110, 116, 101, 100, 34, 41, 41, 10, 125, 10} } diff --git a/generators/eventgrid/templates/actions/eventgrid_name.go.tmpl b/generators/eventgrid/templates/actions/eventgrid_name.go.tmpl index 31b6f0e..0d1e781 100644 --- a/generators/eventgrid/templates/actions/eventgrid_name.go.tmpl +++ b/generators/eventgrid/templates/actions/eventgrid_name.go.tmpl @@ -1,22 +1,18 @@ package actions import ( - "encoding/json" - "errors" - "net/http" - - "github.com/Azure/buffalo-azure/sdk/eventgrid" - "github.com/gobuffalo/buffalo" +{{ range $i := .imports }} {{$i}} +{{ end }} ) // My{{$.name.Camel}}Subscriber gathers responds to all Requests sent to a particular endpoint. type {{$.name.Camel}}Subscriber struct { - eventgrid.Subscriber + eg.Subscriber } // New{{$.name.Camel}}Subscriber instantiates {{$.name.Camel}}Subscriber for use in a `buffalo.App`. -func New{{$.name.Camel}}Subscriber(parent eventgrid.Subscriber) (created *{{$.name.Camel}}Subscriber) { - dispatcher := eventgrid.NewTypeDispatchSubscriber(parent) +func New{{$.name.Camel}}Subscriber(parent eg.Subscriber) (created *{{$.name.Camel}}Subscriber) { + dispatcher := eg.NewTypeDispatchSubscriber(parent) created = &{{$.name.Camel}}Subscriber{ Subscriber: dispatcher, @@ -25,15 +21,15 @@ func New{{$.name.Camel}}Subscriber(parent eventgrid.Subscriber) (created *{{$.na {{ range $t := .types}} dispatcher.Bind("{{$t.Identifier}}", created.Receive{{$t.Name.Camel}}) {{end}} - dispatcher.Bind(eventgrid.EventTypeWildcard, created.ReceiveDefault) + dispatcher.Bind(eg.EventTypeWildcard, created.ReceiveDefault) return } {{ range $t := .types }} // Receive{{$t.Name.Camel}} will respond to an `eventgrid.Event` carrying a serialized `{{$t.Name.Camel}}` as its payload. -func (s *{{$.name.Camel}}Subscriber) Receive{{$t.Name.Camel}}(c buffalo.Context, e eventgrid.Event) error { - var payload {{$t.PackageSpecifier}}.{{$t.Name.Camel}} +func (s *{{$.name.Camel}}Subscriber) Receive{{$t.Name.Camel}}(c buffalo.Context, e eg.Event) error { + var payload {{$t.PkgSpec}}.{{$t.Name.Camel}} if err := json.Unmarshal(e.Data, &payload); err != nil { return c.Error(http.StatusBadRequest, errors.New("unable to unmarshal request data")) } @@ -44,6 +40,6 @@ func (s *{{$.name.Camel}}Subscriber) Receive{{$t.Name.Camel}}(c buffalo.Context, {{end}} // ReceiveDefault will respond to an `eventgrid.Event` carrying any EventType as its payload. -func (s *{{$.name.Camel}}Subscriber) ReceiveDefault(c buffalo.Context, e eventgrid.Event) error { +func (s *{{$.name.Camel}}Subscriber) ReceiveDefault(c buffalo.Context, e eg.Event) error { return c.Error(http.StatusInternalServerError, errors.New("not implemented")) } diff --git a/generators/eventgrid/testdata/main.go b/generators/eventgrid/testdata/main.go new file mode 100644 index 0000000..9d1882e --- /dev/null +++ b/generators/eventgrid/testdata/main.go @@ -0,0 +1,13 @@ +package main + +import ( + "fmt" + + egdp "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid" + "github.com/Azure/buffalo-azure/sdk/eventgrid" +) + +func main() { + fmt.Printf("%#v\n", eventgrid.TypeDispatchSubscriber{}) + fmt.Printf("%#v\n", egdp.StorageBlobCreatedEventData{}) +}