Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for Terraform Plugin SDK v2 #179

Merged
merged 1 commit into from
Aug 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ go 1.13
require (
github.com/bflad/gopaniccheck v0.1.0
github.com/hashicorp/terraform-plugin-sdk v1.9.0
golang.org/x/tools v0.0.0-20200414001008-ae52e4b55789
github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.0
golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed
)
261 changes: 259 additions & 2 deletions go.sum

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions helper/astutils/fieldlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,20 @@ func IsFieldListType(fieldList *ast.FieldList, position int, exprFunc func(ast.E
return t != nil && exprFunc(*t)
}

// IsFieldListTypeModulePackageType returns true if the field at position is present and matches expected module and package type
//
// This function automatically handles Go module versioning in import paths.
// To explicitly check an import path, use IsFieldListTypePackageType instead.
func IsFieldListTypeModulePackageType(fieldList *ast.FieldList, position int, info *types.Info, module string, packageSuffix string, typeName string) bool {
t := FieldListType(fieldList, position)

return t != nil && IsModulePackageFunctionFieldListType(*t, info, module, packageSuffix, typeName)
}

// IsFieldListTypePackageType returns true if the field at position is present and matches expected package type
//
// This function checks an explicit import path. To allow any Go module version
// in the import path, use IsFieldListTypeModulePackageType instead.
func IsFieldListTypePackageType(fieldList *ast.FieldList, position int, info *types.Info, packageSuffix string, typeName string) bool {
t := FieldListType(fieldList, position)

Expand Down
111 changes: 111 additions & 0 deletions helper/astutils/package.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,105 @@
package astutils

import (
"fmt"
"go/ast"
"go/types"
"regexp"
"strings"
)

// IsModulePackageReceiverMethod returns true if the module and package suffix (for vendoring), receiver name, and method name match
//
// This function automatically handles Go module versioning in import paths.
// To explicitly check an import path, use IsPackageReceiverMethod instead.
func IsModulePackageReceiverMethod(e ast.Expr, info *types.Info, module string, packageSuffix string, receiverName string, methodName string) bool {
switch e := e.(type) {
case *ast.SelectorExpr:
if e.Sel.Name != methodName {
return false
}

return IsModulePackageType(info.TypeOf(e.X), module, packageSuffix, receiverName)
}

return false
}

// IsModulePackageFunc returns true if the function package suffix (for vendoring) and name matches
//
// This function automatically handles Go module versioning in import paths.
// To explicitly check an import path, use IsPackageFunc instead.
func IsModulePackageFunc(e ast.Expr, info *types.Info, module string, packageSuffix string, funcName string) bool {
switch e := e.(type) {
case *ast.SelectorExpr:
if e.Sel.Name != funcName {
return false
}

switch x := e.X.(type) {
case *ast.Ident:
return isModulePackagePath(module, packageSuffix, info.ObjectOf(x).(*types.PkgName).Imported().Path())
}
case *ast.StarExpr:
return IsModulePackageFunc(e.X, info, module, packageSuffix, funcName)
}

return false
}

// IsModulePackageFunctionFieldListType returns true if the function parameter package suffix (for vendoring) and name matches
//
// This function automatically handles Go module versioning in import paths.
// To explicitly check an import path, use IsPackageFunctionFieldListType instead.
func IsModulePackageFunctionFieldListType(e ast.Expr, info *types.Info, module string, packageSuffix string, typeName string) bool {
switch e := e.(type) {
case *ast.SelectorExpr:
if e.Sel.Name != typeName {
return false
}

switch x := e.X.(type) {
case *ast.Ident:
return isModulePackagePath(module, packageSuffix, info.ObjectOf(x).(*types.PkgName).Imported().Path())
}
case *ast.StarExpr:
return IsModulePackageFunctionFieldListType(e.X, info, module, packageSuffix, typeName)
}

return false
}

// IsModulePackageNamedType returns if the type name matches and is from the package suffix
//
// This function automatically handles Go module versioning in import paths.
// To explicitly check an import path, use IsPackageNamedType instead.
func IsModulePackageNamedType(t *types.Named, module string, packageSuffix string, typeName string) bool {
if t.Obj().Name() != typeName {
return false
}

return isModulePackagePath(module, packageSuffix, t.Obj().Pkg().Path())
}

// IsModulePackageType returns true if the type name can be matched and is from the package suffix
//
// This function automatically handles Go module versioning in import paths.
// To explicitly check an import path, use IsPackageType instead.
func IsModulePackageType(t types.Type, module string, packageSuffix string, typeName string) bool {
switch t := t.(type) {
case *types.Named:
return IsModulePackageNamedType(t, module, packageSuffix, typeName)
case *types.Pointer:
return IsModulePackageType(t.Elem(), module, packageSuffix, typeName)
}

return false
}

// IsPackageReceiverMethod returns true if the package suffix (for vendoring), receiver name, and method name match
//
// This function checks an explicit import path. To allow any Go module version
// in the import path, use IsModulePackageReceiverMethod instead.
func IsPackageReceiverMethod(e ast.Expr, info *types.Info, packageSuffix string, receiverName, methodName string) bool {
switch e := e.(type) {
case *ast.SelectorExpr:
Expand All @@ -21,6 +114,9 @@ func IsPackageReceiverMethod(e ast.Expr, info *types.Info, packageSuffix string,
}

// IsPackageFunc returns true if the function package suffix (for vendoring) and name matches
//
// This function checks an explicit import path. To allow any Go module version
// in the import path, use IsModulePackageFunc instead.
func IsPackageFunc(e ast.Expr, info *types.Info, packageSuffix string, funcName string) bool {
switch e := e.(type) {
case *ast.SelectorExpr:
Expand All @@ -40,6 +136,9 @@ func IsPackageFunc(e ast.Expr, info *types.Info, packageSuffix string, funcName
}

// IsPackageFunctionFieldListType returns true if the function parameter package suffix (for vendoring) and name matches
//
// This function checks an explicit import path. To allow any Go module version
// in the import path, use IsModuleFunctionFieldListType instead.
func IsPackageFunctionFieldListType(e ast.Expr, info *types.Info, packageSuffix string, typeName string) bool {
switch e := e.(type) {
case *ast.SelectorExpr:
Expand All @@ -59,6 +158,9 @@ func IsPackageFunctionFieldListType(e ast.Expr, info *types.Info, packageSuffix
}

// IsPackageNamedType returns if the type name matches and is from the package suffix
//
// This function checks an explicit import path. To allow any Go module version
// in the import path, use IsModulePackageNamedType instead.
func IsPackageNamedType(t *types.Named, packageSuffix string, typeName string) bool {
if t.Obj().Name() != typeName {
return false
Expand All @@ -69,6 +171,9 @@ func IsPackageNamedType(t *types.Named, packageSuffix string, typeName string) b
}

// IsPackageType returns true if the type name can be matched and is from the package suffix
//
// This function checks an explicit import path. To allow any Go module version
// in the import path, use IsModulePackageType instead.
func IsPackageType(t types.Type, packageSuffix string, typeName string) bool {
switch t := t.(type) {
case *types.Named:
Expand All @@ -79,3 +184,9 @@ func IsPackageType(t types.Type, packageSuffix string, typeName string) bool {

return false
}

func isModulePackagePath(module string, packageSuffix string, path string) bool {
// Only check end of path due to vendoring
r := regexp.MustCompile(fmt.Sprintf("%s(/v[1-9][0-9]*)?/%s$", module, packageSuffix))
return r.MatchString(path)
}
22 changes: 18 additions & 4 deletions helper/terraformtype/helper/customdiff/package.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
package customdiff

import (
"fmt"
"go/ast"
"go/types"

"github.com/bflad/tfproviderlint/helper/astutils"
"github.com/bflad/tfproviderlint/helper/terraformtype"
)

const (
PackageName = `customdiff`
PackagePath = `github.com/hashicorp/terraform-plugin-sdk/customdiff`
PackageModule = terraformtype.ModuleTerraformPluginSdk
PackageModulePath = `helper/customdiff`
PackageName = `customdiff`
PackagePath = PackageModule + `/` + PackageModulePath
)

// IsFunc returns if the function call is in the customdiff package
func IsFunc(e ast.Expr, info *types.Info, funcName string) bool {
return astutils.IsPackageFunc(e, info, PackagePath, funcName)
return astutils.IsModulePackageFunc(e, info, PackageModule, PackageModulePath, funcName)
}

// IsNamedType returns if the type name matches and is from the helper/customdiff package
func IsNamedType(t *types.Named, typeName string) bool {
return astutils.IsPackageNamedType(t, PackagePath, typeName)
return astutils.IsModulePackageNamedType(t, PackageModule, PackageModulePath, typeName)
}

// PackagePathVersion returns the import path for a module version
func PackagePathVersion(moduleVersion int) string {
switch moduleVersion {
case 0, 1:
return PackagePath
default:
return fmt.Sprintf("%s/v%d/%s", PackageModule, moduleVersion, PackageModulePath)
}
}
22 changes: 18 additions & 4 deletions helper/terraformtype/helper/resource/package.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
package resource

import (
"fmt"
"go/ast"
"go/types"

"github.com/bflad/tfproviderlint/helper/astutils"
"github.com/bflad/tfproviderlint/helper/terraformtype"
)

const (
PackageName = `resource`
PackagePath = `github.com/hashicorp/terraform-plugin-sdk/helper/resource`
PackageModule = terraformtype.ModuleTerraformPluginSdk
PackageModulePath = `helper/resource`
PackageName = `resource`
PackagePath = PackageModule + `/` + PackageModulePath
)

// IsFunc returns if the function call is in the resource package
func IsFunc(e ast.Expr, info *types.Info, funcName string) bool {
return astutils.IsPackageFunc(e, info, PackagePath, funcName)
return astutils.IsModulePackageFunc(e, info, PackageModule, PackageModulePath, funcName)
}

// IsNamedType returns if the type name matches and is from the helper/resource package
func IsNamedType(t *types.Named, typeName string) bool {
return astutils.IsPackageNamedType(t, PackagePath, typeName)
return astutils.IsModulePackageNamedType(t, PackageModule, PackageModulePath, typeName)
}

// PackagePathVersion returns the import path for a module version
func PackagePathVersion(moduleVersion int) string {
switch moduleVersion {
case 0, 1:
return PackagePath
default:
return fmt.Sprintf("%s/v%d/%s", PackageModule, moduleVersion, PackageModulePath)
}
}
24 changes: 19 additions & 5 deletions helper/terraformtype/helper/schema/package.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,42 @@
package schema

import (
"fmt"
"go/ast"
"go/types"

"github.com/bflad/tfproviderlint/helper/astutils"
"github.com/bflad/tfproviderlint/helper/terraformtype"
)

const (
PackageName = `schema`
PackagePath = `github.com/hashicorp/terraform-plugin-sdk/helper/schema`
PackageModule = terraformtype.ModuleTerraformPluginSdk
PackageModulePath = `helper/schema`
PackageName = `schema`
PackagePath = PackageModule + `/` + PackageModulePath
)

// IsFunc returns if the function call is in the package
func IsFunc(e ast.Expr, info *types.Info, funcName string) bool {
return astutils.IsPackageFunc(e, info, PackagePath, funcName)
return astutils.IsModulePackageFunc(e, info, PackageModule, PackageModulePath, funcName)
}

// IsNamedType returns if the type name matches and is from the package
func IsNamedType(t *types.Named, typeName string) bool {
return astutils.IsPackageNamedType(t, PackagePath, typeName)
return astutils.IsModulePackageNamedType(t, PackageModule, PackageModulePath, typeName)
}

// IsReceiverMethod returns if the receiver method call is in the package
func IsReceiverMethod(e ast.Expr, info *types.Info, receiverName string, methodName string) bool {
return astutils.IsPackageReceiverMethod(e, info, PackagePath, receiverName, methodName)
return astutils.IsModulePackageReceiverMethod(e, info, PackageModule, PackageModulePath, receiverName, methodName)
}

// PackagePathVersion returns the import path for a module version
func PackagePathVersion(moduleVersion int) string {
switch moduleVersion {
case 0, 1:
return PackagePath
default:
return fmt.Sprintf("%s/v%d/%s", PackageModule, moduleVersion, PackageModulePath)
}
}
20 changes: 17 additions & 3 deletions helper/terraformtype/helper/validation/package.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
package validation

import (
"fmt"
"go/ast"
"go/types"

"github.com/bflad/tfproviderlint/helper/astutils"
"github.com/bflad/tfproviderlint/helper/terraformtype"
)

const (
PackageName = `validation`
PackagePath = `github.com/hashicorp/terraform-plugin-sdk/helper/validation`
PackageModule = terraformtype.ModuleTerraformPluginSdk
PackageModulePath = `helper/validation`
PackageName = `validation`
PackagePath = PackageModule + `/` + PackageModulePath
)

// IsFunc returns if the function call is in the package
func IsFunc(e ast.Expr, info *types.Info, funcName string) bool {
return astutils.IsPackageFunc(e, info, PackagePath, funcName)
return astutils.IsModulePackageFunc(e, info, PackageModule, PackageModulePath, funcName)
}

// PackagePathVersion returns the import path for a module version
func PackagePathVersion(moduleVersion int) string {
switch moduleVersion {
case 0, 1:
return PackagePath
default:
return fmt.Sprintf("%s/v%d/%s", PackageModule, moduleVersion, PackageModulePath)
}
}
5 changes: 5 additions & 0 deletions helper/terraformtype/module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package terraformtype

const (
ModuleTerraformPluginSdk = `github.com/hashicorp/terraform-plugin-sdk`
)
Loading