Skip to content

Commit 7c9ed44

Browse files
committed
fix: handle typed object array in snapshot packages unmarshal
PackageSnapshot.UnmarshalJSON now also accepts the API export format: [{"name":"git","type":"formula"},{"name":"docker","type":"cask"}] and sorts items into formulae/casks/taps/npm by their type field. Fixes #12
1 parent 3b8a12c commit 7c9ed44

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

internal/snapshot/snapshot.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,24 +37,48 @@ type PackageSnapshot struct {
3737
Npm []string `json:"npm"`
3838
}
3939

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.
40+
// UnmarshalJSON accepts three formats:
41+
// - Structured object: {"formulae":[],"casks":[],"taps":[],"npm":[]}
42+
// - Typed object array: [{"name":"git","type":"formula"},{"name":"docker","type":"cask"}]
43+
// - Flat string array: ["git","curl"] (all treated as formulae)
4344
func (ps *PackageSnapshot) UnmarshalJSON(data []byte) error {
45+
// Try structured object first.
4446
type alias PackageSnapshot
4547
var obj alias
4648
if err := json.Unmarshal(data, &obj); err == nil {
4749
*ps = PackageSnapshot(obj)
4850
return nil
4951
}
5052

53+
// Try typed object array: [{"name":"x","type":"formula|cask|tap|npm"}]
54+
var typed []struct {
55+
Name string `json:"name"`
56+
Type string `json:"type"`
57+
}
58+
if err := json.Unmarshal(data, &typed); err == nil && len(typed) > 0 && typed[0].Name != "" {
59+
for _, p := range typed {
60+
switch p.Type {
61+
case "cask":
62+
ps.Casks = append(ps.Casks, p.Name)
63+
case "tap":
64+
ps.Taps = append(ps.Taps, p.Name)
65+
case "npm":
66+
ps.Npm = append(ps.Npm, p.Name)
67+
default:
68+
ps.Formulae = append(ps.Formulae, p.Name)
69+
}
70+
}
71+
return nil
72+
}
73+
74+
// Try flat string array.
5175
var arr []string
5276
if err := json.Unmarshal(data, &arr); err == nil {
5377
ps.Formulae = arr
5478
return nil
5579
}
5680

57-
return fmt.Errorf("packages must be an object {formulae,casks,taps,npm} or a string array")
81+
return fmt.Errorf("packages must be an object {formulae,casks,taps,npm} or an array")
5882
}
5983

6084
type MacOSPref struct {

internal/snapshot/snapshot_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,24 @@ func TestPackageSnapshot_UnmarshalJSON(t *testing.T) {
5656
Npm: []string{"typescript"},
5757
},
5858
},
59+
{
60+
name: "typed object array",
61+
input: `[{"name":"git","type":"formula"},{"name":"docker","type":"cask"},{"name":"homebrew/core","type":"tap"},{"name":"typescript","type":"npm"}]`,
62+
expected: PackageSnapshot{
63+
Formulae: []string{"git"},
64+
Casks: []string{"docker"},
65+
Taps: []string{"homebrew/core"},
66+
Npm: []string{"typescript"},
67+
},
68+
},
69+
{
70+
name: "typed object array with desc field",
71+
input: `[{"name":"ack","type":"formula","desc":"grep for programmers"},{"name":"alfred","type":"cask","desc":"Productivity app"}]`,
72+
expected: PackageSnapshot{
73+
Formulae: []string{"ack"},
74+
Casks: []string{"alfred"},
75+
},
76+
},
5977
{
6078
name: "flat array treated as formulae",
6179
input: `["git","curl","jq"]`,

0 commit comments

Comments
 (0)