-
Notifications
You must be signed in to change notification settings - Fork 1
feat: Create advancedClusterToV2 command skeleton #58
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
Merged
Merged
Changes from 10 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
1fd6eb3
create new command adv2new
lantoli 97c71ba
reduce duplication in commands
lantoli 327ab44
initialize opts
lantoli 0e6ecff
simplify Convert func
lantoli e075ed1
SetupCommonFlags
lantoli 49a1bf3
simplify e2e tests
lantoli cd214e8
refactor RunE
lantoli f7ac701
simplify unit tests
lantoli 9dc1b93
rename cmdName attribute
lantoli ed081ae
example of test with errors
lantoli 813f751
add todo comment
lantoli 769bca1
use alias in manifest
lantoli 32398ac
rename advancedClusterToNew to advancedClusterToV2
lantoli File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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,25 @@ | ||
package adv2new | ||
|
||
import ( | ||
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/cli" | ||
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/convert" | ||
"github.com/spf13/afero" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func Builder() *cobra.Command { | ||
o := &cli.BaseOpts{ | ||
Fs: afero.NewOsFs(), | ||
Convert: convert.AdvancedClusterToNew, | ||
} | ||
cmd := &cobra.Command{ | ||
Use: "advancedClusterToNew", | ||
Short: "Convert advanced_cluster from provider version 1 to 2", | ||
marcosuma marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Long: "Convert a Terraform configuration from mongodbatlas_advanced_cluster in provider version 1.X.X (SDKv2)" + | ||
" to version 2.X.X (TPF - Terraform Plugin Framework)", | ||
Aliases: []string{"adv2new"}, | ||
RunE: o.RunE, | ||
} | ||
cli.SetupCommonFlags(cmd, o) | ||
return cmd | ||
} |
This file contains hidden or 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 was deleted.
Oops, something went wrong.
This file contains hidden or 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,130 @@ | ||
package cli | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice re-use! |
||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/fsnotify/fsnotify" | ||
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/file" | ||
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/flag" | ||
"github.com/spf13/afero" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
type ConvertFn func(config []byte) ([]byte, error) | ||
|
||
// BaseOpts contains common functionality for CLI commands that convert files. | ||
type BaseOpts struct { | ||
Fs afero.Fs | ||
Convert ConvertFn | ||
File string | ||
Output string | ||
ReplaceOutput bool | ||
Watch bool | ||
} | ||
|
||
// RunE is the entry point for the command. | ||
func (o *BaseOpts) RunE(cmd *cobra.Command, args []string) error { | ||
if err := o.preRun(); err != nil { | ||
return err | ||
} | ||
return o.run() | ||
} | ||
|
||
// preRun validates the input and output files before running the command. | ||
func (o *BaseOpts) preRun() error { | ||
if err := file.MustExist(o.Fs, o.File); err != nil { | ||
return err | ||
} | ||
if !o.ReplaceOutput { | ||
return file.MustNotExist(o.Fs, o.Output) | ||
} | ||
return nil | ||
} | ||
|
||
// run executes the conversion and optionally watches for file changes. | ||
func (o *BaseOpts) run() error { | ||
if err := o.generateFile(false); err != nil { | ||
return err | ||
} | ||
if o.Watch { | ||
return o.watchFile() | ||
} | ||
return nil | ||
} | ||
|
||
// generateFile reads the input file, converts it, and writes the output. | ||
func (o *BaseOpts) generateFile(allowParseErrors bool) error { | ||
inConfig, err := afero.ReadFile(o.Fs, o.File) | ||
if err != nil { | ||
return fmt.Errorf("failed to read file %s: %w", o.File, err) | ||
} | ||
|
||
outConfig, err := o.Convert(inConfig) | ||
if err != nil { | ||
if allowParseErrors { | ||
outConfig = []byte("# CONVERT ERROR: " + err.Error() + "\n\n") | ||
outConfig = append(outConfig, inConfig...) | ||
} else { | ||
return err | ||
} | ||
} | ||
|
||
if err := afero.WriteFile(o.Fs, o.Output, outConfig, 0o600); err != nil { | ||
return fmt.Errorf("failed to write file %s: %w", o.Output, err) | ||
} | ||
return nil | ||
} | ||
|
||
// watchFile watches the input file for changes and regenerates the output. | ||
func (o *BaseOpts) watchFile() error { | ||
watcher, err := fsnotify.NewWatcher() | ||
if err != nil { | ||
return err | ||
} | ||
defer watcher.Close() | ||
|
||
if err := watcher.Add(o.File); err != nil { | ||
return err | ||
} | ||
|
||
for { | ||
if err := o.waitForFileEvent(watcher); err != nil { | ||
return err | ||
} | ||
} | ||
} | ||
|
||
// waitForFileEvent waits for file system events and regenerates the output file. | ||
func (o *BaseOpts) waitForFileEvent(watcher *fsnotify.Watcher) error { | ||
watcherError := errors.New("watcher has been closed") | ||
select { | ||
case event, ok := <-watcher.Events: | ||
if !ok { | ||
return watcherError | ||
} | ||
if event.Has(fsnotify.Write) { | ||
if err := o.generateFile(true); err != nil { | ||
return err | ||
} | ||
} | ||
case err, ok := <-watcher.Errors: | ||
if !ok { | ||
return watcherError | ||
} | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
// SetupCommonFlags sets up the common flags used by all commands. | ||
func SetupCommonFlags(cmd *cobra.Command, opts *BaseOpts) { | ||
cmd.Flags().StringVarP(&opts.File, flag.File, flag.FileShort, "", "input file") | ||
_ = cmd.MarkFlagRequired(flag.File) | ||
cmd.Flags().StringVarP(&opts.Output, flag.Output, flag.OutputShort, "", "output file") | ||
_ = cmd.MarkFlagRequired(flag.Output) | ||
lantoli marked this conversation as resolved.
Show resolved
Hide resolved
lantoli marked this conversation as resolved.
Show resolved
Hide resolved
|
||
cmd.Flags().BoolVarP(&opts.ReplaceOutput, flag.ReplaceOutput, flag.ReplaceOutputShort, false, | ||
"replace output file if exists") | ||
cmd.Flags().BoolVarP(&opts.Watch, flag.Watch, flag.WatchShort, false, | ||
"keeps the plugin running and watches the input file for changes") | ||
} |
This file contains hidden or 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,14 @@ | ||
package convert | ||
|
||
import "github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/hcl" | ||
|
||
// AdvancedClusterToNew transforms all mongodbatlas_advanced_cluster resource definitions in a | ||
// Terraform configuration file from SDKv2 schema to TPF (Terraform Plugin Framework) schema. | ||
// All other resources and data sources are left untouched. | ||
func AdvancedClusterToNew(config []byte) ([]byte, error) { | ||
parser, err := hcl.GetParser(config) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return parser.Bytes(), nil | ||
} |
This file contains hidden or 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,13 @@ | ||
package convert_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/convert" | ||
) | ||
|
||
func TestAdvancedClusterToNew(t *testing.T) { | ||
runConvertTests(t, "adv2new", func(testName string, inConfig []byte) ([]byte, error) { | ||
return convert.AdvancedClusterToNew(inConfig) | ||
}) | ||
} |
File renamed without changes.
This file contains hidden or 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,15 @@ | ||
package convert_test | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/convert" | ||
) | ||
|
||
func TestClusterToAdvancedCluster(t *testing.T) { | ||
runConvertTests(t, "clu2adv", func(testName string, inConfig []byte) ([]byte, error) { | ||
includeMoved := strings.Contains(testName, "includeMoved") | ||
return convert.ClusterToAdvancedCluster(inConfig, includeMoved) | ||
}) | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just for sanity, how would the full command look like?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some equivalent examples to use it with names or aliases are:
you can also mix names and aliases in the same command
I like the convert command pattern name of
xxxToyyy
and aliasx2y
, maybeadvancedClusterToV2
andadv2v2
? (not convinced with so many 2, that's why i tried to avoid 2 in the command name).Having this context, what command and alias do you think it's better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marcosuma let me know if it's ok that I keep the current name and alias at the moment and I merge the PR as it is, or you prefer to use a different alias and name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not blocking this PR, but I think
New
andLatest
quickly become obsolete or ambiguous, that's why...ToV2
I like it more.2v2
is not ideal, but that's also an alias so I am less concernedThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's fair, changed here: 32398ac