Bir Go projesini planlamanın mantıklı bir yolu nedir [kapalı]


113

Daha karmaşık hale gelen bir go projem var ve dosya sistemini ağrıyı azaltacak şekilde düzenlemek istiyorum.

Neyin mantıklı olduğuna dair bazı iyi örnekler var mı?

Yanıtlar:


132

Mayıs 2013 güncellemesi: resmi belgeler " Kod organizasyonu " bölümündedir

Go kodu bir çalışma alanında tutulmalıdır .
Çalışma alanı, kökünde üç dizin bulunan bir dizin hiyerarşisidir:

  • src paketler halinde düzenlenmiş Go kaynak dosyalarını içerir (her dizin için bir paket),
  • pkg paket nesnelerini içerir ve
  • bin çalıştırılabilir komutlar içerir.

go toolKaynak paketleri oluşturur ve elde edilen ikilileri yükler pkgve bindizinleri.

Alt srcdizin tipik olarak, bir veya daha fazla kaynak paketin gelişimini izleyen birden çok sürüm kontrol havuzunu (örneğin Git veya Mercurial için) içerir.

bin/
    streak                         # command executable
    todo                           # command executable
pkg/
    linux_amd64/
        code.google.com/p/goauth2/
            oauth.a                # package object
        github.com/nf/todo/
            task.a                 # package object
src/
    code.google.com/p/goauth2/
        .hg/                       # mercurial repository metadata
        oauth/
            oauth.go               # package source
            oauth_test.go          # test source

Temmuz 2014 Güncellemesi: Ben Johnson'dan " Go'da Uygulamaları Yapılandırma " konusuna bakın

Bu makale aşağıdaki gibi ipuçları içerir:

İkili programınızı uygulamanızdan ayırın

main.godosyayı ve uygulama mantığımı aynı pakette birleştirmenin iki sonucu vardır:

  • Uygulamamı kitaplık olarak kullanılamaz hale getiriyor.
  • Yalnızca bir uygulama ikili programım olabilir.

Bunu düzeltmenin bulduğum en iyi yolu cmd, projemde, alt dizinlerinin her birinin bir uygulama ikili dosyası olduğu bir “ ” dizini kullanmaktır .

camlistore/
  cmd/
    camget/
      main.go
    cammount/
      main.go
    camput/
      main.go
    camtool/
      main.go

Kütüphane odaklı geliştirme

main.goDosyayı kökünüzün dışına taşımak, uygulamanızı bir kitaplık perspektifinden oluşturmanıza olanak tanır. Uygulamanızın ikili dosyası, basitçe uygulamanızın kitaplığının bir istemcisidir.

Bazen kullanıcıların birden çok şekilde etkileşimde bulunmasını isteyebilirsiniz, böylece birden çok ikili dosya oluşturursunuz.
Örneğin, adderkullanıcıların birbirine sayı eklemesine izin veren bir “ ” paketiniz varsa, bir komut satırı sürümü ve bir web sürümü yayınlamak isteyebilirsiniz.
Projenizi şu şekilde düzenleyerek bunu kolayca yapabilirsiniz:

adder/
  adder.go
  cmd/
    adder/
      main.go
    adder-server/
      main.go

Kullanıcılar, "toplayıcı" uygulama ikili dosyalarınızı bir üç nokta kullanarak "go get" ile yükleyebilir:

$ go get github.com/benbjohnson/adder/...

Ve işte, kullanıcınız “ adder” ve “ adder-server” yükledi!

Alt paketlerle çıldırmayın

Genellikle projemin türlerinin tümü birbiriyle çok ilişkili olduğundan, kullanılabilirlik ve API açısından daha iyi uyuyor.
Bu türler, API'yi küçük ve net tutan, aralarında dışa aktarılmamış çağrı yapma avantajından da yararlanabilir.

  1. Her dosyada ilgili türleri ve kodu birlikte gruplayın. Türleriniz ve işlevleriniz iyi organize edilmişse, dosyaların genellikle 200 ile 500 SLOC arasında olduğunu görüyorum. Kulağa çok benziyor olabilir ama gezinmeyi kolay buluyorum. 1000 SLOC genellikle tek bir dosya için üst sınırımdır.
  2. En önemli türü dosyanın en üstünde düzenleyin ve dosyanın altına doğru önemi azalan türler ekleyin.
  3. Başvurunuz 10.000 SLOC'nin üzerine çıkmaya başladığında, daha küçük projelere bölünüp ayrılamayacağını ciddi bir şekilde değerlendirmelisiniz.

Not: Bu son uygulama her zaman iyi değildir:

Üzgünüm, bu uygulamaya katılamıyorum.
Türleri dosyalara ayırmak, kod yönetimine, okunabilirliğe, bakıma ve test edilebilirliğe yardımcı olur.
Tek sorumluluğu ve açık / kapalı prensibinin takip edilmesini de sağlayabilir…
Döngüsel bağımlılığa izin vermemenin kuralı, paketlerin net bir yapısına sahip olmamızı sağlamaktır.


(Alternatif Şubat 2013, srcyalnızca ilgili )
" GitHub Kod Düzeni " nde gösterilen klasik düzeni bulabilirsiniz :

Uygulama ve her iki kitaplık Github'da, her biri kendi havuzunda yaşıyor.
$GOPATHprojenin köküdür - Github depolarınızın her biri aşağıdaki birkaç klasöre kontrol edilecektir $GOPATH.

Kod düzeniniz şöyle görünecektir:

$GOPATH/
    src/
        github.com/
            jmcvetta/
                useless/
                    .git/
                    useless.go
                    useless_test.go
                    README.md
                uselessd/
                    .git/
                    uselessd.go
                    uselessd_test.go
                    README.md

Altındaki her klasör src/github.com/jmcvetta/ , ayrı bir git kontrolünün köküdür.

Yine de bu reddit sayfasında bazı eleştiriler vardı :

Repo'yu sahip olduğunuz şekilde yapılandırmamanızı şiddetle tavsiye ederim, " go get" bozulur ki bu Go ile ilgili en yararlı şeylerden biridir.
Kodunuzu Go'yu bilenler için yazmak çok daha iyidir, çünkü büyük olasılıkla onu derleyenler onlardır.
Ve bilmeyen insanlar için, en azından dil hakkında bir fikir edinecekler.

Ana paketi deponun köküne koyun.
Varlıkları bir alt dizinde bulundurun (işleri düzenli tutmak için).
Kodun etini bir alt pakette saklayın (herhangi birinin onu ikili programınızın dışında yeniden kullanmak istemesi durumunda).
Deponun köküne bir kurulum komut dosyası ekleyin, böylece bulması kolaydır.

Hala indirmek, oluşturmak, kurmak ve kurmak için yalnızca iki adımlı bir işlemdir:

  • " go get <your repo path>": varlıklar için bir alt dizinle birlikte go kodunu indirir ve yükler
  • $GOPATH/<your repo path>/setup.sh: varlıkları doğru yere dağıtır ve hizmeti kurar

15
setup.shBununla ilgili (büyük) bir problem , Go'nun platformlar arası olması, POSIX kabuk komut dosyalarının olmamasıdır.
kostix

Jmcvetta yapısı olacak değil bir getireceğim ... / uselessd hem kuracaktır getireceğim, yararsız uselessd ithalatı beri getireyim bölünürler. Ama işe yaramazsa, işe yaramazlar için özel olarak yapılmış bir kitaplıksa, onu bir alt klasör veya kardeş olarak tek bir git deposunda tutmanın daha mantıklı olduğunu kabul ediyorum.
mna

@PuerkitoBio Katılıyorum. Sürüm kontrolü ve bileşen tabanlı yönetim konusundaki eğitimim ( stackoverflow.com/a/933735/6309 ) beni repo başına bir bileşene daha çok yönlendiriyor, dolayısıyla bu cevabın ikinci kısmı.
VonC

7

Sanırım 'proje' ile bir Go paketini değil, geliştirdiğiniz bir yazılımı kastediyorsunuz. Aksi takdirde buradan ve buradan yardım alabilirsiniz . Ancak, Go için paket yazmaktan çok farklı değil: Paketleri kullanın, her paket için bir klasör oluşturun ve bu paketleri uygulamanızda birleştirin.

Kendinize bir fikir oluşturmak için, github'da trend olan Go depolarına bakabilirsiniz: https://github.com/trending/go . Kayda değer örnekler Cayley ve zeus .

En popüler şema muhtemelen bir ana Go dosyasına ve kendi dizinlerinde birçok modül ve alt modüle sahip olmaktır. Çok sayıda meta dosyanız (belge, lisans, şablonlar, ...) varsa, kaynak kodunu bir alt dizine koymak isteyebilirsiniz. Şimdiye kadar yaptığım buydu.


@aussiegeek, ben bir Go uzmanı değilim, ancak kendi kodumda nemo'nun önerdiği şeyi başarıyla uyguladım - fikir şu ki , proje dizininizin altında modüllere sahip olabilirsiniz, onlara tam öneklerini kullanarak başvurmanız yeterlidir - göreli için $GOPATH/srcya da kullanan go getmasaları isimleri.
kostix

doozerdiyi bir örnek değil, testleri bile zayıf.
İnanç Gümüş

@InancGumus Daha iyi bir örnek önermenizi tavsiye ederim.
nemo

bkz bu ve bu .
İnanç Gümüş

1

Bir yoktur önerilen yaklaşım tanımlar nasıl gidip araçlarıyla ve destek kaynak kontrol sistemleri için en iyi çalışması için kodunuzu düzeni için bu Golang yazarların


1
Yani nasıl düzene var $GOROOT, değil kod içinde src/<project>dizine.
docwhat

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.