11package macup
22
33import (
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.
3111type 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.
20823var Updates = []Update {
20924 {"brew" , "Update Homebrew packages" , UpdateBrew },
0 commit comments