Skip to content

Commit 3b8a12c

Browse files
committed
fix: accept flat array format for packages in snapshot push
PackageSnapshot.UnmarshalJSON now handles both the structured object format {"formulae":[],"casks":[],...} and a plain string array ["pkg1","pkg2"] where all items are treated as formulae. Fixes #12
1 parent 0fc88b2 commit 3b8a12c

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

internal/snapshot/snapshot.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package snapshot
22

3-
import "time"
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"time"
7+
)
48

59
type CaptureHealth struct {
610
FailedSteps []string `json:"failed_steps"`
@@ -33,6 +37,26 @@ type PackageSnapshot struct {
3337
Npm []string `json:"npm"`
3438
}
3539

40+
// UnmarshalJSON accepts both the structured object format
41+
// {"formulae":[],"casks":[],...} and a flat string array ["pkg1","pkg2"]
42+
// where all items are treated as formulae.
43+
func (ps *PackageSnapshot) UnmarshalJSON(data []byte) error {
44+
type alias PackageSnapshot
45+
var obj alias
46+
if err := json.Unmarshal(data, &obj); err == nil {
47+
*ps = PackageSnapshot(obj)
48+
return nil
49+
}
50+
51+
var arr []string
52+
if err := json.Unmarshal(data, &arr); err == nil {
53+
ps.Formulae = arr
54+
return nil
55+
}
56+
57+
return fmt.Errorf("packages must be an object {formulae,casks,taps,npm} or a string array")
58+
}
59+
3660
type MacOSPref struct {
3761
Domain string `json:"domain"`
3862
Key string `json:"key"`

internal/snapshot/snapshot_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package snapshot
22

33
import (
4+
"encoding/json"
45
"testing"
56
"time"
67

78
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
810
)
911

1012
// TestSnapshot_Creation tests basic snapshot creation and field initialization.
@@ -37,6 +39,51 @@ func TestPackageSnapshot_Empty(t *testing.T) {
3739
assert.Empty(t, ps.Taps)
3840
}
3941

42+
func TestPackageSnapshot_UnmarshalJSON(t *testing.T) {
43+
tests := []struct {
44+
name string
45+
input string
46+
expected PackageSnapshot
47+
wantErr bool
48+
}{
49+
{
50+
name: "object format",
51+
input: `{"formulae":["git","go"],"casks":["docker"],"taps":["homebrew/core"],"npm":["typescript"]}`,
52+
expected: PackageSnapshot{
53+
Formulae: []string{"git", "go"},
54+
Casks: []string{"docker"},
55+
Taps: []string{"homebrew/core"},
56+
Npm: []string{"typescript"},
57+
},
58+
},
59+
{
60+
name: "flat array treated as formulae",
61+
input: `["git","curl","jq"]`,
62+
expected: PackageSnapshot{
63+
Formulae: []string{"git", "curl", "jq"},
64+
},
65+
},
66+
{
67+
name: "invalid type",
68+
input: `123`,
69+
wantErr: true,
70+
},
71+
}
72+
73+
for _, tt := range tests {
74+
t.Run(tt.name, func(t *testing.T) {
75+
var ps PackageSnapshot
76+
err := json.Unmarshal([]byte(tt.input), &ps)
77+
if tt.wantErr {
78+
require.Error(t, err)
79+
return
80+
}
81+
require.NoError(t, err)
82+
assert.Equal(t, tt.expected, ps)
83+
})
84+
}
85+
}
86+
4087
// TestMacOSPref_Creation tests MacOS preference creation.
4188
func TestMacOSPref_Creation(t *testing.T) {
4289
pref := MacOSPref{

0 commit comments

Comments
 (0)