7 puan yazan GN⁺ 2025-05-10 | 3 yorum | WhatsApp'ta paylaş
  • Rust’ın bağımlılık yönetim sistemi geliştirmeyi kolaylaştırsa da, bağımlılıkların sayısı ve kalitesi düşündürüyor
  • İyi kullanılan bir crate bile güncel olmayabilir; bu yüzden bazen doğrudan kendin yazmak daha iyi olabilir
  • Axum, Tokio gibi popüler crate’ler eklendikten sonra, bağımlılıklar dahil toplam kod satırı sayısı 3,6 milyona ulaşıyor ve bunu yönetmek zorlaşıyor
  • Gerçekte benim yazdığım kod yalnızca yaklaşık 1.000 satır, ancak etrafındaki kodu fiilen gözden geçirmek ve denetlemek mümkün olmuyor
  • Rust’ın standart kütüphanesinin genişletilip genişletilmemesi ve temel altyapının nasıl uygulanacağı konusunda net bir çözüm yok; topluluğun tamamı performans, güvenlik ve bakım arasında dengeyi birlikte düşünmek zorunda

Rust bağımlılık sorununun genel görünümü

  • Rust benim en sevdiğim dil ve topluluğu ile dilin kullanılabilirliği çok güçlü
  • Geliştirme verimliliği yüksek, ancak son zamanlarda bağımlılık yönetimi konusunda endişelerim oluştu

Rust crate’leri ve Cargo’nun avantajları

  • Cargo ile paket yönetimi ve derleme işlerinin otomasyonu mümkün olduğu için verimlilik ciddi biçimde artıyor
  • Farklı işletim sistemleri ve mimariler arasında geçiş kolaylaşıyor; dosyaları elle yönetmek veya derleme araçlarını yapılandırmak gerekmiyor
  • Ayrı bir paket yönetimi derdi olmadan doğrudan kod yazmaya başlanabiliyor

Rust crate yönetiminin dezavantajları

  • Paket yönetimine daha az dikkat edildiği için istikrar ve güvenilirlik geri planda kalabiliyor
  • Örneğin dotenv crate’ini kullandım, ancak bakımının durduğunu bir Security Advisory üzerinden öğrendim
  • Alternatif crate olarak dotenvy’yi düşündüm, ama sonunda gerçekten gereken kısmı yaklaşık 35 satırda kendim yazdım
  • Birçok dilde paketlerin bakımsız kalması sık görüldüğü için, sorunun özü bağımlılıkların kaçınılmaz olduğu durumlar

Bağımlılıkların yol açtığı kod hacmi patlaması

  • Tokio, Axum gibi Rust ekosisteminin önemli ve kaliteli paketlerini kullanıyorum
  • Bağımlılık olarak Axum, Reqwest, ripunzip, serde, serde_json, tokio, tower-http, tracing ve tracing-subscriber eklendi
  • Ana amaç web sunucusu, dosya açma ve log işlevleri olduğu için projenin kendisi aslında basit
  • Cargo vendor özelliğini kullanarak tüm bağımlı crate’leri yerel olarak indirdim
  • tokei ile kod satırlarını analiz ettiğimde, bağımlılıklar dahil yaklaşık 3,6 milyon satıra ulaştığını gördüm (vendor edilen crate’ler hariç yaklaşık 11.136 satır)
  • Karşılaştırma için, Linux çekirdeğinin tamamının yaklaşık 27,8 milyon satır olduğu söyleniyor; yani benim küçük projem bunun yaklaşık yedide biri kadar
  • Benim gerçekten yazdığım kod ise yalnızca yaklaşık 1.000 satır
  • Bu kadar çok bağımlılık kodunu izlemek ve denetlemek pratikte imkânsız

Çözüm üzerine düşünceler

  • Şu an için ortada net bir çözüm yok
  • Bazıları Go’daki gibi standart kütüphaneyi genişletelim diyor, ancak bu da bakım yükü gibi yeni sorunlar doğuruyor
  • Rust yüksek performans, güvenlik ve modülerlik hedefliyor; gömülü sistemler ve C++ ile rekabet etmeyi amaçladığı için standart kütüphanenin genişletilmesi dikkatle ele alınmalı
  • Örneğin Tokio gibi gelişmiş bir runtime bile Github ve Discord üzerinde çok aktif biçimde sürdürülüyor
  • Gerçekçi olmak gerekirse, asenkron runtime veya web sunucusu gibi temel altyapıları doğrudan kendin yazmak bireysel geliştiriciler için fazla ağır
  • Büyük bir hizmet olan Cloudflare bile tokio ve crates.io bağımlılıklarını olduğu gibi kullanıyor; bunları ne kadar sık denetlediği ise belirsiz
  • Clickhouse da ikili dosya boyutu ve crate sayısıyla ilgili sorunlardan söz ediyor
  • Cargo ile nihai ikili dosyaya dahil olan kod satırlarını tam olarak belirlemek zor ve platforma göre gereksiz kodların da dahil olması gibi sınırlamalar var
  • Sonuçta, yanıtı tüm topluluğun birlikte aramak zorunda olduğu bir durumla karşı karşıyayız

3 yorum

 
codemasterkimc 2025-05-11

Trivy ile tarayınca js NPM ya da Java Maven’e göre high veya critical seviyeleri çok daha az çıkıyor ve daha güvenli görünüyor; peki bu yazı Rust üzerinden tam olarak neyi savunmaya çalışıyor?

 
GN⁺ 2025-05-10
Hacker News görüşleri
  • Bence bağımlılıkların "kolayca" eklenebildiği ve boyut ya da maliyet açısından ceza olmayan sistemler eninde sonunda bağımlılık sorunlarına yol açıyor. Son 40 yıldaki yazılım dağıtım biçimlerine bakınca, 80'lerde kütüphaneler parayla satın alınır, kapasite kısıtlı ortamlara göre yalnızca gereken kısımlar seçilip eklenirdi. Bugün ise kütüphanelerin üstüne durmadan başka kütüphaneler yığılıyor. Tek satır import foolib ile kullanılabiliyor ve içinde ne olduğuna kimse aldırmıyor. Her katmanda işlevlerin belki %5'i gerekiyor ama ağaç derinleştikçe işe yaramayan kod birikiyor. Sonunda basit bir ikili dosya 500MiB oluyor ve sırf sayı biçimlendirmek için bir bağımlılık çekilmiş oluyor. Go ya da Rust, her şeyi tek dosyada toplamayı teşvik ettiği için, yalnızca bir kısmını kullanmak isteseniz bile zor bir durum ortaya çıkıyor. Uzun vadede gerçek çözüm, aşırı ince taneli sembol/bağımlılık takibi olabilir; her fonksiyon/tip yalnızca ihtiyaç duyduğu öğeleri açıkça belirtir, tam gereken kod alınır ve kalanı atılır. Bu fikir kişisel olarak bana çok cazip gelmiyor ama mevcut sistemde bağımlılık ağacından bütün evreni içeri çekme sorununu çözmenin başka bir yolunu da göremiyorum
    • Üniversite öğrencisi olduğum için çok bilmiyor olabilirim ama Rust derleyicisi zaten kullanılmayan kodu, değişkenleri ve fonksiyonları tespit ediyor. IDE'lerin çoğu da bunu pek çok dilde yapabiliyor. O halde bunları kaldırmak yetmez mi? Kullanılmayan kod derlenmez
    • Ben de Rust'ta görece ağır bir bağımlılık ağacına sahip bir kütüphane (Xilem) üzerinde çalışırken feature flag ile kırpmayı denedim; ama bağımlılıkların neredeyse tamamı gereken işlevlere göre korunması gereken türdendi (vulkan, PNG decoding, unicode shaping vb.). Gereksiz bağımlılıklar çoğunlukla çok küçük şeylerdi ve yalnızca serde_json küçük değişikliklerle çıkarılabildi. Daha büyük bağımlılıkları (winit/wgpu vb.) kaldırmak içinse yapısal değişiklikler gerekiyor
    • Go ya da C# (.NET) iyi karşı örnekler. Rust ya da JS (Node) kadar etkili paket yönetimi ve ekosistemleri var ama göreli olarak dependency hell yaşamıyorlar. Bunun sebebi standart kütüphanelerinin olağanüstü iyi olması. Standart kütüphanenin bu kadar kapsamlı olması da ancak büyük şirketlerin (Google, Microsoft) yatırım yapabildiği bir alan
    • O zaman mevcut derleyiciler neden kullanılmayan kodu kaldırmıyor?
    • Eskiden her fonksiyon için ayrı .o dosyaları üretilir, bunlar .a arşivlerinde toplanır ve bağlayıcı yalnızca gereken fonksiyonları alırdı. Ad alanı da foolib_do_thing() gibi yapılırdı. Şimdi ise god object deseni gibi bütün fonksiyonlar üst düzey bir nesnede duruyor; foolib içe aktarılınca her şey geliyor. Bu durumda bağlayıcının hangi fonksiyonların gerçekten gerekli olduğunu anlaması zorlaşıyor. Buna karşılık Go'nun ölü kod temizleme yeteneği çok iyi; kullanılmayan şeyler derleme çıktısından kesiliyor
    • Modern derleyici ve bağlayıcılar zaten sembol ayıklama ve ölü kod temizleme yapıyor; Rust da min-sized-rust gibi projelerle bunu destekliyor
    • Eskiden bütün kütüphaneler projeye dahil edilir ve derleme dosyalarına doğrudan entegre edilirdi. Çok emek ister ve can sıkıcıdır ama deps dosyasına tek satır eklemekten çok daha derin bir etkileşim sağlar
    • Go aslında tek dosya konusunda takıntılı değil; mantıksal olarak dosyaları bölmeyi de kolayca destekliyor. Bu yönünü gerçekten seviyorum
    • Dotnet, Trimming ve Ahead Of Time Compilation ile bu fikri zaten hayata geçiriyor. Diğer dillerin Dotnet'ten öğreneceği şeyler var
    • LTO (Link Time Optimization) ile ikili dosya boyutu açısından bu sorun tamamen çözülüyor. Kullanılmayan kısımlar optimizasyonla atılıyor. Derleme süresi ise hâlâ maliyetli
    • Bence sorun aslında kütüphanelerin kendisi değil; bağımlılık eklendikten sonra içlerinde neyin ne kadar kullanıldığına dair görünürlüğün az olması. Her paket için performans/derleme fazlalık kod oranı gibi geri bildirimleri kolayca veren bir ortama ihtiyaç var
    • Unison adlı dil bu fikre kısmen benzeyen bir yaklaşım benimsiyor. Her fonksiyon AST yapısına göre tanımlanıyor, hash tabanlı küresel kayıt sisteminden çağrılıp yeniden kullanılıyor
    • npm'deki isEven, isOdd, leftpad gibi çok sayıda küçük kütüphane parçasının dağınık biçimde bakımının yapılmasındansa, birleşik bir ekibin yönettiği büyük genel amaçlı kütüphaneler geleceğe dönük güvence ve süreklilik açısından çok daha iyi
    • ultra-fine-grained sembol/bağımlılık takibi yerine, aşırı ince modüler yapı ve mevcut tree-shaking sistemlerinden yararlanmak da bir fikir
    • Go'nun gerçek bağımlılık yönetim biçimi aslında asıl yazıda anlatılan ideale daha yakın. Modüller paket koleksiyonları ve vendor edildiğinde fiilen kullanılan paketler ile semboller dahil ediliyor (tam olarak sembol düzeyinde mi çalışıyor, emin değilim)
    • JS modül sistemi zaten tam da böyle aşırı ince taneli sembol yönetimi ve tree shaking desteği sağlıyor
    • Başta önerilen aşırı ince bağımlılık fikri, Rust'taki --gc-sections gibi section splitting ile zaten çözülmüş durumda
    • Rust, crate feature'ları üzerinden API bölerek ince taneli import konusunda çok iyi bir dil. Go'dan farklı
    • Mimariye bağlı olarak, örneğin yerel odaklı bir thick client ise ilk kurulum 800MB olsa bile gerçek kullanımda ağ üzerinden çok kısıtlı iletişim yapıyorsa bu sorun olmayabilir. UI tarafında işbirliği için tekrar tekrar gelen büyük bağımlılıklar da tolere edilebilir
    • Kod yeniden kullanımının en iyi yollarından biri tam da bu bağımlılık kullanım biçimi. Gerçekten ihtiyaç duyulan yerde optimize etmek gerekir
    • 80'lerde yeniden kullanılabilir yazılım bileşeni kavramı Objective-C gibi dillerle zaten pratiğe geçmişti. Rust'ın büyük başarılarından biri, sistem programlama dillerinde de bu tür yazılım bileşenleşmesini yaygınlaştırmış olması
    • tree shaking ile boyut/kod şişmesi sorunu bir ölçüde çözülebilir (sunucuda zaten pek önemsenmez). Daha ciddi sorun bağımlılık tedarik zinciri riski ve güvenlik. Şirket ne kadar büyükse açık kaynak kullanımı için onay süreci de o kadar yaygın olur. Tane boyutunu artırmak, eğer 1000 özellik 1000 ayrı NPM yazarından geliyorsa, güvenlik açısından anlamlı bir çözüm değil
    • Paket soyutlamasının her katmanında kullanım oranı yalnızca %50 olsa bile, her katmanda toplam boyut gerçek ihtiyacın iki katına çıkıyor. 3 katmanda kodun %88'i işe yaramaz hale geliyor. Örnek: Windows 11 hesap makinesine gereksiz kütüphaneler (hesap kurtarma aracı gibi) da ekleniyor. Özellik eklemeyi kolaylaştırmanın karmaşıklığı artırmasına iyi bir örnek
    • Bağımlılık birikiminin sorun olduğu konusunda katılıyorum. Şu anda yapılabilecek en iyi savunma, sistem bağımlılıklarını aşırı sıkı yönetmek. 10 satırlık bir fonksiyon için dış kütüphane çekmek yerine bazen kodu doğrudan kopyalıyorum. Sağlıklı kütüphane ekosistemleri istisna gibi. Junior mühendisler bağımlılıkları düşünmeden eklediğinde genelde hemen müdahale ediyorum
    • Rust hakkında en temel şeyleri bile bilmeden bu kadar kesin konuşulmasını uzun zamandır görmemiştim
    • Ölü kod temizleme sayesinde Rust gibi derlenen dillerde büyük bağımlılık ağaçları ikili dosya şişmesine yol açmıyor
  • npm ekosisteminde hissettiğim sorun, pek çok geliştiricinin tasarım üzerine düşünmeden bağımlılık eklemesi. Örneğin glob kütüphanesi basit bir globbing fonksiyonu olmalı ama yazarı komut satırı aracını da içine kattığı için büyük bir ayrıştırıcıyı bağımlılığa eklemiş. Bu da sık sık dependency out-of-date uyarılarına yol açıyor. Ayrıca glob kütüphanesinin sorumluluk alanı da tartışmalı. Yalnızca string desen eşleme yapması daha esnek bir tasarım olurdu (test ve dosya sistemi soyutlaması daha kolay olurdu). Her şeyi yapan bir kütüphane isteyen kullanıcı çok ama bunun yan etkileri de büyüyor. Rust'ın da çok farklı olmayacağını düşünüyorum
    • Tasarım sezgisi önemli ve iyi diller bu geliştirici tercihini ya destekler ya da engellemez. Rust, Zig, C buna örnek. Sorun istatistiksel olarak daha az ortaya çıkıyor. Geliştirici "kalabalığı" büyüyünce herkesin özgürce crate yığdığı bir "pazar yeri (bazaar) modeli" oluşuyor. Sonuçta Rust'ın da resmî standart kütüphaneye (stdlib::data_structures::automata::weighted_finite_state_transducer gibi) ve düzenli ad alanlarına sahip, "batteries included" bir yapıya kavuşmasını isterim. Dilin kendisinde sürümleme ve geriye dönük uyumluluk var, bu yüzden ileride daha da iyi olabilir
    • POSIX glob fonksiyonu aslında dosya sistemini geziyor. String eşleme için fnmatch var. İdeal olan, fnmatch'i ayrı modül yapmak ve globun buna bağımlı olması. globu sıfırdan yazmaya kalkınca iş zorlaşıyor; dizin yapısı, brace expansion gibi karmaşık gereksinimler yüzünden iyi tasarlanmış fonksiyon kombinasyonları gerekiyor
    • Rust'ta borrow checker, tasarım sezgisi zayıf geliştiricilere karşı bir tür kalkan işlevi gördü. Bu etkinin ne kadar süreceği belirsiz
    • Rust'ın büyük avantajlarından biri, geliştiricilerinin genel olarak yetkin olması ve crate kalitesinin de yüksek seyretmesi
    • Bun'da da glob özelliği yerleşik geliyor
  • Bunu gereksiz yere Rust'a özgüymüş gibi göstermeye gerek yok; bağımlılık sorunu ve tedarik zinciri saldırıları zaten çoktan gerçek oldu. Yeni bir dil tasarlansaydı, bütün kütüphane ağacını güvenli biçimde yalıtacak bir capability system gömülü olmalıydı. Örneğin bir görsel yükleme kütüphanesi tasarlarken, dosya değil yalnızca stream kabul edecek şekilde yapabilir ya da "dosya açma yetkisi yok" diye açıkça tanımlayıp tehlikeli fonksiyonların kullanımını derleme zamanında engelleyebilirdiniz. Mevcut ekosistemlerde bunu yapmak kolay değil ama düzgün uygulanırsa saldırı yüzeyini ciddi biçimde azaltabilir. Bağımlılıkları azaltma kültürüyle de bu kökten çözülemiyor; Go gibi diller de tedarik zinciri saldırılarından muaf değil
    • Sans-IO (bağımlılığın doğrudan IO yapmadığı tasarım) kültürünü daha aktif biçimde yaymak gerekiyor. Yeni bir kütüphane duyurulduğunda doğrudan IO yapmasının eleştirilmesi gibi bir kültür de yararlı olur. Elbette yalnızca topluluk incelemesi yetmez ama Sans-IO ilkesi yaygınlaşırsa iyi olur
    • Örnek olarak WUFFS adlı özel amaçlı bir dil var. Fiilen Hello world bile yazdıramazsınız, string tipi bile yok. Ama güvenilmeyen dosya biçimlerini ayrıştırma konusunda çok özel amaçlı. Bu tür özel amaçlı dillere daha çok ihtiyaç var. Hızlılar ve risk taşımadıkları için gereksiz denetimleri de azaltabiliyorlar
    • Java ve .NET Framework, onlarca yıl önce partial trust/capabilities özelliklerine sahipti ama yaygın kullanılmadıkları için kaldırıldılar
    • Rust'ta da buna hafifçe benzeyen bir eğilim var. #![deny(unsafe_code)] ile unsafe kod kullanımı derleme hatasına dönüştürülebiliyor ve bu durum kullanıcıya açıkça gösteriliyor. Tam bir zorunlu denetim değil gerçi; özellikle izin verirseniz unsafe kod yine yazılabiliyor. Standart kütüphane işlevlerini feature flag gibi geçişli biçimde kontrol eden bir capability system hayal edilebilir
    • Bu tür bir şeyi bizzat yapmak isterdim ve bir gün gerçekleşmesini umuyorum. Rust'ta linter tabanlı capability takibi kısmen mümkün. Derleyicinin unsoundness sorunları ise çözülmeli
    • Mevcut dillere veya ekosistemlere tamamen statik zorlamalar getirmek zor ama yalnızca çalışma zamanı doğrulaması bile çoğu faydayı sağlayabilir. Kütüphane kodunu kaynaktan derliyorsanız, her sistem çağrısının etrafına yetki denetimi yapan sarmalayıcılar koyabilirsiniz. İhlal olursa panic üretir ve her kütüphane için capability profilleri yazıp dağıtmanız gerekir. TypeScript'te buna benzer şeylerin mümkün olduğu zaten gösterildi
    • Haskell, IO monad ile bu yaklaşımı bir ölçüde gerçekleştiriyor. Doğrudan IO yapamayan fonksiyonlar bunu tip imzalarıyla belli ediyor
    • Bana göre böyle bir yapı için OS ile iletişim biçimini kökten değiştirmek gerekebilir. Çünkü stream okumak bile gerçekte dosya okuma sistem çağrıları kullanabiliyor; tuzak burada
    • Capslock adlı proje, Go'da buna yakın bir şey yapıyor
    • Kütüphanelerin sistem API'lerini import etmesini daha giriş programından engellerseniz, capability'leri yalnızca dependency injection ile aktarabilirsiniz. Bugünün dillerinde de tasarlanabilir ama pratikte sorun mevcut kütüphanelerle uyumluluğun bozulması
    • Buna benzer bir şeyin daha önce uygulanıp uygulanmadığını merak ediyorum. Mevcut dillerde uygulaması çok zor görünüyor
    • Tek bir dille olmayabilir; çok dilli bir ekosistem gerekebilir
    • TypeScript ekosisteminde örneğin dosya işlemleri sınıfı olmayan bir ortamdaysanız derleme başarısız olur ve kısıtlama doğal olarak uygulanmış olur
  • Bu, modern yazılım geliştirmenin genel bir sorunu. Giriş bariyeri düştü, mevcut kodun yeniden kullanımı arttı. Bağımlılıklar sonuçta güvenilmeyen koddur. Teknik bir çözüm yoksa birilerinin sürekli kod incelemesi yapması, bakım üstlenmesi ve toplumsal/hukuki güven sistemlerini ayakta tutması gerekir. Bunu Rust stdlib içine çekerseniz, merkez ekip o kodun tamamından sorumlu olur; bu da ciddi bir yönetim yükü doğurur
    • Diller arasında yüzeyde görünen ciddiyet farklı. Standart kütüphanesi güçlü olan diller, dış bağımlılıkları minimumda tutup çok şey yapabildikleri için avantajlı. JS/Node gibi temel özellikleri az olan dillerde ise dış bağımlılık neredeyse varsayılan hale geliyor. "Hafiflik" her zaman iyi değil
    • Bana göre Rust'ın daha fazla standart kütüphane entegrasyonuna ihtiyacı var. Go'nun standart kütüphanesi mükemmele yakınken, Rust'ta temel işler bile (web, tls, x509, base64 vb.) kütüphane seçimi ve yönetimi açısından sancılı
    • Gilad Bracha, üçüncü taraf kütüphaneleri sandbox içine alma konusunda ilginç bir yaklaşım önermişti: import'u kaldırıp her şeyi dependency injection ile yapmak. IO alt sistemi gibi şeyleri enjekte etmezseniz, 3. taraf kodun oraya erişimi asla olmaz. Yalnızca okuma istiyorsanız, yalnızca okuma arayüzünü sarmalayıp verirsiniz. Ancak sistem programlama tarafında bunun sınırları var (unsafe kod vb. yüzünden)
    • QubesOS benzeri biçimde bütün kütüphaneleri izole ortamlarda çalıştırmak, kendi kodunuzu dom0'da, her kütüphaneyi ayrı bir şablon VM'de tutmak ve iletişim için ağ ad alanları kullanmak da önerildi. Hassas sektörlerde pratik olabilir
    • Gördüğüm kadarıyla artık daha zor işler yapmıyoruz; aynı işi daha karmaşık biçimde yapıyoruz. Hedefin kendisi zorlaşmış değil
    • Aslında dilden dile durum farklı. C/C++ tarafında bağımlılık eklemek daha zor ve çapraz platform desteği de daha zahmetli olduğu için aynı sorunlar bu ölçüde ortaya çıkmıyor
    • Gereksiz kod şişmesi tam bir kompleks haline geldi. Neredeyse tüm projeler gereksiz karmaşıklık ve aşırı tasarımla dolu. Bu sektörün genel sorunu
  • blessed.rs, standart kütüphaneye girmesi zor ama yararlı olan kütüphaneleri öneren bir liste sunuyor. Bu sistem sayesinde paketlerin çoğunun belirli amaçlarla sınırlı kalıp yönetilebilir olmasını seviyorum
    • cargo-vet de önerilmeye değer. Güvenilir paketleri izleme ve tanımlama imkânı sağlıyor; örneğin içeri almadan önce uzman denetimi gerektiren paketler ya da tokio bakım ekibinin yönettiği paketlere yarı-YOLO güven verilmesi gibi politikalar tanımlanabiliyor. blessed.rs'den daha formel ve ekip içinde resmî yarı-standart bir liste paylaşmak için iyi bir araç
    • Keşke Python için de böyle bir sistem olsa
    • İnceledim, gerçekten çok iyi bir öneri projesiymiş
  • leftpad olayından sonra paket yöneticilerine karşı olumsuz bir algı kaldı. tokio gibi bazı şeyler fiilen dil seviyesinde özellik sayılır; eğer OP, Go'nun tamamını ya da Node'un V8'ini bile tek tek denetlemek gerektiğini söylüyorsa bu gerçekçi değil
    • Gerçekte tokio da biri tarafından sürekli denetleniyor. Bunu çok kişi yapmıyor olabilir ama yine de birileri yapıyor
    • İki bağımlılığın farklı sürümler kullanması durumunda her iki sürümü de dahil etme davranışı, cargonun oldukça özgün bir desteği
  • cargo paketlerinde feature flag gerçekten çok iyi bir özellik. Gereksiz bağımlılıkları bu bayrakların arkasına taşıyan PR'lar sık sık gönderiyorum. cargo tree ile bağımlılık ağacını görmek de çok kolay. İkili dosyaya gerçekten giren kod satırlarını görmek ise çok anlamlı değil; çünkü fonksiyonlar satır içi açıldığında çoğu zaten main içine karışıyor
    • npm'de feature flag olmaması üzücü. Bunu destekleyen bir paket yöneticisi var mı merak ediyorum. Dahili kütüphanelerde belirli framework bağımlı kodları izole ederek genişletmek isterdim
  • Ben de benzer düşünüyorum. Cargo ile bağımlılık eklemek fazla kolay; tek başıma dikkat etsem bile birkaç tane ekleyince onlarca geçişli bağımlılık geliyor. Ama bunu hiç kullanmayalım demek de gerçekçi değil. C++'ta bu daha az hissediliyor. Rust'ta paketler küçük küçük bölündüğü için internetten rastgele kod çekiyormuşsunuz gibi hissettiriyor. Rust'ın kendisini seviyorum ama bu yapıdan hoşlanmıyorum
    • Rust subreddit'inde bağlantısı verilen yazıda, C++'ta bağımlılıkların daha az görünmesinin sebebinin çoğunun dinamik kütüphane olarak sunulması olduğu söyleniyordu. Hatta OS paket yöneticisinin kararlılık/güvenlik yönetimine bel bağlamak da bir avantaj olabilir. Rust'ta bir tür genişletilmiş standart kütüphane fikri iyi olurdu
    • C++ bağımlılıkları ve derleme sistemi o kadar dağınık ki, Rust tarzı daha az kararlı bağımlılık yönetiminin daha iyi olduğunu düşünüyorum. Gerçek C++ geçişli bağımlılıkları çoğu zaman önceden derlenmiş halde geldiği için daha da az görünür
    • Rust'ta küçük paketlere bölünme bir "felsefe" olmaktan çok derleme hızı yüzünden var. Ölçek büyüdükçe proje crate'lere ayrılıyor. Soyutlama için değil, derleme performansı yüzünden insanlar buna zorlanıyor
    • "O zaman doğrudan kullanma" mantığına otomatik olarak katılmak zorunda değiliz. Biraz daha düşünmek gerek
    • C++ ve CMake o kadar zor ki, bu yüzden pek çok yazılım fiilen hiç kullanılmadan kalabiliyor
  • Çekirdek kütüphaneler için açık kaynak kütüphaneler kullanıyorum, küçük işlevler içinse açık kaynaktan bakıp kodu doğrudan kendi kod tabanıma kopyalıyorum. Kod biraz gereksiz büyüyor ama dış kodu inceleme yükünü ve tedarik zinciri maruziyetini azaltıyor. Büyük kütüphaneler hâlâ sorun ama her şeyi de sıfırdan yazamazsınız. Bu Rust'a özgü değil, genel bir mesele
  • Geçmişte (başka dillerde) kritik sistemlerde modül/paket minimizasyon politikası uygular, kullandığımız tüm paketleri şirket içi depoya taşıyıp her dalı ve her güncellemeyi denetlerdik. Frontend gibi alanlarda bu kadar sıkı yönetim pratikte imkânsız. Son dönemde gürültülü açık kaynak yapay zeka araçları ve modellerinde de bağımlılık yönetimi açısından benzer kaygılar var. Rust'la kişisel projeler yaparken bile UI/async kütüphanelerindeki bağımlılık patlaması beni en çok tedirgin eden şey. Bunlardan biri bile zafiyetli hale gelse içeri sızmak mümkün; bunun sadece zaman meselesi olduğunu düşünüyorum
    • CI/CD sistemlerini yalnızca resmî iç depolarla konuşturmak en gerçekçi çözüm. Geliştirici yerelde istediğini kurabilir ama izinsiz commit'ler derleme sunucusunda engellenir
    • Güvenlik risklerini azaltmaya yönelik RFC'ler var ama muhtemelen kültürel nedenlerle büyük çaplı değişim pek olmuyor
    • Rust'ın güzel yanlarından biri, async'i de istediğiniz tarzda kendiniz uygulayabilmeniz. Belirli bir uygulamaya zorunlu bağlılık yok
 
iolothebard 2025-05-11

Bu sadece Rust’a özgü bir sorun değil.
Ortak paket depoları ve geçişli bağımlılıkları destekleyen paket yöneticilerine sahip tüm dillerin ortak avantajı ve aynı zamanda potansiyel sorunu.
Sonuçta bunu alıp kullananların dikkatli kullanması gerekiyor ama…
Node&npm’in leftpad vakasına rağmen değişen hiçbir şey yok.