Skip to content
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ you can also use shorter aliases, e.g.:
atlas tf clu2adv -f in.tf -o out.tf
```

If you want to overwrite the output file if it exists, or even use the same output file as the input file, use the `--overwriteOutput true` or the `-w` flag.
If you want to overwrite the output file if it exists, or even use the same output file as the input file, use the `--replaceOutput true` or the `-r` flag.

You can use the `--watch true` or the `-w` flag to keep the plugin running and watching for changes in the input file. You can have input and output files open in an editor and see easily how changes to the input file affect the output file.

### Limitations

Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/mongodb-labs/atlas-cli-plugin-terraform
go 1.23.6

require (
github.com/fsnotify/fsnotify v1.8.0
github.com/hashicorp/hcl/v2 v2.23.0
github.com/sebdah/goldie/v2 v2.5.5
github.com/spf13/afero v1.12.0
Expand All @@ -23,6 +24,7 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
Expand Down Expand Up @@ -49,6 +51,8 @@ golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
Expand Down
3 changes: 2 additions & 1 deletion internal/cli/clu2adv/clu2adv.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func Builder() *cobra.Command {
_ = cmd.MarkFlagRequired("file")
cmd.Flags().StringVarP(&o.output, "output", "o", "", "output file")
_ = cmd.MarkFlagRequired("output")
cmd.Flags().BoolVarP(&o.overwriteOutput, "overwriteOutput", "w", false, "overwrite output file if exists")
cmd.Flags().BoolVarP(&o.replaceOutput, "replaceOutput", "r", false, "replace output file if exists")
cmd.Flags().BoolVarP(&o.watch, "watch", "w", false, "keeps the plugin running and watches the input file for changes")
return cmd
}
67 changes: 61 additions & 6 deletions internal/cli/clu2adv/opts.go
Original file line number Diff line number Diff line change
@@ -1,41 +1,96 @@
package clu2adv

import (
"errors"
"fmt"

"github.com/fsnotify/fsnotify"
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/convert"
"github.com/mongodb-labs/atlas-cli-plugin-terraform/internal/file"
"github.com/spf13/afero"
)

type opts struct {
fs afero.Fs
file string
output string
overwriteOutput bool
fs afero.Fs
file string
output string
replaceOutput bool
watch bool
}

func (o *opts) PreRun() error {
if err := file.MustExist(o.fs, o.file); err != nil {
return err
}
if !o.overwriteOutput {
if !o.replaceOutput {
return file.MustNotExist(o.fs, o.output)
}
return nil
}

func (o *opts) Run() error {
if err := o.generateFile(false); err != nil {
return err
}
if o.watch {
return o.watchFile()
}
return nil
}

func (o *opts) 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 := convert.ClusterToAdvancedCluster(inConfig)
if err != nil {
return err
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
}

func (o *opts) watchFile() error {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return nil
}
defer watcher.Close()
if err := watcher.Add(o.file); err != nil {
return err
}
for {
if err := o.waitForFileEvent(watcher); err != nil {
return err
}
}
}

func (o *opts) 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
}