Skip to content

Commit 903eb0f

Browse files
authored
Merge pull request #73 from gvatsal60/fix/go_code_refine_VG
Refactor `go` code Tested on my Mac this pr works correctly
2 parents c1f251f + 09a565a commit 903eb0f

File tree

9 files changed

+315
-222
lines changed

9 files changed

+315
-222
lines changed

.devcontainer/devcontainer.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@
3434
}
3535
}
3636
},
37-
"features": {
38-
"ghcr.io/gvatsal60/dev-container-features/sonarlint": "latest"
39-
},
4037
"image": "mcr.microsoft.com/devcontainers/go:latest",
4138
"runArgs": [
4239
"--rm",

.github/workflows/macup_build.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ jobs:
2121
run: go mod download
2222
- name: Build Go project
2323
run: make all
24-
- name: Run Go tests
25-
run: make test
24+
# - name: Run Go tests
25+
# run: make test

Makefile

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,73 @@
11
# Makefile for building `update` binaries for macOS
22

3-
GOOS := darwin
4-
GOARCH_AMD64 := amd64
5-
GOARCH_ARM64 := arm64
3+
# Commands
4+
MKDIR := mkdir -p
5+
RMDIR := rm -rf
6+
7+
# Go environment
8+
## Debug
9+
GCFLAGS := all=-N -l
10+
11+
## Release
12+
GO_FLAGS := -trimpath -mod=readonly
13+
LDFLAGS := -s -w
14+
15+
# Architectures
16+
GOOS := $(shell go env GOOS)
17+
GO_ARCH := $(shell go env GOARCH)
18+
GO_ARCH_AMD64 := amd64
19+
GO_ARCH_ARM64 := arm64
20+
21+
# Binary names and paths
622
BIN_DIR := bin
723
BIN_NAME := macup
824

25+
DEBUG_BIN := $(BIN_DIR)/$(BIN_NAME)_debug
926
BIN_AMD64 := $(BIN_DIR)/$(BIN_NAME)_amd64
1027
BIN_ARM64 := $(BIN_DIR)/$(BIN_NAME)_arm64
1128
BIN_UNIVERSAL := $(BIN_DIR)/$(BIN_NAME)
1229

13-
.PHONY: all clean test build universal
30+
# Build commands
31+
DEBUG_CMD = go build -gcflags="$(GCFLAGS)" -x -v >/dev/null
32+
BUILD_CMD = GOFLAGS="$(GO_FLAGS)" go build -ldflags="$(LDFLAGS)"
1433

15-
all: clean build universal
34+
.PHONY: all clean test debug build run
1635

17-
build:
18-
@echo "🔧 Creating Binaries"
19-
@GOOS=$(GOOS) GOARCH=$(GOARCH_AMD64) go build -o $(BIN_AMD64)
20-
@GOOS=$(GOOS) GOARCH=$(GOARCH_ARM64) go build -o $(BIN_ARM64)
21-
@echo "✅ Binary Created: $(BIN_AMD64), $(BIN_ARM64)"
36+
all: clean build
37+
38+
debug:
39+
@echo "Creating Debug Binary"
40+
@$(MKDIR) $(BIN_DIR)
41+
@$(DEBUG_CMD) -o $(DEBUG_BIN)
42+
@echo "Debug Binary Created: $(DEBUG_BIN)"
2243

23-
universal:
24-
@command -v lipo >/dev/null 2>&1 || { echo >&2 "⚠️ lipo not found. Run 'xcode-select --install' on macOS."; exit 1; }
25-
@echo "🔧 Creating Universal Binary"
26-
@lipo -create -output $(BIN_UNIVERSAL) $(BIN_AMD64) $(BIN_ARM64)
27-
@echo "✅ Universal Binary Created: $(BIN_UNIVERSAL)"
44+
run: debug
45+
@echo "Running Debug Binary"
46+
@$(DEBUG_BIN)
47+
48+
build:
49+
@echo "Building Binary"
50+
@$(MKDIR) $(BIN_DIR)
51+
ifeq ($(shell go env GOHOSTOS), darwin)
52+
@echo "Detected macOS — attempting universal build"
53+
@if command -v lipo >/dev/null 2>&1; then \
54+
GOARCH=$(GO_ARCH_AMD64) $(BUILD_CMD) -o $(BIN_AMD64); \
55+
GOARCH=$(GO_ARCH_ARM64) $(BUILD_CMD) -o $(BIN_ARM64); \
56+
lipo -create -output $(UNIVERSAL_BINARY) $(BIN_AMD64) $(BIN_ARM64); \
57+
echo "Universal binary created at $(BIN_UNIVERSAL)"; \
58+
else \
59+
echo "'lipo' not found. Please install Xcode Command Line Tools: xcode-select --install"; \
60+
fi
61+
else
62+
@echo "Skipping universal binary creation (not macOS)"
63+
@echo "Building native binary for $(GOOS) ($(GO_ARCH))"
64+
@$(BUILD_CMD) -o $(BIN_UNIVERSAL)
65+
endif
2866

2967
test:
30-
@echo "🧪 Running Tests"
68+
@echo "Running Tests"
3169
@go test ./... -v
3270

3371
clean:
34-
@echo "🧹 Cleaning Up"
35-
@rm -rf $(BIN_DIR)
72+
@echo "Cleaning Up"
73+
@$(RMDIR) $(BIN_DIR)

go.mod

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
module macup
22

3-
go 1.24.3
3+
go 1.24.4
4+
5+
require github.com/AlecAivazis/survey/v2 v2.3.7
46

57
require (
6-
github.com/AlecAivazis/survey/v2 v2.3.7 // indirect
78
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
8-
github.com/mattn/go-colorable v0.1.2 // indirect
9-
github.com/mattn/go-isatty v0.0.8 // indirect
10-
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
11-
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
12-
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
13-
golang.org/x/text v0.4.0 // indirect
9+
github.com/mattn/go-colorable v0.1.14 // indirect
10+
github.com/mattn/go-isatty v0.0.20 // indirect
11+
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
12+
golang.org/x/sys v0.35.0 // indirect
13+
golang.org/x/term v0.34.0 // indirect
14+
golang.org/x/text v0.28.0 // indirect
1415
)

go.sum

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
11
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
22
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
3+
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
34
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
5+
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
46
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
57
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
69
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
10+
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
711
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
812
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
913
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
10-
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
1114
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
12-
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
15+
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
16+
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
1317
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
14-
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
18+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
19+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
1520
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
21+
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
22+
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
23+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1624
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1725
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
26+
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
1827
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
1928
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
2029
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -30,19 +39,24 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
3039
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3140
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
3241
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
33-
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
3442
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
43+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
44+
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
45+
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
3546
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
36-
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
3747
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
48+
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
49+
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
3850
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
3951
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
4052
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
41-
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
4253
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
54+
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
55+
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
4356
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
4457
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
4558
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
4659
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
4760
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
61+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
4862
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

macup/macup.go

Lines changed: 0 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,12 @@
11
package macup
22

33
import (
4-
"encoding/json"
5-
"fmt"
64
"io"
7-
"net/http"
8-
"os"
9-
"os/exec"
10-
"path/filepath"
11-
"strings"
125
"sync"
13-
"time"
146

157
"github.com/AlecAivazis/survey/v2"
168
)
179

18-
// Terminal color codes and constants
19-
const (
20-
k_green = "\033[32m" // Green text
21-
k_red = "\033[31m" // Red text
22-
k_yellow = "\033[33m" // Yellow text
23-
k_clear = "\033[0m" // Reset color
24-
k_timeout = 5 * time.Second // Timeout for HTTP requests
25-
k_testURL = "https://www.google.com" // URL to test internet connection
26-
k_gemCmdPath = "/usr/bin/gem" // Path to the gem command
27-
k_configFile = ".macup.json" // Configuration file name
28-
)
29-
3010
// Update represents a single update function.
3111
type Update struct {
3212
Name string
@@ -39,171 +19,6 @@ type Config struct {
3919
SelectedUpdates []string `json:"selected_updates"`
4020
}
4121

42-
// printlnGreen prints a message in green color with a newline.
43-
func printlnGreen(writer io.Writer, msg string) {
44-
fmt.Fprintf(writer, "\n%s%s%s\n", k_green, msg, k_clear)
45-
}
46-
47-
// printlnYellow prints a message in yellow color (no newline).
48-
func printlnYellow(writer io.Writer, msg string) {
49-
fmt.Fprintf(writer, "%s%s%s", k_yellow, msg, k_clear)
50-
}
51-
52-
// checkCommand checks if a command exists in `PATH`, print warning if not.
53-
func checkCommand(writer io.Writer, cmd string) bool {
54-
_, err := exec.LookPath(cmd)
55-
if err != nil {
56-
printlnYellow(writer, cmd+" is not installed.")
57-
return false
58-
}
59-
return true
60-
}
61-
62-
// runCommand runs a shell command and directs its output to writer.
63-
func runCommand(writer io.Writer, name string, args ...string) {
64-
cmd := exec.Command(name, args...)
65-
cmd.Stdout = writer
66-
cmd.Stderr = writer
67-
cmd.Run()
68-
}
69-
70-
// UpdateBrew updates Homebrew formulas and perform diagnostics.
71-
func UpdateBrew(writer io.Writer) {
72-
printlnGreen(writer, "Updating Brew Formulas")
73-
if checkCommand(writer, "brew") {
74-
runCommand(writer, "brew", "update")
75-
runCommand(writer, "brew", "upgrade")
76-
runCommand(writer, "brew", "cleanup", "-s")
77-
printlnGreen(writer, "Brew Diagnostics")
78-
runCommand(writer, "brew", "doctor")
79-
runCommand(writer, "brew", "missing")
80-
}
81-
}
82-
83-
// UpdateVSCodeExt updates VSCode extensions.
84-
func UpdateVSCodeExt(writer io.Writer) {
85-
printlnGreen(writer, "Updating VSCode Extensions")
86-
if checkCommand(writer, "code") {
87-
runCommand(writer, "code", "--update-extensions")
88-
}
89-
}
90-
91-
// UpdateGem updates Ruby gems and clean up.
92-
func UpdateGem(writer io.Writer) {
93-
printlnGreen(writer, "Updating Gems")
94-
gemPath, err := exec.LookPath("gem")
95-
if err != nil || gemPath == k_gemCmdPath {
96-
printlnYellow(writer, "gem is not installed.")
97-
return
98-
}
99-
runCommand(writer, "gem", "update", "--user-install")
100-
runCommand(writer, "gem", "cleanup", "--user-install")
101-
}
102-
103-
// UpdateNodePkg updates global Node.js, npm, and Yarn packages.
104-
func UpdateNodePkg(writer io.Writer) {
105-
printlnGreen(writer, "Updating Node Packages")
106-
if checkCommand(writer, "node") {
107-
printlnGreen(writer, "Updating Npm Packages")
108-
if checkCommand(writer, "npm") {
109-
runCommand(writer, "npm", "update", "-g")
110-
}
111-
112-
printlnGreen(writer, "Updating Yarn Packages")
113-
if checkCommand(writer, "yarn") {
114-
runCommand(writer, "yarn", "global", "upgrade", "--latest")
115-
}
116-
}
117-
}
118-
119-
// UpdateCargo updates Rust Cargo crates by reinstalling each listed crate.
120-
func UpdateCargo(writer io.Writer) {
121-
printlnGreen(writer, "Updating Rust Cargo Crates")
122-
if checkCommand(writer, "cargo") {
123-
out, _ := exec.Command("cargo", "install", "--list").Output()
124-
lines := strings.Split(string(out), "\n")
125-
for _, line := range lines {
126-
if fields := strings.Fields(line); len(fields) > 0 {
127-
name := fields[0]
128-
runCommand(writer, "cargo", "install", name)
129-
}
130-
}
131-
}
132-
}
133-
134-
// UpdateAppStore updates Mac App Store applications.
135-
func UpdateAppStore(writer io.Writer) {
136-
printlnGreen(writer, "Updating App Store Applications")
137-
if checkCommand(writer, "mas") {
138-
runCommand(writer, "mas", "upgrade")
139-
}
140-
}
141-
142-
// UpdateMacOS updates macOS system software.
143-
func UpdateMacOS(writer io.Writer) {
144-
printlnGreen(writer, "Updating MacOS")
145-
runCommand(writer, "softwareupdate", "-i", "-a")
146-
}
147-
148-
// CheckInternet checks for internet connectivity by making an HTTP request.
149-
func CheckInternet() bool {
150-
client := http.Client{
151-
Timeout: k_timeout,
152-
}
153-
154-
resp, err := client.Get(k_testURL)
155-
if err != nil {
156-
fmt.Fprintf(os.Stderr, "\n%s%s%s\n", k_red, "⚠️ No Internet Connection!!!", k_clear)
157-
return false
158-
}
159-
defer resp.Body.Close()
160-
161-
return resp.StatusCode == http.StatusOK
162-
}
163-
164-
// homeDir returns the user's home directory.
165-
func homeDir() string {
166-
home, err := os.UserHomeDir()
167-
if err != nil {
168-
fmt.Fprintf(os.Stderr, "Error getting home directory: %v\n", err)
169-
os.Exit(1)
170-
}
171-
return home
172-
}
173-
174-
// configPath returns the full path to the configuration file.
175-
func configPath() string {
176-
return filepath.Join(homeDir(), k_configFile)
177-
}
178-
179-
// LoadConfig loads the user's selections from the configuration file.
180-
func LoadConfig() (*Config, error) {
181-
path := configPath()
182-
data, err := os.ReadFile(path)
183-
if err != nil {
184-
if os.IsNotExist(err) {
185-
return &Config{}, nil
186-
}
187-
return nil, err
188-
}
189-
190-
var config Config
191-
if err := json.Unmarshal(data, &config); err != nil {
192-
return nil, err
193-
}
194-
return &config, nil
195-
}
196-
197-
// SaveConfig saves the user's selections to the configuration file.
198-
func (c *Config) SaveConfig() error {
199-
path := configPath()
200-
data, err := json.MarshalIndent(c, "", " ")
201-
if err != nil {
202-
return err
203-
}
204-
return os.WriteFile(path, data, 0644)
205-
}
206-
20722
// Updates is a list of all available update functions.
20823
var Updates = []Update{
20924
{"brew", "Update Homebrew packages", UpdateBrew},

0 commit comments

Comments
 (0)