پالت فرمان

دنبال فرمانی برای اجرا بگردید…

ZarynZaryn
بسته‌ها·۵ دقیقه مطالعه

بسته‌های Zig

یک بستهٔ Zig منتشر کنید و دقیقاً همان هشی را بگیرید که zig fetch حساب می‌کند، بسته را پیش از انتشار بررسی کنید، از هر مخزن زرین به‌عنوان وابستگی استفاده کنید و خطاهای build.zig.zon را رفع کنید. هر قدم توضیح داده شده.

Zig رجیستری مرکزی ندارد. یک وابستگی فقط **نشانی وب یک آرشیو به‌اضافهٔ هش آن** است که در `build.zig.zon` پروژه‌تان نوشته می‌شود. `zig build` آرشیو را دانلود می‌کند، هشش را حساب می‌کند و اگر جور نباشد متوقف می‌شود. این طراحی امن است، ولی میزبانی آرشیو و حساب کردن هش را به عهدهٔ شما می‌گذارد. زرین هر دو را انجام می‌دهد: - **رجیستری برای Zig.** بسته را یک بار بارگذاری کنید؛ زرین نشانی‌اش و هشش را می‌دهد که دقیقاً به همان روش `zig fetch` حساب شده، تا مستقیم در `build.zig.zon` بچسبانید. - **بررسی پیش از انتشار.** زرین `build.zig.zon` شما را همان‌طور که zig می‌خواند می‌خواند و به زبان ساده می‌گوید zig چه چیزی را رد می‌کند (fingerprint جاافتاده، نامی که مجاز نیست، فایل‌هایی که بیرون از بسته مانده‌اند). - **هر مخزن یک وابستگی است.** هر commit یک مخزن زرین به شکل آرشیوی با هش ثابت دانلودشدنی است. - **آینه‌ها.** وابستگی‌ها از گیت‌هاب، Codeberg و جاهای دیگر (آرشیوها، فایل‌های `.zip` و مخزن‌های `git+https`)، و خود کامپایلر Zig، می‌توانند از راه زرین بیایند؛ `zev mirror zig` این را برای کل یک پروژه انجام می‌دهد: [آینه‌ها](/docs/fa/package-mirrors#وابستگیهای-zig) را ببینید. ## یک بستهٔ Zig چه لازم دارد پوشه‌ای با `build.zig` (چطور ساخته شود) و `build.zig.zon` (چه هست). `zig init` هر دو را می‌سازد. `build.zig.zon` این شکلی است: ```zig .{ .name = .greet, // نام بسته: حرف، رقم و _ .version = "0.1.0", // برای هر انتشار بالا ببرید .fingerprint = 0x3610a6865d7ac0a2, // ساختهٔ zig init؛ هرگز عوضش نکنید .minimum_zig_version = "0.15.1", // قدیمی‌ترین Zig که آن را می‌سازد .dependencies = .{}, // بسته‌های دیگری که استفاده می‌کند .paths = .{ "build.zig", "build.zig.zon", "src" }, // چه چیزهایی جزو بسته‌اند } ``` - **`.name`** از Zig 0.14 به بعد با نقطه شروع می‌شود (`.greet`، نه `"greet"`). - **`.fingerprint`** شناسهٔ همیشگی بستهٔ شماست. اگر بستهٔ کسی را کپی کرده‌اید تا بستهٔ خودتان را شروع کنید، بررسی زرین مقدار تازه را به شما می‌گوید. - **`.paths`** فایل‌ها و پوشه‌هایی است که جزو بسته‌اند. هر چیز دیگری در آرشیو (یادداشت، دادهٔ آزمایشی، عکس) کنار گذاشته می‌شود و هش را تغییر نمی‌دهد. ## بسته‌بندی از پوشهٔ بالای بسته (اینجا بسته در `greet/` است): ```bash tar czf greet-0.1.0.tar.gz greet ``` این از پوشه یک فایل فشرده می‌سازد. `.tar.xz`، `.tar.zst` و `.tar` ساده هم کار می‌کنند. ## بررسی (اختیاری، پیشنهادی) در [بسته‌ها](/packages) **Zig** را انتخاب کنید، سپس **بررسی بسته پیش از انتشار** و فایل را انتخاب کنید. یا از ترمینال: ```bash curl --data-binary @greet-0.1.0.tar.gz -H "Authorization: Bearer $ZARYN_TOKEN" \ https://api.zaryn.xyz/v1/packages/zig/-/check ``` هش را می‌گیرید، اینکه چند فایل در بسته است، و هر مشکلی که zig رویش متوقف می‌شود؛ مثلاً: ```text invalid fingerprint 0x1234 for the name .greet: if this is a new or forked package, use 0x3610a6865d7ac0a2 ``` چیزی ذخیره نمی‌شود. ## انتشار در [بسته‌ها](/packages) توکن بسازید (**ساخت توکن انتشار**)، سپس: ```bash curl -T greet-0.1.0.tar.gz -H "Authorization: Bearer $ZARYN_TOKEN" \ https://api.zaryn.xyz/v1/packages/zig/ ``` - `-T` فایل را بارگذاری می‌کند. - نام و نسخه از `build.zig.zon` خوانده می‌شوند، پس چیز دیگری برای نوشتن نیست. - برای انتشار به نام سازمانی که مالک یا مدیرش هستید، `?owner=<نام سازمان>` را به نشانی اضافه کنید. زرین هر چه برای استفاده لازم است برمی‌گرداند: ```json { "name": "greet", "version": "0.1.0", "hash": "greet-0.1.0-osB6XSsBAACcv0dHgf4SJ_AaruNKCheoTxH_lgjFjt-i", "url": "https://api.zaryn.xyz/v1/packages/zig/greet/greet-0.1.0.tar.gz", "zon_entry": ".greet = .{ .url = \"…\", .hash = \"…\" }," } ``` نسخهٔ منتشرشده جایگزین نمی‌شود: برای اصلاح، `.version` را بالا ببرید و دوباره منتشر کنید. ## استفاده در پروژهٔ دیگر در پوشهٔ پروژهٔ دیگر: ```bash zig fetch --save https://api.zaryn.xyz/v1/packages/zig/greet/greet-0.1.0.tar.gz ``` `zig fetch --save` بسته را دانلود و بررسی می‌کند و با هشش به `build.zig.zon` اضافه می‌کند. صفحهٔ بسته در زرین همین مدخل را آمادهٔ کپی نشان می‌دهد، اگر بخواهید خودتان بچسبانید. سپس در `build.zig` به کارش ببرید: ```zig const greet = b.dependency("greet", .{}); exe.root_module.addImport("greet", greet.module("lib")); ``` `"lib"` نام ماژولی است که `build.zig` خود بسته با `b.addModule("lib", …)` می‌دهد؛ README بسته باید بگوید چه نام‌هایی دارد. ## استفاده از یک مخزن زرین به‌عنوان وابستگی هر commit یک مخزن به شکل `.tar.gz` دانلودشدنی است: ```text https://api.zaryn.xyz/v1/repos/<owner>/<repo>/branches/<branch>/archive/<commit>.tar.gz ``` یک commit همیشه همان بایت‌ها را می‌دهد، پس هشش هرگز عوض نمی‌شود. ساده‌ترین راه گرفتن نشانی و هش، پرسیدن از زرین است: ```bash curl https://api.zaryn.xyz/v1/repos/<owner>/<repo>/branches/main/zig-package/HEAD ``` پاسخ تازه‌ترین commit را ثابت می‌کند (هرگز "HEAD" که جابه‌جا می‌شود)، و یک خط آمادهٔ `zig fetch --save …` و مدخل `.dependencies` دارد، به‌اضافهٔ هر چیزی در `build.zig.zon` آن commit که zig ردش می‌کند. در صفحهٔ مخزن هم، اگر `build.zig.zon` داشته باشد، زبانهٔ **zig** کنار دستورهای clone همین را نشان می‌دهد. مخزن باید عمومی باشد تا `zig fetch` بتواند دانلودش کند، چون zig نمی‌تواند توکن بفرستد. ## بسته‌های خصوصی Zig بسته‌ها را می‌شود در صفحهٔ خودشان خصوصی کرد (پریمیوم). چون `zig fetch` نمی‌تواند توکن بفرستد، بستهٔ خصوصی را با curl دانلود کنید، درون پروژه بازش کنید و به پوشه اشاره کنید: ```bash curl -LO -H "Authorization: Bearer $ZARYN_TOKEN" \ https://api.zaryn.xyz/v1/packages/zig/greet/greet-0.1.0.tar.gz mkdir -p deps && tar xzf greet-0.1.0.tar.gz -C deps ``` ```zig .dependencies = .{ .greet = .{ .path = "deps/greet" }, }, ``` ## وقتی چیزی درست کار نمی‌کند | می‌بینید | یعنی | راه‌حل | |---|---|---| | "missing top-level 'fingerprint' field; suggested value: 0x…" | `build.zig.zon` fingerprint ندارد | `.fingerprint = 0x…` را با مقدار پیشنهادی اضافه کنید | | "invalid fingerprint … use 0x…" | fingerprint مال این نام نیست (اغلب بسته‌ای کپی‌شده) | مقدار داده‌شده را بگذارید | | "'name' must be an enum literal" | `.name = "greet"` شکل قدیمی است | `.name = .greet` بنویسید | | "missing top-level 'paths' field" | zig باید بداند کدام فایل‌ها جزو بسته‌اند | `.paths = .{ "build.zig", "build.zig.zon", "src" }` را اضافه کنید | | "there is no build.zig.zon at the top of the archive" | آرشیو پوشه‌ای از پوشه‌هاست، یا manifest ندارد | خود پوشهٔ بسته را بسته‌بندی کنید | | "this package name belongs to someone else" | حساب دیگری این نام را منتشر کرده | `.name` را عوض کنید (و fingerprint تازه بسازید) | | zig می‌گوید `hash mismatch` | آرشیو آن نشانی پس از نوشتن هش تغییر کرده | برای نشانی‌های زرین ممکن نیست؛ برای سایت‌های دیگر [آینه‌ها](/docs/fa/package-mirrors#وابستگیهای-zig) را ببینید | ## هش چطور کار می‌کند zig خود فایل آرشیو را هش نمی‌کند؛ **محتوای درونش** را هش می‌کند. آرشیو را باز می‌کند، فقط فایل‌های زیر `.paths` را نگه می‌دارد، هر فایل را همراه مسیرش هش می‌کند و این هش‌ها را به ترتیب نام ترکیب می‌کند. نتیجه به شکل `name-version-` و پس از آن ۴۴ نویسه نوشته می‌شود که fingerprint و اندازهٔ بسته را هم در خود دارد. به همین دلیل بسته‌بندی دوبارهٔ همان فایل‌ها با ابزاری دیگر، یا افزودن فایل یادداشتی بیرون از `.paths`، همان هش را می‌دهد. زرین همین قاعده‌ها را به کار می‌برد (روی بسته‌های واقعی با `zig fetch` سنجیده شده)، پس هشی که نشان می‌دهد همان هشی است که zig حساب خواهد کرد.