مرور
این یک چیدمان ابتدایی برای پروژههای برنامه Go است. این یک استاندارد رسمی توسط تیم توسعه هسته Go تعریف نشده است. بلکه یک چیدمان متداول برای پروژههای اجتماعی Go
میباشد.
**اگر در حال یادگیری Go هستید یا قصد دارید یک مدرک اثبات (PoC) یا یک پروژه شخصی ساده را ایجاد کنید، این چیدن پروژه بسیار پیچیده است. به جای این که با یک چیدمان واقعاً ساده شروع کنید (فقط یک فایل
main.go و
go.mod کافیست).
**زمانی که پروژهی شما تکامل مییابد، اطمینان حاصل کنید که ساختار کد شما مناسب است، در غیر اینصورت ممکن است به یک کد اشفته که شامل بسیاری از وابستگیهای پنهان و وضعیت جهانی است برسید. زمانی که افراد بیشتری در پروژه شرکت میکنند، نیاز به یک روش ساختارمند تر است. در این صورت، مدیریت مشترک بستهها/کتابخانهها را معرفی کردن بسیار مهم است. وقتی یک پروژه منبع باز دارید و یا میدانید که دیگر پروژهها کد از مخزن پروژهی شما وارد میکنند، داشتن بستهها و کدهای خصوصی (همچنین به نامinternal
شناخته میشود) مهم است. مخزن را کلون کنید، بخشهای لازم را نگه دارید و هر چیز دیگری را حذف کنید! فقط به این دلیل که وجود دارد نیاز نیست از همه استفاده کنید. هیچکدام از این الگوها در هر پروژه استفاده نمیشود. حتی الگوی vendor
نیز یکتا نیست.
این چیدمان پروژه به طور اتفاقی طراحی شده است تا بسیار عمومی باشد و سعی نمیشود یک ساختار بسته Go خاص را نهادینه کند.
مشخصات دایرکتوری پروژه Go
در زیر مشخصات پیشنهادی دایرکتوری پروژه Go آمده است.
.
├── go.mod
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── go.mod
├── init
├── internal
├── pkg
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website
معانی هر دایرکتوری در زیر معرفی شده است.
/cmd
برنامههای اصلی پروژه، به عبارت دیگر، نقطه ورودی برنامهها. فایلهای Go در این دایرکتوری معمولاً فایلهای قابل اجرا ایجاد میکنند. در یک پروژه ساده، فایلی مانند/cmd/myapp/main.go
میتواند به عنوان نقطه ورودی عمل کند.
نام دایرکتوری برای هر برنامه باید با نام فایل اجرایی مورد نظر شما مطابقت داشته باشد (به عنوان مثال/cmd/myapp
).
کد زیادی را در دایرکتوری برنامه قرار ندهید. اگر فکر میکنید که کد میتواند وارد و استفاده شود در پروژههای دیگر، آن را در دایرکتوری/pkg
قرار دهید. اگر کد قابل استفاده مجدد نیست یا نمیخواهید دیگران از آن استفاده کنند، کد را در دایرکتوری/internal
قرار دهید. ممکن است از رفتار افراد دیگر شگفتزده شوید، بنابراین اندازهگیری نیت خود را به خوبی ابراز کنید!
معمولاً یک تابعmain
کوچک وجود دارد که کد از دایرکتوریهای/internal
و/pkg
را وارد کرده و فراخوانی میکند، و هیچ چیز دیگری.
/internal
کد برنامه و کتابخانه خصوصی. این کدی است که نمیخواهید دیگران آن را در برنامهها یا کتابخانههای خود وارد کنند. توجه کنید که الگوی چیدمان برای internal
توسط خود کامپایلر Go اجباری است. برای اطلاعات بیشتر، لطفاً به یادداشتهای انتشار برای Go 1.4 مراجعه کنید. توجه داشته باشید که این محدود به دایرکتوری internal
سطح بالا نیست. میتوانید چندین دایرکتوری internal
را در هر سطح درخت پروژه داشته باشید.
ممکن است تصمیم بگیرید برخی ساختار اضافی برای بستههای داخلی اضافه کنید تا بین کدهای داخلی به اشتراک گذاشته شده و غیر اشتراکی تفاوت قائل شوید. این امر لازم نیست (به ویژه برای پروژههای کوچکتر)، اما نمایش گرافیکی استفاده مطلوبی از برنامههای مورد استفاده را تظاهر میکند. کد واقعی برنامه شما میتواند در دایرکتوری/internal/app
قرار داده شود (به عنوان مثال/internal/app/myapp
) و کد به اشتراک گذاشته شده برای این برنامهها میتواند در دایرکتوری/internal/pkg
قرار گیرد (به عنوان مثال/internal/pkg/myprivlib
).
/pkg
کد کتابخانه که میتواند توسط برنامههای خارجی استفاده شود (به عنوان مثال/pkg/mypubliclib
). پروژههای دیگر این کتابخانهها را وارد کرده و انتظار دارند که به خوبی کار کنند، بنابراین قبل از قرار دادن محتوا در اینجا به خوبی فکر کنید :-) توجه داشته باشید که دایرکتوری internal
روش بهتری برای اطمینان از اینکه بستههای خصوصی وارد نشوند است، زیرا توسط خود Go اجباری است. دایرکتوری/pkg
همچنان روش خوبی برای ابراز صریح آن است که کد در این دایرکتوری برای دیگران ایمن است.
اگر پروژهی برنامه شما بسیار کوچک است و توده چندسطحی ارزش زیادی اضافه نمیکند، استفاده از آن مناسب نیست (مگر اینکه واقعاً میخواهید از آن استفاده کنید :-) ). هنگامی که پروژه اندازه کافی بزرگ میشود و دایرکتوری ریشه بسیار پر میشود، در نظر بگیرید استفاده کنید (به خصوص اگر بخشهای نرمافزار متعدد غیر-Go دارید).
/vendor
وابستگیهای برنامه (به صورت دستی مدیریت شده یا با استفاده از ابزار مدیریت وابستگیها مورد علاقه شما، مانند ویژگیهای Go Modules
). دستور go mod vendor
دایرکتوری /vendor
را برای شما ایجاد میکند. توجه داشته باشید که اگر از نسخه پیشفرض فعال شده Go 1.14 استفاده نمیکنید، ممکن است نیاز به اضافه کردن پرچم -mod=vendor
به دستور go build
داشته باشید.
اگر در حال ساخت یک کتابخانه هستید، لطفاً وابستگیهای برنامه خود را ثبت نکنید.
دایرکتوریهای برنامه سرویس
/api
مشخصات OpenAPI/Swagger، فایلهای طرح JSON، فایلهای تعریف پروتکل و دایرکتوریهای پروتکل API.
دایرکتوریهای برنامه وب
/web
اجزا خاص برای برنامههای وب: داراییهای وب سایت استاتیک، قالبهای سمت سرور و برنامههای تک برگ (SPA).
دایرکتوریهای عمومی برنامه
/configs
الگوهای فایل پیکربندی یا پیکربندیهای پیشفرض.
فایلهای الگوی confd
یا consul-template
را در اینجا قرار دهید.
/init
راهاندازی سیستم (systemd، upstart، sysv) و تنظیمات مدیر فرایند/دیمان (runit، supervisord).
/scripts
اسکریپتها برای ساخت، نصب، تجزیه و تحلیل و دیگر عملیات.
/build
بستهبندی و یکپارچهسازی مداوم.
تنظیمات و اسکریپتهای بسته (AMI)، کانتینر (Docker)، سیستم عامل (deb، rpm، pkg) را در دایرکتوری /build/package
قرار دهید.
تنظیمات و اسکریپتهای یکپارچهسازی مداوم (travis، circle، drone) را در دایرکتوری /build/ci
قرار دهید.
لطفاً توجه داشته باشید که برخی از ابزارهای یکپارچهسازی مداوم (مانند Travis CI) بسیار به مکان فایلهای پیکربندی خود نیاز دارند. سعی کنید فایلهای پیکربندی را در دایرکتوری /build/ci
قرار داده و از ارتباطها برای اتصال آنها به مکان مورد انتظار ابزارهای یکپارچهسازی مداوم استفاده کنید (اگر امکان پذیر است).
/deployments
تنظیمات و الگوهای مستقری برای IaaS، PaaS، سیستم و ارکستراسیون کانتینر (docker-compose، kubernetes/helm، terraform). لطفاً توجه داشته باشید که در برخی از مخازن (بخصوص برای برنامههای مستقر شده با استفاده از Kubernetes)، این دایرکتوری به نام /deploy
صدا زده میشود.
/test
برنامههای آزمون خارجی دیگر و دادههای آزمون. اجازه دارید دایرکتوری /test
را بر اساس نیازهای خود سازماندهی کنید. برای پروژههای بزرگ، سازماندهی دادهها به زیردایرکتوریها منطقی است. به عنوان مثال، میتوانید دایرکتوریهای /test/data
یا /test/testdata
را در دایرکتوری /test
ایجاد کنید تا Go از محتویات صرف نظر کند. لطفاً توجه داشته باشید که Go نیز از دایرکتوریها یا فایلهایی که با "." یا "_" شروع میشوند، صرف نظر میکند که امکانات بیشتری را برای نامگذاری دایرکتوریهای داده آزمون فراهم میکند.
دایرکتوریهای دیگر
/docs
طراحی و مستندات کاربر (غیر از مستندات godocایی که شما تولید میکنید).
/tools
ابزارهای پشتیبانی برای این پروژه. لطفاً توجه داشته باشید که این ابزارها میتوانند از دایرکتوریهای /pkg
و /internal
کد را وارد کنند.
/examples
نمونهها برای برنامهها و/یا کتابخانههای عمومی.
/third_party
ابزارهای جانبی خارجی، کد fork شده و سایر ابزارهای کاربردی شخص ثالث (مانند Swagger UI).
/githooks
هواکهای گیت.
/assets
داراییهای اضافی (تصاویر، لوگوها و غیره) که با مخزن همراه است.
/website
محل ذخیره دادههای وبسایت پروژه اگر از صفحات GitHub استفاده نمیکنید.
/src
برخی از پروژههای Go ممکن است دارای دایرکتوری src
باشند، اما این معمولاً به دلیل توسعهدهندگانی است که از دنیای Java میآیند و این الگوی رایج است. اگر ممکن است، سعی کنید از این الگوی شبیه به Java استفاده نکنید. واقعاً نمیخواهید کد یا پروژه Go خود را شبیه به Java داشته باشید :-)
لطفاً دایرکتوری /src
در سطح پروژه را با دایرکتوری /src
استفاده شده برای فضای کاری Go، که در چگونه کد Go بنویسیم
توضیح داده شده، اشتباه نگیرید. متغیر محیطی $GOPATH
به فضای کاری شما (فعلی) اشاره میکند (به طور پیشفرض، در سیستمهای غیر ویندوزی، به دایرکتوری $HOME/go
اشاره میکند). این فضای کاری شامل دایرکتوریهای اولیه / pkg
، /bin
و /src
است. پروژه واقعی شما یک زیردایرکتوری زیر دایرکتوری /src
خواهد بود، بنابراین اگر پروژه شما یک دایرکتوری /src
دارد، مسیر پروژه به این شکل خواهد بود: /some/path/to/workspace/src/your_project/src/your_code.go
. لطفاً توجه داشته باشید که از نسخه 1.11 Go به بعد، پروژههای شما میتوانند خارج از GOPATH
قرار بگیرند، اما این به معنی نیست که استفاده از این الگو یک ایده خوب است.