Bu proje Go projeleri için basit bir yerleşim düzenidir. Go geliştirici takımının belirlediği, resmi standartları değil
. Go ekosistemindeki, ortak geçmişi ve zaman içinde ortaya çıkmış şablonları içerir. Bu şablonlardan bazıları diğerlerinden daha popülerdir. Bir dizi iyileştirmenin yanı sıra yeterli büyüklükte herhangi bir gerçek dünya uygulamasına özgü birkaç destekli dizin de içerir.
Eğer Go'yu öğrenmeye çalışıyorsanız veya PoC (Proof of Concept) ya da kendinize deneme bir proje yapıyorsanız bu klasör düzeni sizin için ideal olmaya bilir. Çok basit bir şeyle başlayın (tek bir
main.go dosyası ve
go.mod fazlasıyla yeterli olucaktır).
Projeniz büyüdükçe projenin iyi yapılandırıldığından emin olmanın önemli olduğunu unutmayın, yoksa bir sürü gizli bağımlılık (dependency) ve bir sürü, her yerden erişilebilen, global
değişkenlerle dolu dağınık bir kodla karşılaşabilirsiniz. Proje üstünde fazla kişi çalıştığında projeyi çok daha fazla yapılandırmanız gerekebilir. İşte tam da bu durumda paketleri/kütüphaneleri idare edebilmek için ortaya ortak bir yol koymak gerekir. Açık kaynak bir projeniz olduğunda ya da başkalarının sizin projenizi kullandıklarını bildiğinizde projenizde özel paketlerin ve kodların (diğer adıyla, internal
klasörü) olması önemlidir. Bu projeyi klonlayın, ihtiyacınız olanları bırakın ve diğer bütün her şeyi silin. Bütün klasörlerin burada olması kullanmanız gerektiği anlamına gelmez. vendor
klasörü bile herkes tarafından kullanılan bir şey değildir.
Go 1.14 ile birlikte Go Modules
özelliği sonunda production
ortamında kullanılması için hazır oldu. Eğer karşı bir nedeniniz yoksa Go Modules
kullanın. Eğer kullanırsanız $GOPATH
ile ve projenizin nereye koyulacağıyla alakalı endişeler duymazsınız. Projenizde bulunan basit go.mod
dosyası projenizin GitHub'da barındırıldığını varsayar ama bu bir gereklilik değildir. Modül yolu her şey olabilir ama modül yolunun ilk parçasının içinde bir nokta olmalıdır (Go'nun şimdiki versiyonu artık bu konuda zorlamıyor ama eğer daha eski versiyonları kullanırsanız ve derleme işleminde hata alırsanız şaşırmayın). Daha fazla bilgi için 37554
ve 32819
hata bildirimlerine bakabilirsiniz.
"Bu proje düzeni genel bir düzendir ve belirli bir Go paketi yapısını empoze etmeye çalışmaz".
Bu proje bir topluluk eseridir. Eğer yeni bir şablon ve ya düzen ile karşılaşırsanız ya da olan şablonların, düzenlerin güncellenmesi gerektiğini düşünüyorsanız bir hata bildirimi açınız.
Eğer isimlendirmekle, biçimlendirmeyle ve stilize etmeyle ilgili yardıma ihtiyacınız varsa gofmt
ve golint
yazılımlarını çalıştırmayı deneyin. Ayrıca aşağıdaki Go kod stili rehberlerini ve önerilerini okuduğunuzdan emin olun.
- https://talks.golang.org/2014/names.slide
- https://golang.org/doc/effective_go.html#names
- https://blog.golang.org/package-names
- https://github.com/golang/go/wiki/CodeReviewComments
- Style guideline for Go packages (rakyll/JBD)
Ek bilgi için Go Project Layout
adlı yazıya bakabilirsin.
Paketlerin adlandırılması ve düzenlenmesi ile diğer kod yapısı önerileri hakkında daha fazla bilgi:
- GopherCon EU 2018: Peter Bourgon - Best Practices for Industrial Programming
- GopherCon Russia 2018: Ashley McNamara + Brian Ketelsen - Go best practices.
- GopherCon 2017: Edward Muller - Go Anti-Patterns
- GopherCon 2018: Kat Zien - How Do You Structure Your Go Apps
Paket odaklı dizayn rehberi ve Mimari katmanı ile alakalı Çince bir yazı:
Projenin ana uygulamalarını içerir.
Her uygulamanın klasör adı, eklemek istediğiniz uygulamanın adıyla eşleşmelidir. (örneğin, /cmd/myapp
)
Bu klasöre çok fazla kod koymanız iyi olmaz. Eğer kodların başka projeler tarafından kullanılabileceğini düşünüyorsanız, o kodları /pkg
klasörüne koymalısınız. Eğer kod yeniden kullanılabilecek değilse ya da diğerlerinin yeniden kullanmasını istemiyorsanız, bu kodları /internal
klasörüne koymalısınız. Niyetiniz hakkında açık olun, diğer geliştiricilerin kodunuzu ne için kullanabileceğine şaşıracaksınız!
/internal
ve /pkg
klasörlerinden kod çağıran küçük bir main
fonksiyonunuzun olması yaygındır.
Örnekler için /cmd
klasörüne bakabilirsiniz.
Özel uygulama ve kütüphane kodunu içerir. Buradaki kodlar diğer geliştiricilerin kendi projelerinde kullanmasını istemediğiniz kodlardır. Bu yerleşim düzeninin Go derleyicisinin kendisi tarafından uygulandığına dikkat edin. Ayrıntılar için Go 1.4 sürüm notları
. Üst katmandaki internal
klasörü ile sınırlı olmadığınızı unutmayın, projenizin herhangi bir katmanında birden fazla internal
klasörüne sahip olabilirsiniz.
Paylaşılan ve paylaşılmayan kodunuzu ayırmak için isteğe bağlı olarak ekstra yapılar ekleyebilirsiniz. Bu gerekli değildir (özellikle küçük projeler için) ancak amaçlanan paket kullanımını gösteren görsel ipuçlarına sahip olmak güzel bir şeydir. Asıl uygulama kodunuz /internal/app
klasöründe yer alabilir (örneğin, /internal/app/benimuygulamam
) ve bu kodlar /internal/pkg
klasöründe yer alan kodlar (örneğin, /internal/pkg/benimözelkütüphanem
) ile paylaşılabilir.
Diğerleriyle paylaşmak istediğiniz kodu içerir (örneğin, /pkg/myopenlibrary
). Diğer projeler bu kütüphaneleri çalışacağını tahmin ederek kullanırlar. Yani buraya bir şey koyarken iki kere düşünün :-) Unutmayın ki internal
klasörü başka projeler tarafından kullanılmasını istemediğiniz kodlar için daha iyi bir yerdir çünkü bu Go tarafından zorunlu olarak uygulanır. /pkg
klasörü içindeki kodun başkaları tarafından kullanılmasının güvenli olduğunu açıkça belirtmek için hala iyi bir yoldur. Travis Jeffery tarafından yazılan I'll take pkg over internal
blog yazısı pkg
ve internal
klasörleri ve onları ne zaman kullanmanın mantıklı olacağına dair genel bakış sağlar.
Ayrıca ana klasörünüz çok sayıda Go kodu olmayan dosya ve klasör içerdiğinde Go kodunu tek bir yerde gruplamanın yoludur ve bazı Go araçlarını kullanmayı daha kolay hale getirir (bu konuşmalarda bahsedildiği gibi: Best Practices for Industrial Programming
GopherCon Avrupa 2018 konferansından, GopherCon 2018: Kat Zien - How Do You Structure Your Go Apps ve GoLab 2018 - Massimiliano Pippi - Project layout patterns in Go).
Hangi popüler Go projelerinin bu düzeni kullandığını merak ediyorsanız /pkg
klasörüne bakabilirsiniz. Bu genel bir yerleşim düzenidir ama herkes tarafından kabul edilmeyebilir ve bazı Go toplulukları bu yerleşim düzenini tavsiye etmeyebilir.
Eğer projenizde ekstra bir katmana gerek yoksa ya da projeniz çok küçükse burayı kullanmamanızda bir sakınca olmaz (çok istiyorsanız kullanın). Projeniz yeterince büyük olduğunda ve ana klasörünüz karışmaya başladığında (özellikle çok fazla Go kodu olmayan dosyanız olduğunda) bunu kullanmayı düşünebilirsiniz.
Uygulama bağımlılıkları (el ile yönetilen ya da yeni bir özellik olan Go Modules
gibi favori bağımlılık yönetim aracınızla yönetilen). go mod vendor
komutu size yeni bir /vendor
klasörü yaratır. Unutmayın eğer Go 1.14 kullanmıyorsanız go build
komutuna -mod=vendor
parametresi vermeniz gerekebilir Go 1.14 bunu varsayılan olarak yapar.
Eğer bir kütüphane yazıyorsanız bağımlılıklarınızı commit
etmeyin.
Not olarak 1.13
versiyonundan itibaren Go modüller için proxy
özelliğini aktif hale getirdi (varsayılan olarak https://proxy.golang.org
adresini kullanır). Buradan
gereksinimlerinize ve kısıtlamalarınıza uyup uymadığı hakkında daha fazla bilgi edinebilirsiniz. Eğer bu size uyarsa vendor
klasörüne çokta ihtiyacınız olmayacaktır.
OpenAPI/Swagger dosyaları, JSON şema dosyaları, protokol tanımlama dosyaları.
Örnekler için /api
klasörüne bakabilirsiniz.
Spesifik web uygulaması parçaları: statik web varlıkları, sunucu taraflı şablonlar ve SPA'lar.
Konfigürasyon dosya şablonları veya varsayılan konfigürasyonlar.
confd
veya consul-template
dosyalarını buraya koyabilirsiniz.
Sistem başlangıcı (systemd, upstart, sysv) ve işlem yöneticisi (runit, supervisord) konfigürasyonları.
Çeşitli derleme, yükleme, analiz ve benzeri işlemleri gerçekleştirmek için olan komut dosyaları.
Bu dosyalar ana katmandaki Makefile dosyasını küçük ve basit tutar. (örneğin, https://github.com/hashicorp/terraform/blob/master/Makefile
).
Örnekler için /scripts
klasörüne bakabilirsiniz.
Paketleme ve Sürekli Entegrasyon.
/build/package
klasörüne bulut (AMI), konteyner (Docker), işletim sistemi (deb, rpm, pkg) paket konfigürasyonlarını ve komut dosyalarını koyabilirsiniz.
/build/ci
klasörüne de Sürekli Entegrasyon (travis, circle, drone) konfigürasyonlarını ve komut dosyalarını koyabilirsiniz. Önemli olarak bazı sürekli entegrasyon araçları (örneğin, Travis CI) konfigürasyon dosyalarının klasörleriyle alakalı seçici olabiliyor. Konfigürasyon dosyalarını /build/ci
klasörüne koymayı deneyin ve dosyaları sürekli entegrasyon araçlarının bekledikleri yere bağlayın (mümkün olduğunda).
IaaS, Paas, sistem ve konteyner orkestrasyon yayınlama konfigürasyonlarını ve şablonlarını (docker-compose, kubernetes/helm, mesos, terraform, bosh) bu klasöre koyabilirsiniz. Önemli olarak bazı projelerde (özellikle kubernetes ile yayınlanan projeler) bu klasörün adı /deploy
olabilir.
Ek harici test uygulamaları ve test verileri. /test
klasörünün içini istediğiniz gibi yapılandırmada özgür hissedin. Daha büyük projelerde test verileri için alt klasörler açmak mantıklı olabilir. Örneğin, eğer Go'nun test dosyalarını görmezden gelmesini istiyorsanız bu dosyalar için /test/data
veya /test/testdata
adlı klasörlere sahip olabilirsiniz. Not olarak Go "." veya "_" ile başlayan klasörleri ve dosyalarıda görmezden gelir, bu sayede test klasörlerinizi ve dosyalarınızı isimlendirmede daha esnek olabilirsiniz.
Örnekler için /test
klasörüne bakabilirsiniz.
Tasarım ve kullanıcı dökümanları (godoc ile oluşturulmuş dökümanlara ek olarak)
Örnekler için /docs
klasörüne bakabilirsiniz.
Bu klasöre projen için destekleyici araçları koyabilirsiniz. Unutmayın bu araçlar /pkg
ve /internal
klasörlerindeki kodları kullanabilirler.
Örnekler için /tools
klasörüne bakabilirsiniz.
Bu klasöre yaptığınız uygulamalar ya da kütüphaneler için örnekleri koyabilirsiniz.
Örnekler için /examples
klasörüne bakabilirsiniz.
Dış yardımcı araçlar, çatallanmış kod (forked code) ve diğer 3. parti yardımcı şeyler. (örneğin, Swagger UI)
Git hooks.
Bu klasöre resim, logo ve benzeri kaynakları koyabilirsiniz.
Eğer GitHub Pages kullanmıyorsanız burası projenin websitesinin dosyalarının konulması için doğru adres.
Örnekler için /website
klasörüne bakabilirsiniz.
Bazı Go projelerinde src
adlı bir klasör görebilirsiniz, ama bu çoğunlukla src
klasörü kullanmanın genel bir kalıp olduğu Java dünyasından gelen geliştiricilerde olur. Eğer yapabilirseniz bu Java kalıbını benimsememeye çalışın. Gerçekten Go kodunuzun ya da Go projenizin Java gibi gözükmesini istemezsiniz :-)
Proje seviyesindeki /src
klasörü ile How to Write Go Code
adresinde belirtilen Go'nun çalışma alanları için kullandığı /src
klasörünü karıştırmayın. $GOPATH
ortam değişkeni sizin çalışma alanınıza (şu anki) işaret eder (Windows olmayan sistemlerde varsayılan olarak $HOME/go
klasörüne işaret eder). Bu çalışma alanı içerisinde en üst katmandaki /pkg
, /bin
ve /src
klasörlerini barındırır. Asıl projeniz /src
klasörü altında bir alt dizin olur. Eğer projende /src
klasörüne sahipseniz, projenizin dosya yolu büyük ihtimal şöyle gözükecek /calismaalaniniz/src/projeniz/src/kodunuz.go
. Not olarak Go 1.11 ile $GOPATH
klasörü dışında projeler açabilirsiniz ama bunu yapabilmeniz bu yerleşim düzeninin kullanılmasının iyi bir fikir olduğu anlamına gelmez.
-
Go Report Card - Kodunuzu
gofmt
,go vet
,gocyclo
,golint
,ineffassign
,license
vemisspell
yazılımları ile tarar.github.com/golang-standards/project-layout
linkini kendi proje linkiniz ile değiştirin. -
GoDoc - Projenizin GoDoc tarafından yaratılmış online bir dökümantasyonunu çıkartır. İşaret ettiği linki kendi proje linkiniz ile değiştirin. -
Pkg.go.dev - Paket keşfi ve dökümantasyonları için yeni adres Pkg.go.dev. Rozet yaratma aracı ile projenize bir rozet yaratabilirsiniz.
-
Release - Projenizin en son yayınlanmış versiyonunu gösterir. İşaret ettiği linki kendi proje linkiniz ile değiştirin.
Örnek/yeniden kullanılabilir yapılandırmalar, komut dosyaları ve kodları içeren daha kararlı bir proje şablonu yapım aşamasındadır.