পাঠ ১৪.২

Crates.io-তে crate publish করা

Publishing a Crate to Crates.io

Crates.io হলো Rust-এর package registry — অন্যদের লেখা crate এখানেই পাওয়া যায়, এবং নিজেও publish করে অন্যদের সাথে share করা যায়। এই পাঠে দেখব কী ভাবে documentation লিখতে হয়, public API design করতে হয়, metadata add করতে হয়, এবং শেষে publish ও version manage করতে হয়।

Documentation comment

Documentation comment তিনটে slash /// দিয়ে শুরু এবং Markdown support করে। Public API item-এর জন্য HTML documentation generate হয়।

src/lib.rsrust
/// Adds one to the number given.
///
/// # Examples
///
/// ```
/// let arg = 5;
/// let answer = my_crate::add_one(arg);
///
/// assert_eq!(6, answer);
/// ```
pub fn add_one(x: i32) -> i32 {
    x + 1
}

HTML build করতে:

terminalbash
$ cargo doc          # target/doc/-এ HTML generate
$ cargo doc --open   # browser-এ open

প্রচলিত section

  • # Examples — কীভাবে use করতে হয়।
  • # Panics — কোন scenario-তে function panic করতে পারে।
  • # ErrorsResult-return করা function কোন কোন error দিতে পারে।
  • # Safetyunsafe function-এর caller-কে কোন invariant uphold করতে হবে।

Doc-test হিসেবে example

Documentation-এর code example cargo test চালালে automatically run হয়। তাই documentation কখনো actual code-এর সাথে out of sync থাকে না।

terminalbash
$ cargo test

Containing item-এর comment

//! comment containing item document করে — সাধারণত crate বা module-এর top-এ লেখা হয়।

src/lib.rsrust
//! # My Crate
//!
//! `my_crate` is a collection of utilities to make performing certain
//! calculations more convenient.

/// Adds one to the number given.
pub fn add_one(x: i32) -> i32 {
    x + 1
}

pub use দিয়ে convenient public API

Internally module hierarchy অনেক গভীর হলেও user-এর জন্য সেটা চাপিয়ে দেওয়া উচিত না। pub use দিয়ে item top-level-এ re-export করে public API-কে flat রাখা যায়।

src/lib.rsrust
//! # Art
//!
//! A library for modeling artistic concepts.

pub use self::kinds::PrimaryColor;
pub use self::kinds::SecondaryColor;
pub use self::utils::mix;

pub mod kinds {
    /// The primary colors according to the RYB color model.
    pub enum PrimaryColor {
        Red,
        Yellow,
        Blue,
    }

    /// The secondary colors according to the RYB color model.
    pub enum SecondaryColor {
        Orange,
        Green,
        Purple,
    }
}

pub mod utils {
    use crate::kinds::*;

    /// Combines two primary colors in equal amounts to create
    /// a secondary color.
    pub fn mix(c1: PrimaryColor, c2: PrimaryColor) -> SecondaryColor {
        SecondaryColor::Orange
    }
}

Re-export-এর আগে user লিখত:

use art::kinds::PrimaryColor;
use art::utils::mix;

Re-export-এর পরে:

use art::PrimaryColor;
use art::mix;

Internal structure এখনো develop-করা সহজ — public API stable।

Crates.io account

  1. crates.io-এ যাও, GitHub দিয়ে log in।
  2. Profile page থেকে API token নাও।
  3. Login command:
terminalbash
$ cargo login
abcdefghijklmnopqrstuvwxyz012345

Token ~/.cargo/credentials.toml-এ save। সিক্রেট রাখো — share কোরো না।

Metadata add করা

Crate-এর নাম unique হতে হবে — first-come, first-served:

Cargo.tomltoml
[package]
name = "guessing_game"

Publish-এর জন্য আরও কিছু metadata দরকার:

Cargo.tomltoml
[package]
name = "guessing_game"
version = "0.1.0"
edition = "2024"
description = "A fun game where you guess what number the computer has chosen."
license = "MIT OR Apache-2.0"

[dependencies]
  • description — search result-এ দেখানো হবে।
  • license — SPDX identifier ব্যবহার করো। একাধিক license: "MIT OR Apache-2.0"। Custom license file-এর জন্য license-file = "LICENSE.txt"

Metadata না দিলে error:

cargo publish errortext
warning: manifest has no description, license, license-file, documentation, homepage or repository.
error: failed to publish to registry at https://crates.io
Caused by:
  the remote server responded with an error (status 400 Bad Request): missing or empty metadata fields: description, license.

Publish করা

terminalbash
$ cargo publish
    Updating crates.io index
   Packaging guessing_game v0.1.0 (file:///projects/guessing_game)
    Packaged 6 files, 1.2KiB (895.0B compressed)
   Verifying guessing_game v0.1.0 (file:///projects/guessing_game)
   Compiling guessing_game v0.1.0
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.19s
   Uploading guessing_game v0.1.0 (file:///projects/guessing_game)
    Uploaded guessing_game v0.1.0 to registry `crates-io`
    Published guessing_game v0.1.0 at registry `crates-io`

গুরুত্বপূর্ণ — একবার publish-করা version permanent। Overwrite বা delete করা যায় না। Crates.io permanent code archive হিসেবে কাজ করে।

নতুন version publish

Cargo.toml-এ version update করে আবার publish। Version number Semantic Versioning rule অনুযায়ী বাড়াও।

Cargo.tomltoml
[package]
name = "guessing_game"
version = "0.2.0"
terminalbash
$ cargo publish

Version yank করা

Yank মানে — কোনো version-কে নতুন project-এর dependency হিসেবে use করা আটকানো। কিন্তু পুরোনো project-এ যাদের Cargo.lock-এ এই version আছে তাদের কোনো সমস্যা হবে না।

terminalbash
$ cargo yank --vers 1.0.1
    Updating crates.io index
        Yank guessing_game@1.0.1

Undo:

terminalbash
$ cargo yank --vers 1.0.1 --undo
    Updating crates.io index
      Unyank guessing_game@1.0.1

সাবধান — yank code delete করে না। ভুল করে কোনো secret upload হলে সেটা সাথে সাথে rotate/reset করতেই হবে।

এই পাঠ থেকে যা শিখলে

  • /// public item-এর জন্য, //! containing item-এর জন্য doc comment। Markdown supported।
  • Doc-এর code example cargo test-এ run হয় — documentation আর code sync থাকে।
  • pub use দিয়ে internal hierarchy hide করে convenient public API exposed করা যায়।
  • Publish-এর জন্য name, version, description, license — সবই দরকার।
  • cargo publish করলে version permanent — overwrite/delete নেই; SemVer follow করো।
  • cargo yank --vers X দিয়ে broken version deprecate; existing user-দের ক্ষতি হয় না।