Skip to content

Commit

Permalink
helpers.Clone: go back to jinzhu/copier so Config can be cloned
Browse files Browse the repository at this point in the history
We do magic when serializing appconfig.Config to json, which broke object cloning :/
  • Loading branch information
alichay committed Apr 13, 2023
1 parent 33da95a commit 0b75424
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 11 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ require (
github.com/hashicorp/go-version v1.3.0
github.com/heroku/heroku-go/v5 v5.4.0
github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3
github.com/jinzhu/copier v0.3.5
github.com/jpillora/backoff v1.0.0
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/mattn/go-colorable v0.1.13
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s=
github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg=
github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
Expand Down
17 changes: 6 additions & 11 deletions helpers/clone.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package helpers

import (
"encoding/json"
"fmt"
"reflect"

"github.com/jinzhu/copier"
"github.com/superfly/flyctl/internal/sentry"
)

// Clone clones *public fields* in a structure.
// Private fields may or may not be copied, and private pointers may or may not point into the original object.
// - this will panic if the structure is not serializable
// - See CloneFallible
func Clone[T any](v T) T {
Expand All @@ -23,20 +24,14 @@ func Clone[T any](v T) T {
return ret
}

// deepCopy is a little helper so that the implementation can be easily swapped out
// If from is type T, into should be *T and non-nil
func deepCopy(from any, into any) error {
// For some reason, this does not properly DeepCopy.
// The test TestClonePointer would fail using this library.
// return copier.CopyWithOption(into, from, copier.Option{IgnoreEmpty: true, DeepCopy: true})

// Unfortunately, this _does_ deep copy, but this only copies public fields.
jsonStr, err := json.Marshal(from)
if err != nil {
return err
}
return json.Unmarshal(jsonStr, into)
return copier.CopyWithOption(into, from, copier.Option{IgnoreEmpty: true, DeepCopy: true})
}

// CloneFallible clones *public fields* in a structure.
// Private fields may or may not be copied, and private pointers may or may not point into the original object.
// - returns an error if the structure is not serializable
// - See Clone
func CloneFallible[T any](v T) (T, error) {
Expand Down
30 changes: 30 additions & 0 deletions internal/appconfig/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/superfly/flyctl/helpers"
)

func TestGetAndSetEnvVariables(t *testing.T) {
Expand Down Expand Up @@ -126,3 +127,32 @@ func TestConfigPortGetter(t *testing.T) {
})
}
}

// This can't go in helpers/clone_test.go because of an import cycle
func TestCloneAppconfig(t *testing.T) {

config := &Config{
AppName: "testcfg",
RawDefinition: map[string]any{
"mounts": []Volume{
{
Source: "src-raw",
Destination: "dst-raw",
},
{
Source: "src2",
Destination: "dst2",
},
},
},
Mounts: &Volume{
Source: "src",
Destination: "dst",
},
defaultGroupName: "some-group",
}

cloned := helpers.Clone(config)

assert.Equal(t, config, cloned)
}

0 comments on commit 0b75424

Please sign in to comment.