@fredlackey/devutils 0.0.18 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (447) hide show
  1. package/README.md +214 -141
  2. package/package.json +8 -83
  3. package/src/api/loader.js +229 -0
  4. package/src/api/registry.json +62 -0
  5. package/src/cli.js +293 -60
  6. package/src/commands/ai/index.js +16 -0
  7. package/src/commands/ai/launch.js +112 -0
  8. package/src/commands/ai/list.js +54 -0
  9. package/src/commands/ai/resume.js +70 -0
  10. package/src/commands/ai/sessions.js +121 -0
  11. package/src/commands/ai/set.js +131 -0
  12. package/src/commands/ai/show.js +74 -0
  13. package/src/commands/ai/tools.js +46 -0
  14. package/src/commands/alias/add.js +93 -0
  15. package/src/commands/alias/helpers.js +107 -0
  16. package/src/commands/alias/index.js +14 -0
  17. package/src/commands/alias/list.js +55 -0
  18. package/src/commands/alias/remove.js +62 -0
  19. package/src/commands/alias/sync.js +109 -0
  20. package/src/commands/api/disable.js +73 -0
  21. package/src/commands/api/enable.js +148 -0
  22. package/src/commands/api/index.js +15 -0
  23. package/src/commands/api/list.js +66 -0
  24. package/src/commands/api/update.js +87 -0
  25. package/src/commands/auth/index.js +15 -0
  26. package/src/commands/auth/list.js +49 -0
  27. package/src/commands/auth/login.js +384 -0
  28. package/src/commands/auth/logout.js +111 -0
  29. package/src/commands/auth/refresh.js +184 -0
  30. package/src/commands/auth/services.js +169 -0
  31. package/src/commands/auth/status.js +104 -0
  32. package/src/commands/config/export.js +224 -0
  33. package/src/commands/config/get.js +52 -0
  34. package/src/commands/config/import.js +308 -0
  35. package/src/commands/config/index.js +17 -0
  36. package/src/commands/config/init.js +143 -0
  37. package/src/commands/config/reset.js +57 -0
  38. package/src/commands/config/set.js +93 -0
  39. package/src/commands/config/show.js +35 -0
  40. package/src/commands/help.js +338 -0
  41. package/src/commands/identity/add.js +133 -0
  42. package/src/commands/identity/index.js +17 -0
  43. package/src/commands/identity/link.js +76 -0
  44. package/src/commands/identity/list.js +48 -0
  45. package/src/commands/identity/remove.js +72 -0
  46. package/src/commands/identity/show.js +65 -0
  47. package/src/commands/identity/sync.js +172 -0
  48. package/src/commands/identity/unlink.js +57 -0
  49. package/src/commands/ignore/add.js +165 -0
  50. package/src/commands/ignore/index.js +14 -0
  51. package/src/commands/ignore/list.js +89 -0
  52. package/src/commands/ignore/markers.js +43 -0
  53. package/src/commands/ignore/remove.js +164 -0
  54. package/src/commands/ignore/show.js +169 -0
  55. package/src/commands/machine/detect.js +122 -0
  56. package/src/commands/machine/index.js +14 -0
  57. package/src/commands/machine/list.js +74 -0
  58. package/src/commands/machine/set.js +106 -0
  59. package/src/commands/machine/show.js +35 -0
  60. package/src/commands/schema.js +152 -0
  61. package/src/commands/search/collections.js +134 -0
  62. package/src/commands/search/get.js +71 -0
  63. package/src/commands/search/index-cmd.js +54 -0
  64. package/src/commands/search/index.js +21 -0
  65. package/src/commands/search/keyword.js +60 -0
  66. package/src/commands/search/qmd.js +70 -0
  67. package/src/commands/search/query.js +64 -0
  68. package/src/commands/search/semantic.js +62 -0
  69. package/src/commands/search/status.js +46 -0
  70. package/src/commands/status.js +224 -171
  71. package/src/commands/tools/check.js +79 -0
  72. package/src/commands/tools/index.js +14 -0
  73. package/src/commands/tools/install.js +110 -0
  74. package/src/commands/tools/list.js +91 -0
  75. package/src/commands/tools/search.js +60 -0
  76. package/src/commands/update.js +83 -112
  77. package/src/commands/util/add.js +151 -0
  78. package/src/commands/util/index.js +15 -0
  79. package/src/commands/util/list.js +97 -0
  80. package/src/commands/util/remove.js +76 -0
  81. package/src/commands/util/run.js +79 -0
  82. package/src/commands/util/show.js +67 -0
  83. package/src/commands/version.js +21 -88
  84. package/src/installers/_template.js +104 -0
  85. package/src/installers/git.js +150 -0
  86. package/src/installers/homebrew.js +190 -0
  87. package/src/installers/node.js +223 -0
  88. package/src/installers/registry.json +29 -0
  89. package/src/lib/config.js +125 -0
  90. package/src/lib/detect.js +74 -0
  91. package/src/lib/errors.js +114 -0
  92. package/src/lib/github.js +315 -0
  93. package/src/lib/installer.js +225 -0
  94. package/src/lib/output.js +239 -0
  95. package/src/lib/platform.js +112 -0
  96. package/src/lib/platforms/amazon-linux.js +41 -0
  97. package/src/lib/platforms/gitbash.js +46 -0
  98. package/src/lib/platforms/macos.js +45 -0
  99. package/src/lib/platforms/raspbian.js +41 -0
  100. package/src/lib/platforms/ubuntu.js +39 -0
  101. package/src/lib/platforms/windows.js +45 -0
  102. package/src/lib/prompt.js +161 -0
  103. package/src/lib/schema.js +211 -0
  104. package/src/lib/shell.js +75 -0
  105. package/src/patterns/gitignore/claude-code.txt +25 -0
  106. package/src/patterns/gitignore/docker.txt +15 -0
  107. package/src/patterns/gitignore/go.txt +24 -0
  108. package/src/patterns/gitignore/java.txt +38 -0
  109. package/src/patterns/gitignore/jetbrains.txt +26 -0
  110. package/src/patterns/gitignore/linux.txt +18 -0
  111. package/src/patterns/gitignore/macos.txt +27 -0
  112. package/src/patterns/gitignore/node.txt +51 -0
  113. package/src/patterns/gitignore/python.txt +55 -0
  114. package/src/patterns/gitignore/rust.txt +14 -0
  115. package/src/patterns/gitignore/terraform.txt +30 -0
  116. package/src/patterns/gitignore/vscode.txt +15 -0
  117. package/src/patterns/gitignore/windows.txt +25 -0
  118. package/src/utils/clone/index.js +165 -0
  119. package/src/utils/git-push/index.js +230 -0
  120. package/src/utils/git-status/index.js +116 -0
  121. package/src/utils/git-status/unix.sh +75 -0
  122. package/src/utils/registry.json +41 -0
  123. package/bin/dev.js +0 -16
  124. package/files/README.md +0 -0
  125. package/files/claude/.claude/commands/setup-context.md +0 -3
  126. package/files/monorepos/_archive/README.md +0 -36
  127. package/files/monorepos/_legacy/README.md +0 -36
  128. package/files/monorepos/ai-docs/README.md +0 -33
  129. package/files/monorepos/apps/README.md +0 -24
  130. package/files/monorepos/docs/README.md +0 -40
  131. package/files/monorepos/packages/README.md +0 -25
  132. package/files/monorepos/research/README.md +0 -29
  133. package/files/monorepos/scripts/README.md +0 -24
  134. package/src/commands/README.md +0 -41
  135. package/src/commands/configure.js +0 -199
  136. package/src/commands/identity.js +0 -1630
  137. package/src/commands/ignore.js +0 -247
  138. package/src/commands/install.js +0 -526
  139. package/src/commands/setup.js +0 -246
  140. package/src/completion.js +0 -284
  141. package/src/constants.js +0 -45
  142. package/src/ignore/claude-code.txt +0 -10
  143. package/src/ignore/docker.txt +0 -18
  144. package/src/ignore/linux.txt +0 -23
  145. package/src/ignore/macos.txt +0 -36
  146. package/src/ignore/node.txt +0 -55
  147. package/src/ignore/terraform.txt +0 -37
  148. package/src/ignore/vscode.txt +0 -18
  149. package/src/ignore/windows.txt +0 -35
  150. package/src/index.js +0 -0
  151. package/src/installs/README.md +0 -399
  152. package/src/installs/adobe-creative-cloud.js +0 -546
  153. package/src/installs/adobe-creative-cloud.md +0 -605
  154. package/src/installs/appcleaner.js +0 -321
  155. package/src/installs/appcleaner.md +0 -699
  156. package/src/installs/apt-transport-https.js +0 -390
  157. package/src/installs/apt-transport-https.md +0 -678
  158. package/src/installs/atomicparsley.js +0 -642
  159. package/src/installs/atomicparsley.md +0 -795
  160. package/src/installs/aws-cli.js +0 -797
  161. package/src/installs/aws-cli.md +0 -727
  162. package/src/installs/balena-etcher.js +0 -710
  163. package/src/installs/balena-etcher.md +0 -761
  164. package/src/installs/bambu-studio.js +0 -1143
  165. package/src/installs/bambu-studio.md +0 -780
  166. package/src/installs/bash-completion.js +0 -575
  167. package/src/installs/bash-completion.md +0 -833
  168. package/src/installs/bash.js +0 -417
  169. package/src/installs/bash.md +0 -993
  170. package/src/installs/beyond-compare.js +0 -603
  171. package/src/installs/beyond-compare.md +0 -813
  172. package/src/installs/brave-browser.js +0 -968
  173. package/src/installs/brave-browser.md +0 -650
  174. package/src/installs/build-essential.js +0 -529
  175. package/src/installs/build-essential.md +0 -977
  176. package/src/installs/ca-certificates.js +0 -618
  177. package/src/installs/ca-certificates.md +0 -937
  178. package/src/installs/caffeine.js +0 -508
  179. package/src/installs/caffeine.md +0 -839
  180. package/src/installs/camtasia.js +0 -596
  181. package/src/installs/camtasia.md +0 -762
  182. package/src/installs/chatgpt.js +0 -476
  183. package/src/installs/chatgpt.md +0 -814
  184. package/src/installs/chocolatey.js +0 -456
  185. package/src/installs/chocolatey.md +0 -661
  186. package/src/installs/chrome-canary.js +0 -419
  187. package/src/installs/chrome-canary.md +0 -641
  188. package/src/installs/chromium.js +0 -667
  189. package/src/installs/chromium.md +0 -838
  190. package/src/installs/claude-code.js +0 -576
  191. package/src/installs/claude-code.md +0 -1173
  192. package/src/installs/cloudflare-warp.js +0 -900
  193. package/src/installs/cloudflare-warp.md +0 -1047
  194. package/src/installs/comet-browser.js +0 -588
  195. package/src/installs/comet-browser.md +0 -731
  196. package/src/installs/curl.js +0 -379
  197. package/src/installs/curl.md +0 -714
  198. package/src/installs/cursor.js +0 -579
  199. package/src/installs/cursor.md +0 -970
  200. package/src/installs/dbeaver.js +0 -924
  201. package/src/installs/dbeaver.md +0 -939
  202. package/src/installs/dbschema.js +0 -692
  203. package/src/installs/dbschema.md +0 -925
  204. package/src/installs/dependencies.md +0 -453
  205. package/src/installs/development-tools.js +0 -600
  206. package/src/installs/development-tools.md +0 -977
  207. package/src/installs/docker.js +0 -1029
  208. package/src/installs/docker.md +0 -1109
  209. package/src/installs/drawio.js +0 -1019
  210. package/src/installs/drawio.md +0 -795
  211. package/src/installs/elmedia-player.js +0 -347
  212. package/src/installs/elmedia-player.md +0 -556
  213. package/src/installs/ffmpeg.js +0 -889
  214. package/src/installs/ffmpeg.md +0 -852
  215. package/src/installs/file.js +0 -464
  216. package/src/installs/file.md +0 -987
  217. package/src/installs/gemini-cli.js +0 -811
  218. package/src/installs/gemini-cli.md +0 -1153
  219. package/src/installs/git.js +0 -400
  220. package/src/installs/git.md +0 -907
  221. package/src/installs/gitego.js +0 -949
  222. package/src/installs/gitego.md +0 -1172
  223. package/src/installs/go.js +0 -931
  224. package/src/installs/go.md +0 -958
  225. package/src/installs/google-antigravity.js +0 -913
  226. package/src/installs/google-antigravity.md +0 -1075
  227. package/src/installs/google-chrome.js +0 -833
  228. package/src/installs/google-chrome.md +0 -862
  229. package/src/installs/gpg.js +0 -480
  230. package/src/installs/gpg.md +0 -1056
  231. package/src/installs/homebrew.js +0 -1028
  232. package/src/installs/homebrew.md +0 -988
  233. package/src/installs/imageoptim.js +0 -968
  234. package/src/installs/imageoptim.md +0 -1119
  235. package/src/installs/installers.json +0 -4032
  236. package/src/installs/installers.json.tmp +0 -3953
  237. package/src/installs/jq.js +0 -400
  238. package/src/installs/jq.md +0 -809
  239. package/src/installs/keyboard-maestro.js +0 -719
  240. package/src/installs/keyboard-maestro.md +0 -825
  241. package/src/installs/kiro.js +0 -864
  242. package/src/installs/kiro.md +0 -1015
  243. package/src/installs/latex.js +0 -789
  244. package/src/installs/latex.md +0 -1095
  245. package/src/installs/lftp.js +0 -356
  246. package/src/installs/lftp.md +0 -907
  247. package/src/installs/lsb-release.js +0 -346
  248. package/src/installs/lsb-release.md +0 -814
  249. package/src/installs/messenger.js +0 -847
  250. package/src/installs/messenger.md +0 -900
  251. package/src/installs/microsoft-office.js +0 -568
  252. package/src/installs/microsoft-office.md +0 -760
  253. package/src/installs/microsoft-teams.js +0 -801
  254. package/src/installs/microsoft-teams.md +0 -886
  255. package/src/installs/moom.js +0 -326
  256. package/src/installs/moom.md +0 -570
  257. package/src/installs/node.js +0 -904
  258. package/src/installs/node.md +0 -1153
  259. package/src/installs/nordpass.js +0 -716
  260. package/src/installs/nordpass.md +0 -921
  261. package/src/installs/nordvpn.js +0 -892
  262. package/src/installs/nordvpn.md +0 -1052
  263. package/src/installs/nvm.js +0 -995
  264. package/src/installs/nvm.md +0 -1057
  265. package/src/installs/ohmyzsh.js +0 -529
  266. package/src/installs/ohmyzsh.md +0 -1094
  267. package/src/installs/openssh.js +0 -804
  268. package/src/installs/openssh.md +0 -1056
  269. package/src/installs/pandoc.js +0 -662
  270. package/src/installs/pandoc.md +0 -1036
  271. package/src/installs/parallels-desktop.js +0 -431
  272. package/src/installs/parallels-desktop.md +0 -446
  273. package/src/installs/pinentry.js +0 -510
  274. package/src/installs/pinentry.md +0 -1142
  275. package/src/installs/pngyu.js +0 -869
  276. package/src/installs/pngyu.md +0 -896
  277. package/src/installs/postman.js +0 -799
  278. package/src/installs/postman.md +0 -940
  279. package/src/installs/procps.js +0 -425
  280. package/src/installs/procps.md +0 -851
  281. package/src/installs/safari-tech-preview.js +0 -374
  282. package/src/installs/safari-tech-preview.md +0 -533
  283. package/src/installs/sfnt2woff.js +0 -658
  284. package/src/installs/sfnt2woff.md +0 -795
  285. package/src/installs/shellcheck.js +0 -481
  286. package/src/installs/shellcheck.md +0 -1005
  287. package/src/installs/slack.js +0 -741
  288. package/src/installs/slack.md +0 -865
  289. package/src/installs/snagit.js +0 -585
  290. package/src/installs/snagit.md +0 -844
  291. package/src/installs/software-properties-common.js +0 -372
  292. package/src/installs/software-properties-common.md +0 -805
  293. package/src/installs/spotify.js +0 -877
  294. package/src/installs/spotify.md +0 -901
  295. package/src/installs/studio-3t.js +0 -823
  296. package/src/installs/studio-3t.md +0 -918
  297. package/src/installs/sublime-text.js +0 -804
  298. package/src/installs/sublime-text.md +0 -914
  299. package/src/installs/superwhisper.js +0 -706
  300. package/src/installs/superwhisper.md +0 -630
  301. package/src/installs/tailscale.js +0 -745
  302. package/src/installs/tailscale.md +0 -1100
  303. package/src/installs/tar.js +0 -389
  304. package/src/installs/tar.md +0 -946
  305. package/src/installs/termius.js +0 -798
  306. package/src/installs/termius.md +0 -844
  307. package/src/installs/terraform.js +0 -779
  308. package/src/installs/terraform.md +0 -899
  309. package/src/installs/tfenv.js +0 -778
  310. package/src/installs/tfenv.md +0 -1091
  311. package/src/installs/tidal.js +0 -771
  312. package/src/installs/tidal.md +0 -864
  313. package/src/installs/tmux.js +0 -346
  314. package/src/installs/tmux.md +0 -1030
  315. package/src/installs/tree.js +0 -411
  316. package/src/installs/tree.md +0 -833
  317. package/src/installs/unzip.js +0 -460
  318. package/src/installs/unzip.md +0 -879
  319. package/src/installs/vim.js +0 -421
  320. package/src/installs/vim.md +0 -1040
  321. package/src/installs/vlc.js +0 -821
  322. package/src/installs/vlc.md +0 -927
  323. package/src/installs/vscode.js +0 -843
  324. package/src/installs/vscode.md +0 -1002
  325. package/src/installs/wget.js +0 -420
  326. package/src/installs/wget.md +0 -791
  327. package/src/installs/whatsapp.js +0 -729
  328. package/src/installs/whatsapp.md +0 -854
  329. package/src/installs/winpty.js +0 -352
  330. package/src/installs/winpty.md +0 -620
  331. package/src/installs/woff2.js +0 -553
  332. package/src/installs/woff2.md +0 -977
  333. package/src/installs/wsl.js +0 -572
  334. package/src/installs/wsl.md +0 -699
  335. package/src/installs/xcode-clt.js +0 -520
  336. package/src/installs/xcode-clt.md +0 -351
  337. package/src/installs/xcode.js +0 -560
  338. package/src/installs/xcode.md +0 -573
  339. package/src/installs/yarn.js +0 -824
  340. package/src/installs/yarn.md +0 -1074
  341. package/src/installs/yq.js +0 -654
  342. package/src/installs/yq.md +0 -944
  343. package/src/installs/yt-dlp.js +0 -701
  344. package/src/installs/yt-dlp.md +0 -946
  345. package/src/installs/yum-utils.js +0 -297
  346. package/src/installs/yum-utils.md +0 -648
  347. package/src/installs/zoom.js +0 -759
  348. package/src/installs/zoom.md +0 -884
  349. package/src/installs/zsh.js +0 -455
  350. package/src/installs/zsh.md +0 -1008
  351. package/src/scripts/README.md +0 -617
  352. package/src/scripts/STATUS.md +0 -208
  353. package/src/scripts/afk.js +0 -411
  354. package/src/scripts/backup-all.js +0 -746
  355. package/src/scripts/backup-source.js +0 -727
  356. package/src/scripts/brewd.js +0 -389
  357. package/src/scripts/brewi.js +0 -520
  358. package/src/scripts/brewr.js +0 -527
  359. package/src/scripts/brews.js +0 -477
  360. package/src/scripts/brewu.js +0 -504
  361. package/src/scripts/c.js +0 -201
  362. package/src/scripts/ccurl.js +0 -341
  363. package/src/scripts/certbot-crontab-init.js +0 -504
  364. package/src/scripts/certbot-init.js +0 -657
  365. package/src/scripts/ch.js +0 -355
  366. package/src/scripts/claude-danger.js +0 -268
  367. package/src/scripts/clean-dev.js +0 -435
  368. package/src/scripts/clear-dns-cache.js +0 -541
  369. package/src/scripts/clone.js +0 -435
  370. package/src/scripts/code-all.js +0 -437
  371. package/src/scripts/count-files.js +0 -211
  372. package/src/scripts/count-folders.js +0 -211
  373. package/src/scripts/count.js +0 -264
  374. package/src/scripts/d.js +0 -219
  375. package/src/scripts/datauri.js +0 -389
  376. package/src/scripts/delete-files.js +0 -380
  377. package/src/scripts/docker-clean.js +0 -426
  378. package/src/scripts/dp.js +0 -442
  379. package/src/scripts/e.js +0 -390
  380. package/src/scripts/empty-trash.js +0 -513
  381. package/src/scripts/evm.js +0 -444
  382. package/src/scripts/fetch-github-repos.js +0 -456
  383. package/src/scripts/get-channel.js +0 -345
  384. package/src/scripts/get-course.js +0 -399
  385. package/src/scripts/get-dependencies.js +0 -306
  386. package/src/scripts/get-folder.js +0 -799
  387. package/src/scripts/get-tunes.js +0 -426
  388. package/src/scripts/get-video.js +0 -367
  389. package/src/scripts/git-backup.js +0 -577
  390. package/src/scripts/git-clone.js +0 -493
  391. package/src/scripts/git-pup.js +0 -319
  392. package/src/scripts/git-push.js +0 -396
  393. package/src/scripts/h.js +0 -622
  394. package/src/scripts/hide-desktop-icons.js +0 -499
  395. package/src/scripts/hide-hidden-files.js +0 -538
  396. package/src/scripts/install-dependencies-from.js +0 -456
  397. package/src/scripts/ips.js +0 -663
  398. package/src/scripts/iso.js +0 -370
  399. package/src/scripts/killni.js +0 -577
  400. package/src/scripts/ll.js +0 -467
  401. package/src/scripts/local-ip.js +0 -325
  402. package/src/scripts/m.js +0 -524
  403. package/src/scripts/map.js +0 -309
  404. package/src/scripts/mkd.js +0 -351
  405. package/src/scripts/ncu-update-all.js +0 -457
  406. package/src/scripts/nginx-init.js +0 -718
  407. package/src/scripts/npmi.js +0 -382
  408. package/src/scripts/o.js +0 -511
  409. package/src/scripts/org-by-date.js +0 -338
  410. package/src/scripts/p.js +0 -224
  411. package/src/scripts/packages.js +0 -330
  412. package/src/scripts/path.js +0 -225
  413. package/src/scripts/ports.js +0 -597
  414. package/src/scripts/q.js +0 -305
  415. package/src/scripts/refresh-files.js +0 -394
  416. package/src/scripts/remove-smaller-files.js +0 -516
  417. package/src/scripts/rename-files-with-date.js +0 -533
  418. package/src/scripts/resize-image.js +0 -539
  419. package/src/scripts/rm-safe.js +0 -669
  420. package/src/scripts/s.js +0 -540
  421. package/src/scripts/set-git-public.js +0 -365
  422. package/src/scripts/show-desktop-icons.js +0 -475
  423. package/src/scripts/show-hidden-files.js +0 -472
  424. package/src/scripts/tpa.js +0 -280
  425. package/src/scripts/tpo.js +0 -280
  426. package/src/scripts/u.js +0 -505
  427. package/src/scripts/vpush.js +0 -437
  428. package/src/scripts/y.js +0 -283
  429. package/src/utils/README.md +0 -95
  430. package/src/utils/common/apps.js +0 -143
  431. package/src/utils/common/display.js +0 -157
  432. package/src/utils/common/network.js +0 -185
  433. package/src/utils/common/os.js +0 -294
  434. package/src/utils/common/package-manager.js +0 -301
  435. package/src/utils/common/privileges.js +0 -138
  436. package/src/utils/common/shell.js +0 -261
  437. package/src/utils/macos/apps.js +0 -228
  438. package/src/utils/macos/brew.js +0 -315
  439. package/src/utils/ubuntu/apt.js +0 -307
  440. package/src/utils/ubuntu/desktop.js +0 -292
  441. package/src/utils/ubuntu/snap.js +0 -344
  442. package/src/utils/ubuntu/systemd.js +0 -286
  443. package/src/utils/windows/choco.js +0 -465
  444. package/src/utils/windows/env.js +0 -246
  445. package/src/utils/windows/registry.js +0 -269
  446. package/src/utils/windows/shell.js +0 -240
  447. package/src/utils/windows/winget.js +0 -489
@@ -1,1028 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * @fileoverview Install Homebrew package manager.
5
- * @module installs/homebrew
6
- *
7
- * Homebrew is a free and open-source package management system that simplifies
8
- * the installation of software on macOS and Linux. Originally created for macOS,
9
- * Homebrew has expanded to support Linux distributions via Linuxbrew.
10
- *
11
- * This installer provides:
12
- * - Native Homebrew installation on macOS (Intel and Apple Silicon)
13
- * - Linuxbrew installation on Ubuntu/Debian (x86_64)
14
- * - Linuxbrew installation on Amazon Linux (x86_64)
15
- * - Linuxbrew installation on Raspberry Pi OS (ARM64/ARM32 with limitations)
16
- * - Linuxbrew installation within WSL (Ubuntu)
17
- *
18
- * IMPORTANT PLATFORM NOTES:
19
- * - macOS: Full support with pre-compiled bottles for fast installation
20
- * - Ubuntu/Debian (x86_64): Full support with bottles via Linuxbrew
21
- * - Amazon Linux (x86_64): Full support with bottles via Linuxbrew
22
- * - Raspberry Pi OS (ARM64): Limited support; no bottles, packages compile from source
23
- * - Raspberry Pi OS (ARM32): Minimal support; requires system Ruby, no bottles
24
- * - Windows (Native): Not supported; use WSL for Homebrew on Windows
25
- * - Git Bash: Not supported; use WSL for Homebrew on Windows
26
- */
27
-
28
- const os = require('../utils/common/os');
29
- const shell = require('../utils/common/shell');
30
- const fs = require('fs');
31
- const path = require('path');
32
-
33
- /**
34
- * The URL for the Homebrew installation script.
35
- * This is the official installer maintained by the Homebrew project.
36
- */
37
- const HOMEBREW_INSTALL_URL = 'https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh';
38
-
39
- /**
40
- * Installation paths for Homebrew on different platforms.
41
- * These are the default locations where Homebrew installs itself.
42
- */
43
- const HOMEBREW_PATHS = {
44
- // macOS Apple Silicon (M1/M2/M3/M4)
45
- macos_arm: '/opt/homebrew',
46
- // macOS Intel
47
- macos_intel: '/usr/local',
48
- // Linux (including WSL)
49
- linux: '/home/linuxbrew/.linuxbrew'
50
- };
51
-
52
- /**
53
- * Required build dependencies for installing Homebrew on Debian-based Linux systems.
54
- * These packages are required to compile packages from source and run the installer.
55
- */
56
- const DEBIAN_BUILD_DEPENDENCIES = [
57
- 'build-essential', // Compilers and build tools (gcc, g++, make)
58
- 'procps', // Process utilities required by Homebrew
59
- 'curl', // For downloading the installer
60
- 'file', // File type detection utility
61
- 'git' // Version control system used by Homebrew
62
- ];
63
-
64
- /**
65
- * Required build dependencies for installing Homebrew on RHEL-based Linux systems.
66
- * These packages are required to compile packages from source and run the installer.
67
- */
68
- const RHEL_BUILD_DEPENDENCIES = [
69
- 'procps-ng', // Process utilities (Amazon Linux 2023 uses procps-ng)
70
- 'curl', // For downloading the installer
71
- 'file', // File type detection utility
72
- 'git' // Version control system used by Homebrew
73
- ];
74
-
75
- /**
76
- * Check if Homebrew is already installed by looking for the brew command.
77
- *
78
- * This is the primary method to detect if Homebrew is installed and functional.
79
- * It checks if 'brew' exists in the PATH and is executable.
80
- *
81
- * @returns {boolean} True if Homebrew is installed and available, false otherwise
82
- */
83
- function isBrewInstalled() {
84
- return shell.commandExists('brew');
85
- }
86
-
87
- /**
88
- * Get the installed Homebrew version.
89
- *
90
- * Executes 'brew --version' to retrieve the version string if Homebrew
91
- * is installed. Returns null if Homebrew is not installed or the command fails.
92
- *
93
- * @returns {Promise<string|null>} The Homebrew version string, or null if not installed
94
- */
95
- async function getBrewVersion() {
96
- if (!isBrewInstalled()) {
97
- return null;
98
- }
99
-
100
- const result = await shell.exec('brew --version');
101
- if (result.code === 0 && result.stdout) {
102
- // Output format: "Homebrew 4.4.15"
103
- const match = result.stdout.match(/Homebrew\s+([\d.]+)/);
104
- return match ? match[1] : result.stdout.trim().split('\n')[0];
105
- }
106
- return null;
107
- }
108
-
109
- /**
110
- * Check if Homebrew installation directory exists.
111
- *
112
- * This is a secondary check that looks for the Homebrew directory structure
113
- * even if the 'brew' command is not in PATH. Useful for detecting partial
114
- * installations that may need PATH configuration.
115
- *
116
- * @param {string} platform - The platform type ('macos', 'linux', etc.)
117
- * @returns {boolean} True if the Homebrew directory exists, false otherwise
118
- */
119
- function doesBrewDirectoryExist(platform) {
120
- if (platform === 'macos') {
121
- // Check both Apple Silicon and Intel paths
122
- const arch = os.getArch();
123
- const brewPath = arch === 'arm64' ? HOMEBREW_PATHS.macos_arm : HOMEBREW_PATHS.macos_intel;
124
- return fs.existsSync(path.join(brewPath, 'bin', 'brew'));
125
- }
126
-
127
- // Linux (Ubuntu, Debian, Amazon Linux, Raspberry Pi, WSL)
128
- return fs.existsSync(path.join(HOMEBREW_PATHS.linux, 'bin', 'brew'));
129
- }
130
-
131
- /**
132
- * Get the appropriate shell configuration file path for the current user.
133
- *
134
- * Determines which shell configuration file to modify for PATH configuration.
135
- * Checks the SHELL environment variable to determine the user's default shell.
136
- *
137
- * @returns {string} The path to the shell configuration file
138
- */
139
- function getShellConfigFile() {
140
- const homeDir = os.getHomeDir();
141
- const currentShell = process.env.SHELL || '';
142
-
143
- // Check for zsh (default on modern macOS)
144
- if (currentShell.includes('zsh')) {
145
- return path.join(homeDir, '.zshrc');
146
- }
147
-
148
- // Default to bash configuration files
149
- // On macOS, .bash_profile is used for login shells; on Linux, .bashrc
150
- if (process.platform === 'darwin') {
151
- return path.join(homeDir, '.bash_profile');
152
- }
153
-
154
- return path.join(homeDir, '.bashrc');
155
- }
156
-
157
- /**
158
- * Get the Homebrew shellenv command for PATH configuration.
159
- *
160
- * Returns the appropriate command to add Homebrew to the shell PATH.
161
- * The command varies based on the platform and processor architecture.
162
- *
163
- * @param {string} platform - The platform type ('macos', 'linux', etc.)
164
- * @returns {string} The shellenv command to add to shell configuration
165
- */
166
- function getShellenvCommand(platform) {
167
- if (platform === 'macos') {
168
- const arch = os.getArch();
169
- if (arch === 'arm64') {
170
- // Apple Silicon Mac
171
- return 'eval "$(/opt/homebrew/bin/brew shellenv)"';
172
- }
173
- // Intel Mac
174
- return 'eval "$(/usr/local/bin/brew shellenv)"';
175
- }
176
-
177
- // Linux (Ubuntu, Debian, Amazon Linux, Raspberry Pi, WSL)
178
- return 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"';
179
- }
180
-
181
- /**
182
- * Configure PATH for Homebrew by adding shellenv to shell configuration file.
183
- *
184
- * This function adds the Homebrew shellenv command to the appropriate shell
185
- * configuration file if it's not already present. It also runs the shellenv
186
- * command to make Homebrew available in the current session.
187
- *
188
- * @param {string} platform - The platform type ('macos', 'linux', etc.)
189
- * @returns {Promise<void>}
190
- */
191
- async function configureBrewPath(platform) {
192
- const shellConfigFile = getShellConfigFile();
193
- const shellenvCommand = getShellenvCommand(platform);
194
-
195
- console.log(`Configuring Homebrew in ${shellConfigFile}...`);
196
-
197
- // Check if the shellenv command is already in the config file
198
- let configContent = '';
199
- try {
200
- if (fs.existsSync(shellConfigFile)) {
201
- configContent = fs.readFileSync(shellConfigFile, 'utf8');
202
- }
203
- } catch (error) {
204
- // File doesn't exist or can't be read; we'll create it
205
- }
206
-
207
- // Only add the command if it's not already present
208
- if (!configContent.includes('brew shellenv')) {
209
- const lineToAdd = `\n# Homebrew\n${shellenvCommand}\n`;
210
-
211
- try {
212
- fs.appendFileSync(shellConfigFile, lineToAdd);
213
- console.log(`Added Homebrew to ${shellConfigFile}`);
214
- } catch (error) {
215
- console.log(`Warning: Could not update ${shellConfigFile}`);
216
- console.log(`Please add this line manually: ${shellenvCommand}`);
217
- }
218
- } else {
219
- console.log('Homebrew PATH configuration already exists in shell config.');
220
- }
221
-
222
- // Run shellenv to make brew available in the current process
223
- // Note: This won't persist to the parent shell, but it enables verification
224
- if (platform === 'macos') {
225
- const arch = os.getArch();
226
- const brewPath = arch === 'arm64' ? '/opt/homebrew/bin' : '/usr/local/bin';
227
- process.env.PATH = `${brewPath}:${process.env.PATH}`;
228
- } else {
229
- process.env.PATH = `/home/linuxbrew/.linuxbrew/bin:${process.env.PATH}`;
230
- }
231
- }
232
-
233
- /**
234
- * Install Homebrew on macOS.
235
- *
236
- * Prerequisites:
237
- * - macOS 14 (Sonoma) or later for full support (older versions may work)
238
- * - Apple Silicon (M1/M2/M3/M4) or 64-bit Intel processor
239
- * - Command Line Tools for Xcode (installed automatically if not present)
240
- * - Bash shell available (default on macOS)
241
- *
242
- * The installer automatically:
243
- * 1. Downloads Homebrew to /opt/homebrew (Apple Silicon) or /usr/local (Intel)
244
- * 2. Installs the Command Line Tools for Xcode if not present
245
- * 3. Configures the Homebrew environment
246
- *
247
- * @returns {Promise<void>}
248
- */
249
- async function install_macos() {
250
- console.log('Checking if Homebrew is already installed...');
251
-
252
- // Check if Homebrew is already installed via command
253
- const existingVersion = await getBrewVersion();
254
- if (existingVersion) {
255
- console.log(`Homebrew ${existingVersion} is already installed, skipping installation.`);
256
- return;
257
- }
258
-
259
- // Check if Homebrew directory exists but PATH is not configured
260
- if (doesBrewDirectoryExist('macos')) {
261
- console.log('Homebrew appears to be installed but not in PATH.');
262
- console.log('Configuring PATH...');
263
- await configureBrewPath('macos');
264
-
265
- // Verify it works now
266
- const versionAfterConfig = await getBrewVersion();
267
- if (versionAfterConfig) {
268
- console.log(`Homebrew ${versionAfterConfig} is now configured and ready.`);
269
- return;
270
- }
271
- }
272
-
273
- console.log('Installing Homebrew on macOS...');
274
- console.log('');
275
- console.log('This will install:');
276
- console.log(' - Homebrew package manager');
277
- console.log(' - Xcode Command Line Tools (if not already installed)');
278
- console.log('');
279
-
280
- // Run the official Homebrew installer with interactive terminal support
281
- // This allows the installer to prompt for sudo password when needed
282
- console.log('Downloading and running the Homebrew installer...');
283
- console.log('This may take several minutes...');
284
- console.log('You may be prompted for your password to complete the installation.');
285
- console.log('');
286
-
287
- const exitCode = await shell.spawnInteractive(
288
- `/bin/bash -c "$(curl -fsSL ${HOMEBREW_INSTALL_URL})"`
289
- );
290
-
291
- if (exitCode !== 0) {
292
- throw new Error(
293
- `Failed to install Homebrew (exit code: ${exitCode}).\n\n` +
294
- `Troubleshooting:\n` +
295
- ` 1. If Xcode Command Line Tools installation hung, run:\n` +
296
- ` xcode-select --install\n` +
297
- ` Then retry installing Homebrew.\n` +
298
- ` 2. For permission errors, ensure you own the target directory:\n` +
299
- ` sudo chown -R $(whoami) /opt/homebrew # Apple Silicon\n` +
300
- ` sudo chown -R $(whoami) /usr/local/Homebrew # Intel\n` +
301
- ` 3. Check your internet connection and retry.`
302
- );
303
- }
304
-
305
- // Configure PATH
306
- await configureBrewPath('macos');
307
-
308
- // Verify installation
309
- const version = await getBrewVersion();
310
- if (!version) {
311
- // Even if version check fails, the installation might be successful
312
- // Give user instructions to complete setup
313
- console.log('');
314
- console.log('Homebrew installation completed.');
315
- console.log('');
316
- console.log('IMPORTANT: To use Homebrew, either:');
317
- console.log(' 1. Open a new terminal window, OR');
318
- console.log(' 2. Run this command in your current terminal:');
319
- console.log(` ${getShellenvCommand('macos')}`);
320
- console.log('');
321
- console.log('Then verify with: brew --version');
322
- return;
323
- }
324
-
325
- console.log(`Homebrew ${version} installed successfully.`);
326
- console.log('');
327
- console.log('IMPORTANT: To use Homebrew in your current terminal, run:');
328
- console.log(` ${getShellenvCommand('macos')}`);
329
- console.log('');
330
- console.log('Or simply open a new terminal window.');
331
- console.log('');
332
- console.log('Verify with: brew --version');
333
- console.log('Run diagnostics: brew doctor');
334
- }
335
-
336
- /**
337
- * Install build dependencies on Ubuntu/Debian systems.
338
- *
339
- * Installs the required packages for Homebrew to function on Debian-based systems.
340
- * These packages include compilers, build tools, and utilities needed by Homebrew.
341
- *
342
- * @returns {Promise<void>}
343
- * @throws {Error} If package installation fails
344
- */
345
- async function installDebianBuildDependencies() {
346
- console.log('Installing required build dependencies...');
347
-
348
- // Update package lists first
349
- const updateResult = await shell.exec(
350
- 'sudo DEBIAN_FRONTEND=noninteractive apt-get update -y'
351
- );
352
- if (updateResult.code !== 0) {
353
- console.log('Warning: apt-get update had issues, continuing anyway...');
354
- }
355
-
356
- // Install build dependencies
357
- const packages = DEBIAN_BUILD_DEPENDENCIES.join(' ');
358
- const installResult = await shell.exec(
359
- `sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ${packages}`
360
- );
361
-
362
- if (installResult.code !== 0) {
363
- throw new Error(
364
- `Failed to install build dependencies.\n` +
365
- `Output: ${installResult.stderr}\n\n` +
366
- `Required packages: ${packages}\n` +
367
- `Please install them manually with:\n` +
368
- ` sudo apt-get update && sudo apt-get install -y ${packages}`
369
- );
370
- }
371
-
372
- console.log('Build dependencies installed successfully.');
373
- }
374
-
375
- /**
376
- * Install Homebrew on Ubuntu/Debian systems.
377
- *
378
- * Prerequisites:
379
- * - Ubuntu 20.04 LTS or later, or Debian 10 (Buster) or later (64-bit x86_64)
380
- * - sudo privileges
381
- * - curl and git installed (handled automatically)
382
- *
383
- * Homebrew on Linux (Linuxbrew) installs to /home/linuxbrew/.linuxbrew and
384
- * provides pre-compiled bottles for x86_64 architecture, enabling fast installation.
385
- *
386
- * @returns {Promise<void>}
387
- */
388
- async function install_ubuntu() {
389
- console.log('Checking if Homebrew is already installed...');
390
-
391
- // Check if Homebrew is already installed via command
392
- const existingVersion = await getBrewVersion();
393
- if (existingVersion) {
394
- console.log(`Homebrew ${existingVersion} is already installed, skipping installation.`);
395
- return;
396
- }
397
-
398
- // Check if Homebrew directory exists but PATH is not configured
399
- if (doesBrewDirectoryExist('linux')) {
400
- console.log('Homebrew appears to be installed but not in PATH.');
401
- console.log('Configuring PATH...');
402
- await configureBrewPath('linux');
403
-
404
- // Verify it works now
405
- const versionAfterConfig = await getBrewVersion();
406
- if (versionAfterConfig) {
407
- console.log(`Homebrew ${versionAfterConfig} is now configured and ready.`);
408
- return;
409
- }
410
- }
411
-
412
- console.log('Installing Homebrew on Ubuntu/Debian...');
413
- console.log('');
414
-
415
- // Install build dependencies
416
- await installDebianBuildDependencies();
417
-
418
- console.log('');
419
- console.log('Downloading and running the Homebrew installer...');
420
- console.log('This may take several minutes...');
421
- console.log('You may be prompted for your password to complete the installation.');
422
- console.log('');
423
-
424
- // Run the official Homebrew installer with interactive terminal support
425
- const exitCode = await shell.spawnInteractive(
426
- `/bin/bash -c "$(curl -fsSL ${HOMEBREW_INSTALL_URL})"`
427
- );
428
-
429
- if (exitCode !== 0) {
430
- throw new Error(
431
- `Failed to install Homebrew (exit code: ${exitCode}).\n\n` +
432
- `Troubleshooting:\n` +
433
- ` 1. Ensure all dependencies are installed:\n` +
434
- ` sudo apt-get install -y build-essential procps curl file git\n` +
435
- ` 2. Check your internet connection\n` +
436
- ` 3. If you see tar errors, run:\n` +
437
- ` sudo apt-get install -y tar`
438
- );
439
- }
440
-
441
- // Configure PATH
442
- await configureBrewPath('linux');
443
-
444
- // Verify installation
445
- const version = await getBrewVersion();
446
- if (!version) {
447
- console.log('');
448
- console.log('Homebrew installation completed.');
449
- console.log('');
450
- console.log('IMPORTANT: To use Homebrew, either:');
451
- console.log(' 1. Open a new terminal window, OR');
452
- console.log(' 2. Run this command in your current terminal:');
453
- console.log(` ${getShellenvCommand('linux')}`);
454
- console.log('');
455
- console.log('Then verify with: brew --version');
456
- return;
457
- }
458
-
459
- console.log(`Homebrew ${version} installed successfully.`);
460
- console.log('');
461
- console.log('IMPORTANT: To use Homebrew in your current terminal, run:');
462
- console.log(` ${getShellenvCommand('linux')}`);
463
- console.log('');
464
- console.log('Or simply open a new terminal window.');
465
- console.log('');
466
- console.log('Verify with: brew --version');
467
- console.log('Run diagnostics: brew doctor');
468
- }
469
-
470
- /**
471
- * Install Homebrew on Raspberry Pi OS.
472
- *
473
- * Prerequisites:
474
- * - Raspberry Pi OS Bookworm or Bullseye (64-bit recommended)
475
- * - Raspberry Pi 3B+ or later (64-bit capable hardware recommended)
476
- * - At least 2 GB RAM (4 GB recommended)
477
- * - sudo privileges
478
- *
479
- * IMPORTANT: Homebrew on ARM Linux is a Tier 3 platform:
480
- * - No pre-compiled binary packages (bottles) are available
481
- * - All packages must be compiled from source
482
- * - Installation takes significantly longer than on x86_64 platforms
483
- * - 32-bit (armv7l) requires system Ruby to be installed first
484
- *
485
- * @returns {Promise<void>}
486
- */
487
- async function install_raspbian() {
488
- console.log('Checking if Homebrew is already installed...');
489
-
490
- // Check if Homebrew is already installed via command
491
- const existingVersion = await getBrewVersion();
492
- if (existingVersion) {
493
- console.log(`Homebrew ${existingVersion} is already installed, skipping installation.`);
494
- return;
495
- }
496
-
497
- // Check if Homebrew directory exists but PATH is not configured
498
- if (doesBrewDirectoryExist('linux')) {
499
- console.log('Homebrew appears to be installed but not in PATH.');
500
- console.log('Configuring PATH...');
501
- await configureBrewPath('linux');
502
-
503
- // Verify it works now
504
- const versionAfterConfig = await getBrewVersion();
505
- if (versionAfterConfig) {
506
- console.log(`Homebrew ${versionAfterConfig} is now configured and ready.`);
507
- return;
508
- }
509
- }
510
-
511
- // Detect architecture to provide appropriate warnings
512
- const archResult = await shell.exec('uname -m');
513
- const arch = archResult.stdout.trim();
514
-
515
- console.log('Installing Homebrew on Raspberry Pi OS...');
516
- console.log('');
517
- console.log('IMPORTANT: Homebrew on ARM is a Tier 3 platform.');
518
- console.log('- No pre-compiled bottles are available');
519
- console.log('- All packages will compile from source');
520
- console.log('- Installation and package installation will be slow');
521
- console.log('');
522
-
523
- // Install build dependencies
524
- await installDebianBuildDependencies();
525
-
526
- // For 32-bit Raspberry Pi OS, we need to install system Ruby first
527
- if (arch === 'armv7l') {
528
- console.log('');
529
- console.log('Detected 32-bit Raspberry Pi OS (armv7l).');
530
- console.log('Installing system Ruby (required for 32-bit ARM)...');
531
-
532
- const rubyResult = await shell.exec(
533
- 'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ruby ruby-dev'
534
- );
535
- if (rubyResult.code !== 0) {
536
- throw new Error(
537
- `Failed to install Ruby, which is required for Homebrew on 32-bit ARM.\n` +
538
- `Please install Ruby manually:\n` +
539
- ` sudo apt-get install -y ruby ruby-dev\n` +
540
- `Then retry installing Homebrew.`
541
- );
542
- }
543
- console.log('Ruby installed successfully.');
544
- }
545
-
546
- console.log('');
547
- console.log('Downloading and running the Homebrew installer...');
548
- console.log('This may take several minutes (or longer on slower hardware)...');
549
- console.log('You may be prompted for your password to complete the installation.');
550
- console.log('');
551
-
552
- // Run the official Homebrew installer with interactive terminal support
553
- const exitCode = await shell.spawnInteractive(
554
- `/bin/bash -c "$(curl -fsSL ${HOMEBREW_INSTALL_URL})"`
555
- );
556
-
557
- if (exitCode !== 0) {
558
- throw new Error(
559
- `Failed to install Homebrew (exit code: ${exitCode}).\n\n` +
560
- `Troubleshooting:\n` +
561
- ` 1. Ensure all dependencies are installed:\n` +
562
- ` sudo apt-get install -y build-essential procps curl file git\n` +
563
- ` 2. For 32-bit (armv7l), ensure Ruby is installed:\n` +
564
- ` sudo apt-get install -y ruby ruby-dev\n` +
565
- ` 3. If compilation fails with out-of-memory errors, add swap space:\n` +
566
- ` sudo fallocate -l 2G /swapfile\n` +
567
- ` sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile\n` +
568
- ` 4. Check your internet connection and retry.`
569
- );
570
- }
571
-
572
- // Configure PATH
573
- await configureBrewPath('linux');
574
-
575
- // Verify installation
576
- const version = await getBrewVersion();
577
- if (!version) {
578
- console.log('');
579
- console.log('Homebrew installation completed.');
580
- console.log('');
581
- console.log('IMPORTANT: To use Homebrew, either:');
582
- console.log(' 1. Open a new terminal window, OR');
583
- console.log(' 2. Run this command in your current terminal:');
584
- console.log(` ${getShellenvCommand('linux')}`);
585
- console.log('');
586
- console.log('Then verify with: brew --version');
587
- return;
588
- }
589
-
590
- console.log(`Homebrew ${version} installed successfully.`);
591
- console.log('');
592
- console.log('IMPORTANT: To use Homebrew in your current terminal, run:');
593
- console.log(` ${getShellenvCommand('linux')}`);
594
- console.log('');
595
- console.log('Or simply open a new terminal window.');
596
- console.log('');
597
- console.log('NOTE: Package installation will be slow on Raspberry Pi because');
598
- console.log('all packages compile from source. Consider using apt for common tools.');
599
- console.log('');
600
- console.log('Verify with: brew --version');
601
- console.log('Run diagnostics: brew doctor (expect some warnings about ARM platform)');
602
- }
603
-
604
- /**
605
- * Install build dependencies on Amazon Linux/RHEL systems.
606
- *
607
- * Installs the required packages for Homebrew to function on RHEL-based systems.
608
- * Detects whether to use dnf (Amazon Linux 2023) or yum (Amazon Linux 2).
609
- *
610
- * @returns {Promise<void>}
611
- * @throws {Error} If package installation fails
612
- */
613
- async function installRhelBuildDependencies() {
614
- console.log('Installing required build dependencies...');
615
-
616
- // Detect package manager (dnf for AL2023, yum for AL2)
617
- const hasDnf = shell.commandExists('dnf');
618
- const packageManager = hasDnf ? 'dnf' : 'yum';
619
-
620
- console.log(`Using package manager: ${packageManager}`);
621
-
622
- // Install Development Tools group
623
- console.log('Installing Development Tools group...');
624
- const groupResult = await shell.exec(
625
- `sudo ${packageManager} groupinstall -y "Development Tools"`
626
- );
627
- if (groupResult.code !== 0) {
628
- console.log('Warning: Could not install Development Tools group, trying individual packages...');
629
- // Try installing gcc and make individually
630
- await shell.exec(`sudo ${packageManager} install -y gcc gcc-c++ make`);
631
- }
632
-
633
- // Install other required dependencies
634
- // Note: Amazon Linux 2023 uses procps-ng, AL2 uses procps
635
- const procpsPkg = hasDnf ? 'procps-ng' : 'procps';
636
- const packages = [procpsPkg, 'curl', 'file', 'git'].join(' ');
637
-
638
- const installResult = await shell.exec(
639
- `sudo ${packageManager} install -y ${packages}`
640
- );
641
-
642
- if (installResult.code !== 0) {
643
- throw new Error(
644
- `Failed to install build dependencies.\n` +
645
- `Output: ${installResult.stderr}\n\n` +
646
- `Please install them manually with:\n` +
647
- ` sudo ${packageManager} groupinstall -y "Development Tools"\n` +
648
- ` sudo ${packageManager} install -y ${packages}`
649
- );
650
- }
651
-
652
- console.log('Build dependencies installed successfully.');
653
- }
654
-
655
- /**
656
- * Install Homebrew on Amazon Linux/RHEL systems.
657
- *
658
- * Prerequisites:
659
- * - Amazon Linux 2023 (AL2023) or Amazon Linux 2 (AL2)
660
- * - 64-bit x86_64 architecture
661
- * - sudo privileges
662
- * - EC2 instance or compatible environment
663
- *
664
- * Amazon Linux 2023 uses DNF as the default package manager.
665
- * Amazon Linux 2 uses YUM.
666
- *
667
- * @returns {Promise<void>}
668
- */
669
- async function install_amazon_linux() {
670
- console.log('Checking if Homebrew is already installed...');
671
-
672
- // Check if Homebrew is already installed via command
673
- const existingVersion = await getBrewVersion();
674
- if (existingVersion) {
675
- console.log(`Homebrew ${existingVersion} is already installed, skipping installation.`);
676
- return;
677
- }
678
-
679
- // Check if Homebrew directory exists but PATH is not configured
680
- if (doesBrewDirectoryExist('linux')) {
681
- console.log('Homebrew appears to be installed but not in PATH.');
682
- console.log('Configuring PATH...');
683
- await configureBrewPath('linux');
684
-
685
- // Verify it works now
686
- const versionAfterConfig = await getBrewVersion();
687
- if (versionAfterConfig) {
688
- console.log(`Homebrew ${versionAfterConfig} is now configured and ready.`);
689
- return;
690
- }
691
- }
692
-
693
- console.log('Installing Homebrew on Amazon Linux...');
694
- console.log('');
695
-
696
- // Set locale to avoid warnings during installation
697
- process.env.LC_ALL = 'en_US.UTF-8';
698
- process.env.LANG = 'en_US.UTF-8';
699
-
700
- // Install build dependencies
701
- await installRhelBuildDependencies();
702
-
703
- console.log('');
704
- console.log('Downloading and running the Homebrew installer...');
705
- console.log('This may take several minutes...');
706
- console.log('You may be prompted for your password to complete the installation.');
707
- console.log('');
708
-
709
- // Run the official Homebrew installer with interactive terminal support
710
- const exitCode = await shell.spawnInteractive(
711
- `/bin/bash -c "$(curl -fsSL ${HOMEBREW_INSTALL_URL})"`
712
- );
713
-
714
- if (exitCode !== 0) {
715
- throw new Error(
716
- `Failed to install Homebrew (exit code: ${exitCode}).\n\n` +
717
- `Troubleshooting:\n` +
718
- ` 1. Ensure Development Tools are installed:\n` +
719
- ` sudo dnf groupinstall -y "Development Tools" # Amazon Linux 2023\n` +
720
- ` sudo yum groupinstall -y "Development Tools" # Amazon Linux 2\n` +
721
- ` 2. Install required dependencies:\n` +
722
- ` sudo dnf install -y procps-ng curl file git # Amazon Linux 2023\n` +
723
- ` sudo yum install -y procps curl file git # Amazon Linux 2\n` +
724
- ` 3. Set locale if you see locale warnings:\n` +
725
- ` export LC_ALL=en_US.UTF-8 && export LANG=en_US.UTF-8\n` +
726
- ` 4. Check your internet connection and retry.`
727
- );
728
- }
729
-
730
- // Configure PATH
731
- await configureBrewPath('linux');
732
-
733
- // Verify installation
734
- const version = await getBrewVersion();
735
- if (!version) {
736
- console.log('');
737
- console.log('Homebrew installation completed.');
738
- console.log('');
739
- console.log('IMPORTANT: To use Homebrew, either:');
740
- console.log(' 1. Open a new terminal window, OR');
741
- console.log(' 2. Run this command in your current terminal:');
742
- console.log(` ${getShellenvCommand('linux')}`);
743
- console.log('');
744
- console.log('Then verify with: brew --version');
745
- return;
746
- }
747
-
748
- console.log(`Homebrew ${version} installed successfully.`);
749
- console.log('');
750
- console.log('IMPORTANT: To use Homebrew in your current terminal, run:');
751
- console.log(` ${getShellenvCommand('linux')}`);
752
- console.log('');
753
- console.log('Or simply open a new terminal window.');
754
- console.log('');
755
- console.log('Verify with: brew --version');
756
- console.log('Run diagnostics: brew doctor');
757
- }
758
-
759
- /**
760
- * Handle Homebrew installation on native Windows.
761
- *
762
- * Homebrew does not run natively on Windows. This function informs the user
763
- * that they need to use WSL (Windows Subsystem for Linux) to use Homebrew.
764
- *
765
- * @returns {Promise<void>}
766
- */
767
- async function install_windows() {
768
- console.log('Homebrew is not available for native Windows.');
769
- console.log('');
770
- console.log('To use Homebrew on Windows, install Windows Subsystem for Linux (WSL):');
771
- console.log('');
772
- console.log('1. Open PowerShell as Administrator and run:');
773
- console.log(' wsl --install -d Ubuntu');
774
- console.log('');
775
- console.log('2. Restart your computer when prompted.');
776
- console.log('');
777
- console.log('3. After restart, open Ubuntu from the Start menu and complete setup.');
778
- console.log('');
779
- console.log('4. Then run this installer again from within WSL.');
780
- return;
781
- }
782
-
783
- /**
784
- * Install Homebrew on Ubuntu running in WSL (Windows Subsystem for Linux).
785
- *
786
- * Prerequisites:
787
- * - Windows 10 version 2004 (build 19041) or higher, or Windows 11
788
- * - WSL 2 enabled (WSL 1 has known issues with Homebrew)
789
- * - Ubuntu distribution installed in WSL
790
- * - sudo privileges within WSL
791
- *
792
- * The installation process is identical to native Ubuntu, but this function
793
- * provides WSL-specific messaging and warnings.
794
- *
795
- * @returns {Promise<void>}
796
- */
797
- async function install_ubuntu_wsl() {
798
- console.log('Detected Ubuntu running in WSL (Windows Subsystem for Linux).');
799
- console.log('');
800
-
801
- // Check if Homebrew is already installed via command
802
- const existingVersion = await getBrewVersion();
803
- if (existingVersion) {
804
- console.log(`Homebrew ${existingVersion} is already installed, skipping installation.`);
805
- return;
806
- }
807
-
808
- // Check if Homebrew directory exists but PATH is not configured
809
- if (doesBrewDirectoryExist('linux')) {
810
- console.log('Homebrew appears to be installed but not in PATH.');
811
- console.log('Configuring PATH...');
812
- await configureBrewPath('linux');
813
-
814
- // Verify it works now
815
- const versionAfterConfig = await getBrewVersion();
816
- if (versionAfterConfig) {
817
- console.log(`Homebrew ${versionAfterConfig} is now configured and ready.`);
818
- return;
819
- }
820
- }
821
-
822
- console.log('Installing Homebrew in WSL...');
823
- console.log('');
824
- console.log('NOTE: For best performance, ensure you are using WSL 2.');
825
- console.log('Check with: wsl.exe -l -v');
826
- console.log('');
827
-
828
- // Install build dependencies
829
- await installDebianBuildDependencies();
830
-
831
- console.log('');
832
- console.log('Downloading and running the Homebrew installer...');
833
- console.log('This may take several minutes...');
834
- console.log('You may be prompted for your password to complete the installation.');
835
- console.log('');
836
-
837
- // Run the official Homebrew installer with interactive terminal support
838
- const exitCode = await shell.spawnInteractive(
839
- `/bin/bash -c "$(curl -fsSL ${HOMEBREW_INSTALL_URL})"`
840
- );
841
-
842
- if (exitCode !== 0) {
843
- throw new Error(
844
- `Failed to install Homebrew in WSL (exit code: ${exitCode}).\n\n` +
845
- `Troubleshooting:\n` +
846
- ` 1. Ensure WSL 2 is being used (WSL 1 has known issues):\n` +
847
- ` Run in PowerShell: wsl --set-version Ubuntu 2\n` +
848
- ` 2. Ensure all dependencies are installed:\n` +
849
- ` sudo apt-get install -y build-essential procps curl file git\n` +
850
- ` 3. If apt-get update fails with network errors, restart WSL:\n` +
851
- ` Run in PowerShell: wsl --shutdown\n` +
852
- ` Then reopen Ubuntu.\n` +
853
- ` 4. Check your internet connection and retry.`
854
- );
855
- }
856
-
857
- // Configure PATH
858
- await configureBrewPath('linux');
859
-
860
- // Verify installation
861
- const version = await getBrewVersion();
862
- if (!version) {
863
- console.log('');
864
- console.log('Homebrew installation completed.');
865
- console.log('');
866
- console.log('IMPORTANT: To use Homebrew, either:');
867
- console.log(' 1. Open a new terminal window, OR');
868
- console.log(' 2. Run this command in your current terminal:');
869
- console.log(` ${getShellenvCommand('linux')}`);
870
- console.log('');
871
- console.log('Then verify with: brew --version');
872
- return;
873
- }
874
-
875
- console.log(`Homebrew ${version} installed successfully in WSL.`);
876
- console.log('');
877
- console.log('IMPORTANT: To use Homebrew in your current terminal, run:');
878
- console.log(` ${getShellenvCommand('linux')}`);
879
- console.log('');
880
- console.log('Or simply open a new terminal window.');
881
- console.log('');
882
- console.log('WSL Tips:');
883
- console.log(' - Store files in ~/... (Linux filesystem) for best performance');
884
- console.log(' - Accessing /mnt/c/... (Windows filesystem) is slower');
885
- console.log(' - Configure git line endings: git config --global core.autocrlf input');
886
- console.log('');
887
- console.log('Verify with: brew --version');
888
- console.log('Run diagnostics: brew doctor');
889
- }
890
-
891
- /**
892
- * Handle Homebrew installation in Git Bash.
893
- *
894
- * Homebrew does not run in Git Bash. This function informs the user
895
- * that they need to use WSL (Windows Subsystem for Linux) to use Homebrew.
896
- *
897
- * @returns {Promise<void>}
898
- */
899
- async function install_gitbash() {
900
- console.log('Homebrew is not available for Git Bash.');
901
- console.log('');
902
- console.log('Git Bash is a Windows terminal emulator that provides a bash-like');
903
- console.log('environment but does not include a full Linux userspace required');
904
- console.log('by Homebrew.');
905
- console.log('');
906
- console.log('To use Homebrew on Windows, install Windows Subsystem for Linux (WSL):');
907
- console.log('');
908
- console.log('1. Open PowerShell as Administrator and run:');
909
- console.log(' wsl --install -d Ubuntu');
910
- console.log('');
911
- console.log('2. Restart your computer when prompted.');
912
- console.log('');
913
- console.log('3. After restart, open Ubuntu from the Start menu and complete setup.');
914
- console.log('');
915
- console.log('4. Then run this installer from within WSL.');
916
- return;
917
- }
918
-
919
- /**
920
- * Check if Homebrew is currently installed on the system.
921
- *
922
- * This function checks for Homebrew installation across all supported platforms:
923
- * - macOS: Checks if brew command exists or Homebrew directory exists
924
- * - Linux/WSL: Checks if brew command exists or Linuxbrew directory exists
925
- * - Windows/Git Bash: Always returns false (Homebrew not supported)
926
- *
927
- * @returns {Promise<boolean>} True if Homebrew is installed, false otherwise
928
- */
929
- async function isInstalled() {
930
- const platform = os.detect();
931
-
932
- // Windows and Git Bash don't support Homebrew
933
- if (platform.type === 'windows' || platform.type === 'gitbash') {
934
- return false;
935
- }
936
-
937
- // Check if brew command exists
938
- if (isBrewInstalled()) {
939
- return true;
940
- }
941
-
942
- // Also check if Homebrew directory exists (may not be in PATH)
943
- if (platform.type === 'macos') {
944
- return doesBrewDirectoryExist('macos');
945
- }
946
-
947
- // Linux platforms (including WSL)
948
- return doesBrewDirectoryExist('linux');
949
- }
950
-
951
- /**
952
- * Check if this installer is supported on the current platform.
953
- * Homebrew is supported on macOS and Linux (including WSL).
954
- * Windows and Git Bash are NOT supported (use WSL instead).
955
- * @returns {boolean} True if installation is supported on this platform
956
- */
957
- function isEligible() {
958
- const platform = os.detect();
959
- // Homebrew does NOT run natively on Windows or Git Bash
960
- return ['macos', 'ubuntu', 'debian', 'wsl', 'raspbian', 'amazon_linux', 'rhel', 'fedora'].includes(platform.type);
961
- }
962
-
963
- /**
964
- * Main installation entry point.
965
- *
966
- * Detects the current platform and runs the appropriate installer function.
967
- * Handles platform-specific mappings to ensure all supported platforms
968
- * have appropriate installation logic.
969
- *
970
- * Supported platforms:
971
- * - macOS: Native Homebrew installation
972
- * - Ubuntu/Debian: Linuxbrew installation
973
- * - Raspberry Pi OS: Linuxbrew installation (with ARM limitations)
974
- * - Amazon Linux/RHEL: Linuxbrew installation
975
- * - WSL (Ubuntu): Linuxbrew installation within WSL
976
- * - Windows (Native): Not supported, advises WSL
977
- * - Git Bash: Not supported, advises WSL
978
- *
979
- * @returns {Promise<void>}
980
- */
981
- async function install() {
982
- const platform = os.detect();
983
-
984
- // Map platform types to their installer functions
985
- const installers = {
986
- 'macos': install_macos,
987
- 'ubuntu': install_ubuntu,
988
- 'debian': install_ubuntu,
989
- 'wsl': install_ubuntu_wsl,
990
- 'raspbian': install_raspbian,
991
- 'amazon_linux': install_amazon_linux,
992
- 'rhel': install_amazon_linux,
993
- 'fedora': install_amazon_linux,
994
- 'windows': install_windows,
995
- 'gitbash': install_gitbash
996
- };
997
-
998
- const installer = installers[platform.type];
999
-
1000
- if (!installer) {
1001
- console.log(`Homebrew is not available for ${platform.type}.`);
1002
- return;
1003
- }
1004
-
1005
- await installer();
1006
- }
1007
-
1008
- // Export all functions for use as a module and for testing
1009
- module.exports = {
1010
- install,
1011
- isInstalled,
1012
- isEligible,
1013
- install_macos,
1014
- install_ubuntu,
1015
- install_ubuntu_wsl,
1016
- install_raspbian,
1017
- install_amazon_linux,
1018
- install_windows,
1019
- install_gitbash
1020
- };
1021
-
1022
- // Allow direct execution: node homebrew.js
1023
- if (require.main === module) {
1024
- install().catch(err => {
1025
- console.error(err.message);
1026
- process.exit(1);
1027
- });
1028
- }