Skip to content

Commit 86d6d9e

Browse files
Refactor: Change package.yaml schema and related Go code
This commit refactors the schema of `packages.yaml` from a list of packages with a 'type' field to a structure where packages are grouped by type directly under each group. - Changed `data/brew/packages.yaml` to the new schema: `groups.<group_name>.packages.<type> = [PackageInfo]` - Updated Go type definitions in `scripts/brew-management/pkg/types/types.go`: - Removed `Package` struct. - Introduced `PackageInfo` struct (name, tags, description, id). - Changed `Group.Packages` from `[]Package` to `map[string][]PackageInfo`. - Modified Go code in `scripts/brew-management/` to align with the new types: - Updated YAML (un)marshalling in `pkg/yaml/`. - Adjusted package filtering and processing in `cmd/install/`, `cmd/prune/`, `pkg/brew/`, `pkg/convert/`, `pkg/sync/`. - Updated validation logic in `pkg/validate/`. - Updated `scripts/brew-management/packages.schema.json` to reflect the new schema. - Added `UniqueStrings` utility function. - Ensured `validate` command works with the new schema and skips Homebrew prerequisite check.
1 parent 309ef2b commit 86d6d9e

File tree

12 files changed

+654
-856
lines changed

12 files changed

+654
-856
lines changed

data/brew/packages.yaml

Lines changed: 335 additions & 654 deletions
Large diffs are not rendered by default.

scripts/brew-management/cmd/install.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,18 @@ Examples:
7575
}
7676

7777
// Get filtered packages
78-
packages := yamlPkg.GetFilteredPackages(config, options)
78+
filteredPackages := yamlPkg.GetFilteredPackages(config, options)
7979

80-
if len(packages) == 0 {
80+
if len(filteredPackages) == 0 {
8181
utils.PrintStatus(utils.Yellow, "No packages found matching the specified criteria.")
8282
return
8383
}
8484

85-
utils.PrintStatus(utils.Blue, fmt.Sprintf("Found %d packages to install", len(packages)))
85+
utils.PrintStatus(utils.Blue, fmt.Sprintf("Found %d packages to install", len(filteredPackages)))
8686

8787
// Install packages
88-
if err := brew.InstallPackages(packages, options); err != nil {
88+
// Note: brew.InstallPackages will need to be adapted to handle []types.FilteredPackage
89+
if err := brew.InstallPackages(filteredPackages, options); err != nil {
8990
utils.PrintStatus(utils.Red, fmt.Sprintf("Installation failed: %v", err))
9091
return
9192
}
@@ -109,22 +110,22 @@ func handleListCommands(yamlFile string) error {
109110
priority int
110111
desc string
111112
}
112-
var groups []groupInfo
113+
var groupsToSort []groupInfo // Renamed to avoid conflict
113114

114115
for name, group := range config.Groups {
115-
groups = append(groups, groupInfo{
116+
groupsToSort = append(groupsToSort, groupInfo{ // Use renamed variable
116117
name: name,
117118
priority: group.Priority,
118119
desc: group.Description,
119120
})
120121
}
121122

122123
// Sort by priority
123-
sort.Slice(groups, func(i, j int) bool {
124-
return groups[i].priority < groups[j].priority
124+
sort.Slice(groupsToSort, func(i, j int) bool { // Use renamed variable
125+
return groupsToSort[i].priority < groupsToSort[j].priority // Use renamed variable
125126
})
126127

127-
for _, group := range groups {
128+
for _, group := range groupsToSort { // Use renamed variable
128129
fmt.Printf(" %s: %s (priority: %d)\n", group.name, group.desc, group.priority)
129130
}
130131
}
@@ -134,9 +135,11 @@ func handleListCommands(yamlFile string) error {
134135
tagSet := make(map[string]bool)
135136

136137
for _, group := range config.Groups {
137-
for _, pkg := range group.Packages {
138-
for _, tag := range pkg.Tags {
139-
tagSet[tag] = true
138+
for _, pkgInfos := range group.Packages { // Iterate through map values (slices of PackageInfo)
139+
for _, pkgInfo := range pkgInfos { // Iterate through PackageInfo slices
140+
for _, tag := range pkgInfo.Tags { // Access Tags from PackageInfo
141+
tagSet[tag] = true
142+
}
140143
}
141144
}
142145
}

scripts/brew-management/cmd/prune.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -133,20 +133,24 @@ func getAllPackagesFromConfig(config *types.PackageGrouped) map[string]map[strin
133133
"tap": make(map[string]bool),
134134
"brew": make(map[string]bool),
135135
"cask": make(map[string]bool),
136-
"mas": make(map[string]bool),
136+
"mas": make(map[string]bool), // MAS uses ID as string key
137137
}
138138

139139
for _, group := range config.Groups {
140-
for _, pkg := range group.Packages {
141-
switch pkg.Type {
142-
case "tap":
143-
result["tap"][pkg.Name] = true
144-
case "brew":
145-
result["brew"][pkg.Name] = true
146-
case "cask":
147-
result["cask"][pkg.Name] = true
148-
case "mas":
149-
result["mas"][fmt.Sprintf("%d", pkg.ID)] = true
140+
for pkgType, pkgInfos := range group.Packages { // Iterate over package types (brew, cask, etc.)
141+
for _, pkgInfo := range pkgInfos { // Iterate over packages of that type
142+
switch pkgType {
143+
case "tap":
144+
result["tap"][pkgInfo.Name] = true
145+
case "brew":
146+
result["brew"][pkgInfo.Name] = true
147+
case "cask":
148+
result["cask"][pkgInfo.Name] = true
149+
case "mas":
150+
if pkgInfo.ID != 0 { // Ensure ID is present for MAS apps
151+
result["mas"][fmt.Sprintf("%d", pkgInfo.ID)] = true
152+
}
153+
}
150154
}
151155
}
152156
}

scripts/brew-management/cmd/root.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ Examples:
3535
brew-manager prune --dry-run
3636
brew-manager validate`,
3737
PersistentPreRun: func(cmd *cobra.Command, args []string) {
38-
// Check prerequisites for most commands
39-
if cmd.Name() != "help" && cmd.Name() != "completion" {
38+
// Check prerequisites for most commands, skip for validate, help, and completion
39+
commandName := cmd.Name()
40+
if commandName != "validate" && commandName != "help" && commandName != "completion" {
4041
if err := utils.CheckPrerequisites(); err != nil {
4142
utils.PrintStatus(utils.Red, fmt.Sprintf("Error: %v", err))
4243
os.Exit(1)

scripts/brew-management/packages.schema.json

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,32 @@
1818
"description": "Installation priority (lower numbers install first)"
1919
},
2020
"packages": {
21-
"items": {
22-
"$ref": "#/$defs/Package"
23-
},
24-
"type": "array",
21+
"type": "object",
2522
"title": "Packages",
26-
"description": "Packages in this group"
23+
"description": "Packages in this group, categorized by type",
24+
"properties": {
25+
"tap": {
26+
"type": "array",
27+
"items": { "$ref": "#/$defs/PackageInfo" },
28+
"description": "Tap packages"
29+
},
30+
"brew": {
31+
"type": "array",
32+
"items": { "$ref": "#/$defs/PackageInfo" },
33+
"description": "Brew formula packages"
34+
},
35+
"cask": {
36+
"type": "array",
37+
"items": { "$ref": "#/$defs/PackageInfo" },
38+
"description": "Cask packages"
39+
},
40+
"mas": {
41+
"type": "array",
42+
"items": { "$ref": "#/$defs/PackageInfo" },
43+
"description": "Mac App Store packages"
44+
}
45+
},
46+
"additionalProperties": false
2747
}
2848
},
2949
"additionalProperties": false,
@@ -34,30 +54,20 @@
3454
"packages"
3555
]
3656
},
37-
"Package": {
57+
"PackageInfo": {
3858
"properties": {
3959
"name": {
4060
"type": "string",
4161
"minLength": 1,
4262
"title": "Package Name",
4363
"description": "Package name"
4464
},
45-
"type": {
46-
"type": "string",
47-
"enum": [
48-
"tap",
49-
"brew",
50-
"cask",
51-
"mas"
52-
],
53-
"title": "Package Type",
54-
"description": "Package type"
55-
},
5665
"tags": {
5766
"items": {
5867
"type": "string"
5968
},
6069
"type": "array",
70+
"uniqueItems": true,
6171
"title": "Tags",
6272
"description": "Tags for categorization and filtering"
6373
},
@@ -77,8 +87,7 @@
7787
"additionalProperties": false,
7888
"type": "object",
7989
"required": [
80-
"name",
81-
"type"
90+
"name"
8291
]
8392
},
8493
"PackageGrouped": {
@@ -119,6 +128,7 @@
119128
"type": "string"
120129
},
121130
"type": "array",
131+
"uniqueItems": true,
122132
"title": "Groups",
123133
"description": "Groups to include in this profile"
124134
},
@@ -127,6 +137,7 @@
127137
"type": "string"
128138
},
129139
"type": "array",
140+
"uniqueItems": true,
130141
"title": "Tags",
131142
"description": "Tags to include in this profile"
132143
},
@@ -135,6 +146,7 @@
135146
"type": "string"
136147
},
137148
"type": "array",
149+
"uniqueItems": true,
138150
"title": "Exclude Tags",
139151
"description": "Tags to exclude from this profile"
140152
}

scripts/brew-management/pkg/brew/brew.go

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@ import (
1010
)
1111

1212
// InstallPackages installs packages based on configuration and options
13-
func InstallPackages(packages []types.Package, options *types.InstallOptions) error {
13+
func InstallPackages(filteredPackages []types.FilteredPackage, options *types.InstallOptions) error {
1414
if err := utils.CheckPrerequisites(); err != nil {
1515
return err
1616
}
1717

1818
// Group packages by type
19-
packagesByType := make(map[string][]types.Package)
20-
for _, pkg := range packages {
21-
packagesByType[pkg.Type] = append(packagesByType[pkg.Type], pkg)
19+
packagesByType := make(map[string][]types.PackageInfo)
20+
for _, filteredPkg := range filteredPackages {
21+
packagesByType[filteredPkg.Type] = append(packagesByType[filteredPkg.Type], filteredPkg.PackageInfo)
2222
}
2323

2424
// Install in order: taps, brews, casks, mas
2525
order := []string{"tap", "brew", "cask", "mas"}
2626

2727
for _, pkgType := range order {
28-
packages := packagesByType[pkgType]
29-
if len(packages) == 0 {
28+
pkgInfos := packagesByType[pkgType]
29+
if len(pkgInfos) == 0 {
3030
continue
3131
}
3232

@@ -35,7 +35,7 @@ func InstallPackages(packages []types.Package, options *types.InstallOptions) er
3535
continue
3636
}
3737

38-
if err := installPackagesByType(pkgType, packages, options); err != nil {
38+
if err := installPackagesByType(pkgType, pkgInfos, options); err != nil {
3939
return fmt.Errorf("failed to install %s packages: %w", pkgType, err)
4040
}
4141
}
@@ -59,41 +59,46 @@ func shouldSkipType(pkgType string, options *types.InstallOptions) bool {
5959
}
6060

6161
// installPackagesByType installs packages of a specific type
62-
func installPackagesByType(pkgType string, packages []types.Package, options *types.InstallOptions) error {
62+
func installPackagesByType(pkgType string, pkgInfos []types.PackageInfo, options *types.InstallOptions) error {
6363
utils.PrintStatus(utils.Blue, fmt.Sprintf("Installing %s packages...", pkgType))
6464

65-
for _, pkg := range packages {
65+
for _, pkgInfo := range pkgInfos {
6666
if options.Verbose {
67-
utils.PrintStatus(utils.Cyan, fmt.Sprintf("Processing %s: %s", pkgType, pkg.Name))
67+
utils.PrintStatus(utils.Cyan, fmt.Sprintf("Processing %s: %s", pkgType, pkgInfo.Name))
6868
}
6969

7070
if options.DryRun {
71-
utils.PrintStatus(utils.Yellow, fmt.Sprintf("[DRY RUN] Would install %s: %s", pkgType, pkg.Name))
71+
utils.PrintStatus(utils.Yellow, fmt.Sprintf("[DRY RUN] Would install %s: %s", pkgType, pkgInfo.Name))
7272
continue
7373
}
7474

75-
if err := installSinglePackage(pkgType, pkg, options.Verbose); err != nil {
76-
utils.PrintStatus(utils.Red, fmt.Sprintf("Failed to install %s: %s - %v", pkgType, pkg.Name, err))
75+
if err := installSinglePackage(pkgType, pkgInfo, options.Verbose); err != nil {
76+
utils.PrintStatus(utils.Red, fmt.Sprintf("Failed to install %s: %s - %v", pkgType, pkgInfo.Name, err))
77+
// Decide if we should continue or stop on error. For now, continue.
7778
continue
7879
}
7980

80-
utils.PrintStatus(utils.Green, fmt.Sprintf("Installed %s: %s", pkgType, pkg.Name))
81+
utils.PrintStatus(utils.Green, fmt.Sprintf("Installed %s: %s", pkgType, pkgInfo.Name))
8182
}
8283

8384
return nil
8485
}
8586

8687
// installSinglePackage installs a single package
87-
func installSinglePackage(pkgType string, pkg types.Package, verbose bool) error {
88+
func installSinglePackage(pkgType string, pkgInfo types.PackageInfo, verbose bool) error {
8889
switch pkgType {
8990
case "tap":
90-
return installTap(pkg.Name, verbose)
91+
return installTap(pkgInfo.Name, verbose)
9192
case "brew":
92-
return installBrew(pkg.Name, verbose)
93+
return installBrew(pkgInfo.Name, verbose)
9394
case "cask":
94-
return installCask(pkg.Name, verbose)
95+
return installCask(pkgInfo.Name, verbose)
9596
case "mas":
96-
return installMas(pkg.Name, pkg.ID, verbose)
97+
// 'mas' type requires ID. Ensure it's present.
98+
if pkgInfo.ID == 0 {
99+
return fmt.Errorf("missing ID for mas package: %s", pkgInfo.Name)
100+
}
101+
return installMas(pkgInfo.Name, pkgInfo.ID, verbose)
97102
default:
98103
return fmt.Errorf("unknown package type: %s", pkgType)
99104
}

0 commit comments

Comments
 (0)