مرور

این یک چیدمان ابتدایی برای پروژه‌های برنامه 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 قرار بگیرند، اما این به معنی نیست که استفاده از این الگو یک ایده خوب است.