Go ile yazdığım bir komut satırı aracını paketlemek ve dağıtmak
Bir Go CLI aracını yazmak işin yarısı; onu sürümlemek, çapraz derlemek ve başkalarının kolayca kurabileceği biçimde dağıtmak diğer yarısı.
Yıllar önce Go’yu öğrenmek için küçük bir komut satırı aracı yazmıştım. O zaman ilgilendiğim şey aracın çalışmasıydı. Bu yıl aynı tür araçlardan birini ekip arkadaşlarımın da kullanmasını isteyince, daha önce hafife aldığım bir kısma odaklandım: bir aracı yazmak işin yarısı; onu insanların zahmetsizce kurabileceği hâle getirmek diğer yarısı.
Tek dosya: Go’nun sessiz avantajı
Go’nun bu iş için en büyük kozu, go build’in tek bir çalıştırılabilir dosya üretmesi. Çalışma zamanı yok, bağımlılık dizini yok. Bu dosyayı kopyalayan herkes aracı çalıştırabilir.
PHP ya da Node dünyasından gelince bunun ne kadar büyük bir kolaylık olduğu hemen anlaşılmıyor. Bir aracı paylaşmak demek, karşı tarafta doğru sürümün kurulu olmasını ummak demekti. Go’da bu soru hiç sorulmuyor.
Çapraz derleme
Tek bir komutla farklı işletim sistemleri için ayrı ikili dosyalar üretebiliyorsunuz:
GOOS=linux GOARCH=amd64 go build -o dist/arac-linux-amd64 .
GOOS=darwin GOARCH=arm64 go build -o dist/arac-darwin-arm64 .
GOOS=windows GOARCH=amd64 go build -o dist/arac-windows-amd64.exe .
Geliştirme makinem ne olursa olsun, kullanıcının makinesi için doğru ikiliyi üretebiliyorum. Bu adımı bir betiğe alıp her sürümde otomatik çalıştırıyorum.
Sürüm bilgisini ikiliye gömmek
Bir kullanıcı “hangi sürümü kullanıyorum?” diye sorabilmeli. Sürüm numarasını derleme anında, ldflags ile koda gömüyorum:
go build -ldflags "-X main.surum=1.4.0" -o arac .
package main
var surum = "dev"
func main() {
// --version bayrağı bu değeri yazdırır
}
Varsayılan dev; resmî bir sürüm derlendiğinde gerçek numara geçiyor. Bir hata raporu geldiğinde, kullanıcının elindeki sürümü tahmin etmek zorunda kalmıyorum.
Dağıtım ve kurulum
İkili dosyaları her sürümde bir depo sürümüne (release) ekliyorum. Kurulum böylece üç adıma iniyor: doğru dosyayı indir, çalıştırılabilir yap, PATH üzerindeki bir dizine taşı. Bunu da kısa bir kurulum betiğiyle tek komuta indirgemek mümkün.
go install: geliştiriciler için kısa yol
İkili dosya dağıtımı, Go kurulu olmayan kullanıcılar için doğru yol. Ama aracı kullanacak kişiler de geliştiriciyse, daha kısa bir yol var: go install.
go install github.com/kullanici/arac@latest
Bu komut, kaynaktan derleyip ikiliyi kullanıcının PATH’ine koyuyor. Tek satır, sürüm seçilebilir, ayrı bir indirme adımı yok. Ekip içi araçları çoğu zaman böyle dağıtıyorum; çünkü ekipte zaten herkeste Go kurulu.
Yani aslında iki ayrı kitleye iki ayrı dağıtım yolu sunuyorum: Go bilmeyenlere hazır ikili dosya, geliştiricilere go install. Bir aracı yaygınlaştırmanın sırrı, tek bir kurulum yöntemini herkese dayatmak değil; her kitleye onun için en az sürtünmeli yolu sunmaktır. Bu ayrımı yapmak birkaç dakikalık bir iş; ama aracın gerçekten kullanılıp kullanılmayacağını belirleyen şey çoğu zaman tam da bu.
Bir not daha: hangi yolu seçerseniz seçin, aracın dış bağımlılıklarını az tutun. Go’nun standart kütüphanesi şaşırtıcı derecede geniş; küçük bir araç için çoğu zaman tek bir dış pakete bile ihtiyaç olmuyor. Bağımlılık ne kadar azsa, derleme o kadar hızlı, ikili o kadar küçük ve aracın yıllar sonra hâlâ sorunsuz derlenme olasılığı o kadar yüksek.
Çıkardığım ders
Bir aracı kullanılır kılan, içindeki zekice kod değil; onu kurmanın ne kadar kolay olduğudur. Yıllar içinde teknik olarak iyi ama kurulumu zahmetli olduğu için kimsenin dokunmadığı çok araç gördüm. Go’yu bu tür işler için tercih etmemin sebebi sözdizimi değil; yazdığım şeyi başkasının eline “çalışır” hâlde ulaştırmayı bu kadar kolaylaştırması. Bir araç ancak kurulduğu kadar vardır.
Yorumlar
Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.