Skip to content

Commit

Permalink
Initial support for Terraform Plugin SDK v2 (#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikechoi78 committed Aug 5, 2020
1 parent ed7f1cf commit 5489e89
Show file tree
Hide file tree
Showing 1,023 changed files with 137,027 additions and 23,613 deletions.
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

0 comments on commit 5489e89

Please sign in to comment.