Sepanjang Section ini kita berperan sebagai pemakai: mengunduh crate rand, memanfaatkan bitflags, menikmati hasil resolusi versi orang lain. Peran tersebut bisa dibalik — library yang kita tulis hari ini dapat di-cargo add oleh orang lain di seluruh dunia lewat crates.io. Registry ini terbuka bagi siapa pun: satu akun, satu API token, dan satu perintah cargo publish sudah cukup untuk menaruh crate publik berisi kode, dokumentasi, dan test yang lolos. Chapter ini menyiapkan kandidat publikasi bernama hitung-ongkir dari nol — metadata, test, pemeriksaan nama, isi paket, sampai uji penerbitan dengan dry run — sehingga saat akun crates.io kita siap, langkah terakhir tinggal satu perintah.
Menyiapkan Kandidat: Package hitung-ongkir #
Kandidat kita library kecil yang menarik tarif pengiriman paket. Manifestnya sudah memakai metadata yang dikenal registry:
[package]
name = "hitung-ongkir"
version = "0.1.0"
edition = "2024"
description = "Menghitung ongkir kirim paket berdasarkan berat dan zona kota"
license = "MIT"
authors = ["Budi Santoso <[email protected]>"]
[dependencies]Bedah metadata yang berperan saat publikasi:
- Baris 2 (
name = "hitung-ongkir"): nama menjadi alamat crate di registry — pemakai menuliskancargo add hitung-ongkir. Nama bersifat siapa-cepat-dia-dapat di seluruh crates.io, jadi pilih yang spesifik, bukan generik sepertiutilatauhelper. - Baris 3 (
version = "0.1.0"): nomor rilis pertama. Setiapcargo publishwajib memakai versi yang belum pernah dipakai — menaikkan versi adalah satu-satunya cara merilis perubahan berikutnya. - Baris 5 (
description = "Menghitung ongkir kirim paket berdasarkan berat dan zona kota"): teks yang tampil di hasil pencarian crates.io dan docs.rs. - Baris 6 (
license = "MIT"): pernyataan lisensi kode. crates.io menuntut kunci ini — ataulicense-file— terisi sebelum publikasi.
Isi src/lib.rs mengikuti kebiasaan library yang sehat: komentar /// menjadi dokumentasi dan test melekat pada crate:
/// Menghitung ongkir kirim paket berdasarkan berat dalam gram.
///
/// Tarif dasar Rp8000 untuk 1000 gram pertama,
/// kemudian Rp5000 untuk tiap 1000 gram berikutnya.
pub fn hitung(berat_gram: u32) -> u32 {
let berat_kg = berat_gram / 1000;
if berat_kg == 0 {
8000
} else {
8000 + (berat_kg - 1) * 5000
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn paket_ringan_pakai_tarif_dasar() {
assert_eq!(hitung(800), 8000);
}
#[test]
fn paket_berat_kena_tarif_tambahan() {
assert_eq!(hitung(2500), 13000);
}
}Jalankan cargo test untuk memastikan perilakunya:
running 2 tests
test tests::paket_berat_kena_tarif_tambahan ... ok
test tests::paket_ringan_pakai_tarif_dasar ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00sDua test yang lolos adalah standar minimum sebelum membagikan kode: pemakai tidak akan memberi tahu kita secara sopan ketika crate mereka pasang salah menghitung ongkir.
Peringatan untuk Metadata yang Kurang #
Registry memeriksa kelengkapan manifest pada saat pembungkusan. Perilaku ini bisa kita saksikan tanpa akun — cukup jalankan cargo package pada package polos tanpa description dan license:
warning: manifest has no description, license, license-file, documentation, homepage or repository
|
= note: see https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more detailsPeringatan tersebut mengingatkan bahwa manifest kita di mata registry masih “tanpa identitas”. Package hitung-ongkir sendiri masih menyisakan satu peringatan lebih ringan — manifest has no documentation, homepage or repository — yang hilang begitu kunci repository diisi URL repositori kode.
Memeriksa Nama yang Tersedia #
Sebelum jauh menulis kode, pastikan nama belum diambil orang. crates.io menyediakan API publik yang bisa ditanyai dengan curl:
curl -A "cek-nama-tutorial" https://crates.io/api/v1/crates/hitung-ongkirOutput yang Dihasilkan:
{"errors":[{"detail":"crate `hitung-ongkir` does not exist"}]}Pesan does not exist justru kabar baik: nama tersebut masih tersedia. Sebaliknya, menanyai nama yang sudah ada — misalnya rand — menghasilkan berkas JSON berisi informasi lengkap crate tersebut. Header -A wajib disertakan karena API crates.io menolak permintaan tanpa identitas User-Agent.
Kebijakan nama di crates.io menganut prinsip siapa cepat dia dapat: sekali dipublikasikan, nama melekat pada pemiliknya selamanya, dan nama populer yang diambil tanpa niat serius dianggap squatting yang bisa dilaporkan moderator registry. Praktik yang baik sebelum jatuh cinta pada nama: siapkan dua-tiga kandidat, periksa semuanya sekali jalan, dan hindari nama yang terlalu umum seperti utils maupun yang terlalu mirip dengan crate besar.
Melihat Isi Paket dengan cargo package –list #
Perintah cargo package --list menampilkan berkas apa saja yang akan masuk arsip .crate tanpa benar-benar membuatnya:
cargo package --listOutput yang Dihasilkan:
warning: manifest has no documentation, homepage or repository
|
= note: see https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more details
Cargo.lock
Cargo.toml
Cargo.toml.orig
src/lib.rsEmpat berkas itulah seluruh isi paket: src/lib.rs sebagai kode, Cargo.toml manifest versi publikasi, Cargo.toml.orig salinan manifest asli sebelum penyesuaian, dan Cargo.lock daftar dependency terkunci. Perhatikan yang ikut serta: hanya berkas yang diperlukan membangun crate — folder target, berkas sementara, dan catatan pribadi tidak ikut. Kalau ada berkas yang seharusnya dibuang dari paket, berkas .gitignore atau exclude di manifest mengurusnya; kebalikannya, berkas yang perlu ikut tapi berada di luar konvensi — misalnya berkas data untuk build script — didaftarkan lewat kunci include.
Kelangkapan isi paket bukan perkara kecil. Build pemakai nanti berjalan dari arsip ini, bukan dari folder proyek kita — berkas yang lupa disertakan hanya ketahuan setelah pemakai melaporkan kegagalan build di komputer mereka.
Uji Penerbitan dengan dry run #
Perintah cargo publish menaikkan paket ke crates.io, tetapi versi --dry-run menjalankan seluruh pemeriksaan lalu berhenti tepat sebelum pengunggahan:
cargo publish --dry-runOutput yang Dihasilkan:
Updating crates.io index
warning: manifest has no documentation, homepage or repository
|
= note: see https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more details
Packaging hitung-ongkir v0.1.0 (/tmp/w5a/hitung-ongkir)
Packaged 4 files, 1.8KiB (1.0KiB compressed)
Verifying hitung-ongkir v0.1.0 (/tmp/w5a/hitung-ongkir)
Compiling hitung-ongkir v0.1.0 (/tmp/w5a/hitung-ongkir/target/package/hitung-ongkir-0.1.0)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.70s
Uploading hitung-ongkir v0.1.0 (/tmp/w5a/hitung-ongkir)
warning: aborting upload due to dry runEmpat tahap terbaca berurutan: Packaging merangkai arsip berisi empat berkas, Packaged melaporkan ukurannya, Verifying mengompilasi ulang crate dari dalam arsip untuk membuktikan paket berdiri sendiri, dan Uploading dihentikan oleh warning: aborting upload due to dry run — baris yang menegaskan tidak ada satu byte pun yang meninggalkan komputer kita. Tahap verifikasi yang mengompilasi dari arsip inilah yang menangkap masalah klasik: berkas lupa disertakan atau kode yang kebetulan hanya jalan di folder proyek.
Dry run juga memeriksa hal-hal yang bukan kode: nomor versi di manifest, kelengkapan metadata, sampai nama-nama dependency yang harus tersedia di registry. Karena pemeriksaan lengkap tanpa efek samping, menjalankan dry run sebelum rilis versi apa pun adalah kebiasaan yang murah — termasuk untuk rilis kedua, ketiga, dan seterusnya dari crate yang sama.
Langkah Terakhir: Akun dan Token #
Unggahan sungguhan membutuhkan dua hal yang tidak bisa disimulasikan: akun crates.io dan API token. Prosedurnya ringkas — masuk ke crates.io, daftar dengan akun GitHub, buat token di halaman pengaturan akun, lalu beritahu cargo lewat:
cargo login --registry crates-ioPerintah tersebut meminta token dari terminal — masukkan token milik akun kita sendiri, simpan penampung seperti YOUR_CRATES_IO_TOKEN hanya untuk latihan — dan menyimpannya di berkas kredensial lokal ~/.cargo/credentials. Setelah token tersimpan, perintah cargo publish menjalankan tahapan yang sama persis dengan dry run, lalu melanjutkan pengunggahan yang tadinya dibatalkan. Crate muncul di crates.io beberapa saat kemudian, lengkap dengan dokumentasi yang dibangun docs.rs.
Pemilikan crate bisa dibagikan: perintah cargo owner --add mengundang rekan tim sebagai pemilik bersama sehingga publikasi tidak bergantung pada satu akun. Untuk crate yang dipakai publik, kelengkapan berkas README.md, kunci repository, dan dokumentasi /// yang rapi menentukan kesan pertama pemakai — tiga hal yang alatnya sudah kita siapkan pada chapter-chapter sebelumnya.
Dari sini tanggung jawab kita bergeser menjadi penjaga SemVer: perbaikan galat menaikkan PATCH, fitur baru menaikkan MINOR, dan perubahan API merusak menaikkan MAJOR — persis janji yang kita pelajari dari sisi pemakai pada Chapter Versi dan SemVer.
Ringkasan #
Publikasi menuntut kesiapan berlapis: manifest dengan name, version, description, dan license yang tuntas; test yang lolos; nama yang diperiksa masih tersedia lewat API crates.io; isi paket yang ditinjau lewat cargo package --list; dan uji penerbitan lewat cargo publish --dry-run yang berhenti sebelum mengunggah. Langkah pamungkas menunggu akun crates.io dan token cargo login, setelah itu cargo publish menaikkan versi pertama — permanen, terindeks, dan siap di-cargo add orang lain. Dengan seluruh perkakas package, dependency, feature, profil, workspace, build script, dan publikasi kini di tangan, Section berikutnya mengajak kita menjaga kualitas kode Rust lewat testing yang tertata.