Homebrew के ज़रिए अपने स्क्रिप्ट distribute करना
(justin.searls.co)- Homebrew macOS पर CLI टूल्स को आसानी से install और manage करने वाला एक package manager है, जिसकी मदद से डेवलपर्स अक्सर इस्तेमाल होने वाले टूल्स के जरिए system environment को efficiently configure कर सकते हैं
- यह गाइड Homebrew का उपयोग करके personal CLI scripts को distribute करने की प्रक्रिया समझाती है, और GitHub integration व automated workflow के जरिए maintenance को सरल बनाने का तरीका बताती है
- distribution process CLI बनाना → GitHub release → Tap बनाना → Formula लिखना और update करना के क्रम में आगे बढ़ती है, और अंत में सिर्फ
brew tapऔरbrew installcommands से installation संभव हो जाता है - Homebrew की terminology और best practices को समझने पर reproducibility और supply-chain security को मजबूत करने वाली stable distribution संभव होती है
- GitHub Actions workflow के जरिए इसे automate किया जा सकता है, और एक बार setup हो जाने पर बाद में दूसरे CLI distribute करना भी काफ़ी आसान हो जाता है
पृष्ठभूमि और प्रेरणा
- Homebrew CLI टूल install करने के लिए पसंदीदा package manager है, और बहुत से डेवलपर्स इसका उपयोग करते हैं
- लेकिन अपने बनाए हुए CLI को अक्सर npm या RubyGem के ज़रिए distribute किया जाता है, इसलिए Homebrew distribution का तरीका थोड़ा अनजान लग सकता है
- Homebrew के official core repository में self-made tools को register करने से Homebrew team आमतौर पर बचती है, इसलिए सामान्य डेवलपर्स अलग tap और formula के जरिए distribute करते हैं
- यह गाइड सरल Ruby-आधारित CLI distribution अनुभव के आधार पर समझाती है
शब्दावली
- Homebrew beer-brewing theme को दर्शाने वाली अपनी खास terminology इस्तेमाल करता है, इसलिए इन्हें समझने पर system structure को समझना आसान हो जाता है
- Formula एक package definition file है, जिसमें source code या binary को install करने के निर्देश शामिल होते हैं
- Tap, Formula का Git repository होता है, जिसमें user या organization के हिसाब से custom packages manage किए जाते हैं
- Cask, GUI apps या बड़े binaries के installation manifest होते हैं; यह Formula जैसा है, लेकिन prebuilt files को handle करता है
- Bottle, source से build किए बिना prebuilt binary package को copy करने का तरीका है, जिससे installation speed बढ़ती है
- Cellar वह directory है जहाँ installed Formula रखे जाते हैं, जैसे
/opt/homebrew/Cellar - Keg किसी खास Formula का installation instance directory है, जो Cellar के अंदर version के हिसाब से रखा जाता है
अवलोकन
- Homebrew core repository niche या personal submissions स्वीकार नहीं करता, इसलिए users को CLI distribute करने के लिए अलग tap repository बनानी पड़ती है
- 1. CLI बनाकर GitHub पर अपलोड करें और tag release करें
- 2.
brew tap-newसे Tap बनाएं और GitHub पर push करें - 3.
brew createसे Formula बनाएं (tarball URL और SHA256 सहित) - 4. हर नए version release पर Formula update करें ताकि users
brew installcommand से आसानी से install कर सकें
- distribution पूरा होने के बाद user दो commands से CLI install कर सकता है:
brew tap your_github_handle/tapऔरbrew install your_cool_cli- यह गाइड CLI development को छोड़कर tap creation, Formula creation और update process पर focus करती है
- उदाहरण के तौर पर iMessage database से interactive web archive बनाने वाले
imsgCLI का उपयोग किया गया है
tap बनाना
- Homebrew की tap creation guide को follow करें, और अपनी GitHub username या organization name के हिसाब से values बदलें
- आगे सभी CLI tools को एक ही tap में रखने के लिए
homebrew-tapनाम recommend किया गया है;homebrewprefix को CLI में special handling मिलती है औरtapprefix प्रचलित convention है
- आगे सभी CLI tools को एक ही tap में रखने के लिए
- tap creation command चलाएँ:
brew tap-new searlsco/homebrew-tap- यह
/opt/homebrew/Library/Taps/searlsco/homebrew-tapमें scaffold बनाता है - GitHub पर corresponding repository बनाएं, फिर generated contents को push करें:
cd /opt/homebrew/Library/Taps/searlsco/homebrew-tap,git remote add origin git@github.com:searlsco/homebrew-tap.git,git push -u origin main
- यह
- tap का ownership लेने के बाद दूसरे users
brew tap searlsco/tapcommand से repository clone करके उसे/opt/homebrew/Library/Tapsमें रख सकते हैं- शुरुआत में इसमें कोई उपयोगी content नहीं होगा, लेकिन basic behavior verify किया जा सकता है
Formula बनाना
- Homebrew सीधे GitHub repository को refer कर सकता है, लेकिन reproducibility और open-source supply-chain security मजबूत करने के लिए versioned tarball और checksum इस्तेमाल करने की recommendation है
- GitHub tag push होने पर predictable URL पर tarball host करता है; उदाहरण के लिए
imsgrepository मेंgit tag v0.0.5,git push --tagsचलाने के बादhttps://github.com/searlsco/imsg/archive/refs/tags/v0.0.5.tar.gzबनता है
- GitHub tag push होने पर predictable URL पर tarball host करता है; उदाहरण के लिए
- Formula creation command:
brew create https://github.com/searlsco/imsg/archive/refs/tags/v0.0.5.tar.gz --tap searlsco/homebrew-tap --set-name imsg --ruby--tapflag custom tap specify करता है और Formula को/opt/homebrew/Library/Taps/searlsco/homebrew-tap/Formulaमें रखता है--set-name imsgFormula name को explicitly set करता है; duplicate names से बचने के लिए unique नाम चुनें (जैसे existing TLDR या standard CLI से conflict का ध्यान रखें)--rubyRuby CLI के लिए template preset है, जो customization आसान बनाने वाले कई options में से एक है
- generated Formula शुरुआत में काम न करे तो LLM की मदद से उसे ठीक किया जा सकता है:
brew install --verbose imsgचलाएँ, फिर error को ChatGPT में डालें और Formula update दोहराएँ- अंतिम Formula/imsg.rb file को Ruby CLI distribution के starting point के रूप में copy किया जा सकता है
- language-specific package manager के बजाय Homebrew के जरिए distribute करने पर implementation language बदलने के बाद भी user upgrades सुचारु रहते हैं
Formula के मुख्य highlights
- सभी Formula Ruby में लिखे जाते हैं, क्योंकि JavaScript या AI से पहले लोकप्रिय development tools का बड़ा हिस्सा Ruby-आधारित था
headmethod से Git repository specify किया जा सकता है, लेकिन इसका वास्तविक असर स्पष्ट नहीं हैlivecheckजोड़ना Formula version updates आसान बनाता है, इसलिए यह उपयोगी है- binary execution test को help output check करके सरलता से implement किया जा सकता है; generated comments देखकर घबराने की जरूरत नहीं
brew style searlsco/tapcommand से style errors check करें--rubytemplate का defaultuses_from_macos "ruby"2.6.10 version इस्तेमाल करता है (COVID से पहले की release, 3 साल पहले EOL), इसलिएdepends_on "ruby@3"के जरिए latest ruby Formula dependency recommend की जाती है
- जब Formula संतोषजनक लगे, तो
git pushके साथ live deploy करें; users फिरbrew tap searlsco/tapऔरbrew install imsgसे install कर सकते हैं
हर CLI release पर Formula update करना
- Formula के ऊपर मौजूद
urlऔरsha256hash को हर release पर manually update करना झंझट भरा है, और tag push या GitHub release बनाना भी थकाऊ लग सकता है- Homebrew का
bump-formula-prcommand या GitHub Actions PR बना सकते हैं, लेकिन fork और PR process बेवजह जटिल लगती है - अगर tap के owner आप ही हैं, तो main branch पर सीधे commit करने वाला सरल तरीका अधिक बेहतर है
- Homebrew का
- इससे बचने के लिए Formula repository में GitHub workflow जोड़ने की recommendation है, ताकि release पर tap अपने आप update हो जाए
- workflow example को copy करके इस्तेमाल किया जा सकता है
- setup के लिए: GitHub personal access token (PAT) बनाते समय
homebrew-taprepository परContent→Writepermission दें, और उसे Formula repository Secrets मेंHOMEBREW_TAP_TOKENनाम से save करें - environment variables के जरिए tap और Formula specify करें (जैसे line 13-15)
- GitHub bot account update recommend किया गया है:
GH_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com,GH_NAME: github-actions[bot]
- release बनाने के बाद
git push --tagsचलाते ही कुछ ही सेकंड में automatic update हो जाता है, और usersbrew updateवbrew upgrade imsgसे upgrade कर सकते हैं
सबसे अच्छी बात
- यह process जटिल ज़रूर है, लेकिन tap setup और एक Formula example पूरा हो जाने के बाद अतिरिक्त CLI distribution लगभग मामूली काम रह जाता है
- कुछ ही मिनटों में नया Formula publish किया जा सकता है, जो काफी सुविधाजनक है
- Homebrew की official process थोड़ी complex है, लेकिन automation इसे आसान बना देती है
- हर tool के release और distribution के बीच की झंझट कम होती है, और अलग-अलग languages के CLI तक support बढ़ाया जा सकता है
- वास्तव में कोई और Formula publish किया जाएगा या नहीं, यह निश्चित नहीं है, लेकिन यह संभावना खुली रहना ही संतोषजनक है
2 टिप्पणियां
--no-forkविकल्प मौजूद है, जिससे सीधे branch push करके merge किया जा सकता है, और यह automatic update फीचर भी प्रदान करता है.Hacker News राय
Homebrew की naming conventions कभी-कभी थोड़ी उलझाने वाली लगती हैं, लेकिन फिर भी बार-बार महसूस होता है कि यह कुल मिलाकर बेहद उपयोगी टूल है
साथ ही, अपना tap बनाकर टूल डिस्ट्रीब्यूट करने की प्रक्रिया इतनी आसान होगी, यह नहीं सोचा था
यह जानने की जिज्ञासा है कि language-specific package managers (जैसे: uv) की तुलना में यह किन मायनों में बेहतर है
खासकर जो लोग किसी खास ecosystem के भीतर नहीं हैं, उनके लिए क्या यह ज्यादा आसान है, यानी general-purpose usability के नज़रिए से क्या इसका कोई बढ़त है
धन्यवाद देते हुए, package registry इस्तेमाल करने वाले दूसरे टूल्स में आम तौर पर account creation, 2FA, signing process वगैरह की ज़रूरत होती है
Homebrew में GitHub terms of service (ToS) भरोसे की बुनियाद की तरह काम करता है, इसलिए पूरी प्रक्रिया काफी ज्यादा सरल हो जाती है
Homebrew टीम भी इस तरीके की वजह से बहुत-सी जटिलता कम कर पाती है
अगर Python packages के हिसाब से बात करें, तो uv की तरह सब कुछ एक साथ package करने की कोशिश व्यवहारिक रूप से कठिन है
इसलिए आम तौर पर venv environment में pinned dependencies ही install करने का तरीका इस्तेमाल किया जाता है
ठोस उदाहरण के लिए यह formula देख सकते हैं
uv के मामले में, official tools (
brew update-python-resources,homebrew-pypi-poet) से private packages को support कराने की कोशिश की थी, लेकिन वह ठीक से काम नहीं कर पायाइसलिए resource generation में मदद के लिए सीधे uvbrew बना लिया
Homebrew में Python formula लिखने के लिए official docs भी हैं
अगर आप Go developer हैं, तो Goreleaser टूल की सिफारिश की जाती है
यह personal tap में binary distribution को बहुत आसान बना देता है (हालाँकि official core में यह तरीका प्रतिबंधित है)
हर भाषा के project management में इसकी उपयोगिता काफी है
व्यक्तिगत रूप से, मुझे लगता है कि tap की तरफ से सीधे updates manage करना ज्यादा आदर्श है
यह आम तौर पर upstream से update होने वाले तरीके जैसा ही है
इस workflow को देखें, तो जिन formula/cask के मालिक आप नहीं हैं उन्हें भी आसानी से update किया जा सकता है
brew bumpकमांड से सब कुछ scan किया जा सकता है, PR बनाया जा सकता है, औरbrew test-botसे testing भी automate की जा सकती हैअसली PR का उदाहरण यहाँ देखा जा सकता है
आम तौर पर GitHub Actions usage time को लेकर हिचकिचाहट रहती थी, लेकिन open source में यह मुफ़्त है, इसलिए इस तरह इस्तेमाल करना ठीक लगेगा
अपने Homebrew tap के लिए version auto-bump workflow के रूप में मैंने खुद homebrew-bump-revision लिखा है
कई personal projects में इसका अच्छा उपयोग कर रहा हूँ
मैंने आलस की वजह से इसे आज़माया नहीं, लेकिन यह अच्छा टूल है
Ruby Rogues podcast में Homebrew के साथ CLI डिस्ट्रीब्यूट करने के तरह-तरह के tips पर एक episode था
इस episode link पर और जानकारी सुनी जा सकती है
Python tool packaging के बारे में एक दिलचस्प बात पता चली
कुछ Python packages में build process के दौरान dependency loop बन जाता है, जिससे वे Homebrew के साथ compatible नहीं रहते
pip binary releases डाउनलोड कर लेता है, इसलिए वहाँ दिक्कत नहीं होती, लेकिन Homebrew हर dependency को खुद build करता है, इसलिए यह प्रक्रिया काफी लंबी हो जाती है
इसी वजह से मध्यम आकार के Python projects में भी "bottle" build में एक घंटे से ज्यादा लग सकता है
सिस्टम मैनेजमेंट के लिए nix इस्तेमाल करना शुरू करने के बाद मुझे एक बार भी पछतावा नहीं हुआ
बस एक ही कमी लगती है कि multiplayer games की वजह से Windows पर निर्भर रहना पड़ता है