Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract HCL rewrite logic into tfupdate package and updater interface
- Loading branch information
1 parent
b264126
commit bd9fb4b
Showing
9 changed files
with
436 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package tfupdate | ||
|
||
import ( | ||
"github.com/hashicorp/hcl2/hclwrite" | ||
"github.com/pkg/errors" | ||
"github.com/zclconf/go-cty/cty" | ||
) | ||
|
||
// ProviderUpdater is a updater implementation which updates the provider version constraint. | ||
type ProviderUpdater struct { | ||
name string | ||
version string | ||
} | ||
|
||
// NewProviderUpdater is a factory method which returns an ProviderUpdater instance. | ||
func NewProviderUpdater(name string, version string) (Updater, error) { | ||
if len(name) == 0 { | ||
return nil, errors.Errorf("failed to new provider updater. name is required.") | ||
} | ||
|
||
if len(version) == 0 { | ||
return nil, errors.Errorf("failed to new provider updater. version is required.") | ||
} | ||
|
||
return &ProviderUpdater{ | ||
name: name, | ||
version: version, | ||
}, nil | ||
} | ||
|
||
// Update updates the provider version constraint. | ||
// Note that this method will rewrite the AST passed as an argument. | ||
func (u *ProviderUpdater) Update(f *hclwrite.File) error { | ||
if err := u.updateTerraformBlock(f); err != nil { | ||
return err | ||
} | ||
|
||
if err := u.updateProviderBlock(f); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (u *ProviderUpdater) updateTerraformBlock(f *hclwrite.File) error { | ||
tf := f.Body().FirstMatchingBlock("terraform", []string{}) | ||
if tf == nil { | ||
return nil | ||
} | ||
|
||
p := tf.Body().FirstMatchingBlock("required_providers", []string{}) | ||
if p == nil { | ||
return nil | ||
} | ||
p.Body().SetAttributeValue(u.name, cty.StringVal(u.version)) | ||
|
||
return nil | ||
} | ||
|
||
func (u *ProviderUpdater) updateProviderBlock(f *hclwrite.File) error { | ||
p := f.Body().FirstMatchingBlock("provider", []string{u.name}) | ||
if p == nil { | ||
return nil | ||
} | ||
|
||
p.Body().SetAttributeValue("version", cty.StringVal(u.version)) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package tfupdate | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/hashicorp/hcl2/hcl" | ||
"github.com/hashicorp/hcl2/hclwrite" | ||
) | ||
|
||
func TestNewProviderUpdater(t *testing.T) { | ||
cases := []struct { | ||
name string | ||
version string | ||
want Updater | ||
ok bool | ||
}{ | ||
{ | ||
name: "aws", | ||
version: "2.23.0", | ||
want: &ProviderUpdater{ | ||
name: "aws", | ||
version: "2.23.0", | ||
}, | ||
ok: true, | ||
}, | ||
{ | ||
name: "", | ||
version: "2.23.0", | ||
want: nil, | ||
ok: false, | ||
}, | ||
{ | ||
name: "aws", | ||
version: "", | ||
want: nil, | ||
ok: false, | ||
}, | ||
} | ||
|
||
for _, tc := range cases { | ||
got, err := NewProviderUpdater(tc.name, tc.version) | ||
if tc.ok && err != nil { | ||
t.Errorf("NewProviderUpdater() with name = %s, version = %s returns unexpected err: %+v", tc.name, tc.version, err) | ||
} | ||
|
||
if !tc.ok && err == nil { | ||
t.Errorf("NewProviderUpdater() with name = %s, version = %s expects to return an error, but no error: %+v", tc.name, tc.version, err) | ||
} | ||
|
||
if !reflect.DeepEqual(got, tc.want) { | ||
t.Errorf("NewProviderUpdater() with name = %s, version = %s returns %#v, but want = %#v", tc.name, tc.version, got, tc.want) | ||
} | ||
} | ||
} | ||
|
||
func TestUpdateProvider(t *testing.T) { | ||
cases := []struct { | ||
src string | ||
name string | ||
version string | ||
want string | ||
ok bool | ||
}{ | ||
{ | ||
src: ` | ||
terraform { | ||
required_version = "0.12.4" | ||
required_providers { | ||
null = "2.1.1" | ||
} | ||
} | ||
`, | ||
name: "null", | ||
version: "2.1.2", | ||
want: ` | ||
terraform { | ||
required_version = "0.12.4" | ||
required_providers { | ||
null = "2.1.2" | ||
} | ||
} | ||
`, | ||
ok: true, | ||
}, | ||
{ | ||
src: ` | ||
provider "aws" { | ||
version = "2.11.0" | ||
region = "ap-northeast-1" | ||
} | ||
`, | ||
name: "aws", | ||
version: "2.23.0", | ||
want: ` | ||
provider "aws" { | ||
version = "2.23.0" | ||
region = "ap-northeast-1" | ||
} | ||
`, | ||
ok: true, | ||
}, | ||
} | ||
|
||
for _, tc := range cases { | ||
u := &ProviderUpdater{ | ||
name: tc.name, | ||
version: tc.version, | ||
} | ||
f, diags := hclwrite.ParseConfig([]byte(tc.src), "", hcl.Pos{Line: 1, Column: 1}) | ||
if diags.HasErrors() { | ||
t.Fatalf("unexpected diagnostics: %s", diags) | ||
} | ||
|
||
err := u.Update(f) | ||
if tc.ok && err != nil { | ||
t.Errorf("Update() with src = %s, name = %s, version = %s returns unexpected err: %+v", tc.src, tc.name, tc.version, err) | ||
} | ||
if !tc.ok && err == nil { | ||
t.Errorf("Update() with src = %s, name = %s, version = %s expects to return an error, but no error", tc.src, tc.name, tc.version) | ||
} | ||
|
||
got := string(hclwrite.Format(f.BuildTokens(nil).Bytes())) | ||
if got != tc.want { | ||
t.Errorf("Update() with src = %s, name = %s, version = %s returns %s, but want = %s", tc.src, tc.name, tc.version, got, tc.want) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package tfupdate | ||
|
||
import ( | ||
"github.com/hashicorp/hcl2/hclwrite" | ||
"github.com/pkg/errors" | ||
"github.com/zclconf/go-cty/cty" | ||
) | ||
|
||
// TerraformUpdater is a updater implementation which updates the terraform version constraint. | ||
type TerraformUpdater struct { | ||
version string | ||
} | ||
|
||
// NewTerraformUpdater is a factory method which returns an TerraformUpdater instance. | ||
func NewTerraformUpdater(version string) (Updater, error) { | ||
if len(version) == 0 { | ||
return nil, errors.Errorf("failed to new terraform updater. version is required.") | ||
} | ||
|
||
return &TerraformUpdater{ | ||
version: version, | ||
}, nil | ||
} | ||
|
||
// Update updates the terraform version constraint. | ||
// Note that this method will rewrite the AST passed as an argument. | ||
func (u *TerraformUpdater) Update(f *hclwrite.File) error { | ||
tf := f.Body().FirstMatchingBlock("terraform", []string{}) | ||
tf.Body().SetAttributeValue("required_version", cty.StringVal(u.version)) | ||
|
||
return nil | ||
} |
Oops, something went wrong.