Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Mempublikasikan Crate ke Crates.io

Kita sudah memakai packages dari crates.io sebagai dependencies buat project kita, tapi kita juga bisa nge-share kode kita sama orang lain dengan mempublikasikan packages milik kita sendiri. Registry crate di crates.io mendistribusikan source code dari packages kita, jadi ia pada dasarnya meng-host kode yang open source (sumber terbuka).

Rust dan Cargo punya berbagai fitur yang bikin package yang kita publikasikan jadi lebih gampang dicari dan dipakai orang. Kita bakal membahas beberapa fitur ini lalu menjelaskan gimana caranya mempublikasikan sebuah package.

Mendokumentasikan packages kita secara akurat bakal membantu para user lain tahu gimana dan kapan mereka bisa memakainya, jadi sangat sepadan menghabiskan waktu buat nulis dokumentasi. Di Bab 3, kita sudah membahas gimana cara memberi komentar di kode Rust menggunakan dua garis miring, //. Rust juga punya jenis komentar khusus buat dokumentasi, yang lebih enak disebut documentation comment (komentar dokumentasi), yang bakal men-generate dokumentasi dalam format HTML. HTML ini menampilkan isi dari komentar dokumentasi buat item-item API public yang ditujukan buat para programmer yang tertarik buat tahu gimana cara memakai crate kita, bukannya gimana crate kita itu diimplementasikan.

Komentar dokumentasi memakai tiga garis miring, ///, bukannya dua dan mendukung notasi Markdown buat memformat teksnya. Taruh komentar dokumentasi persis sebelum item yang lagi mereka dokumentasikan. Listing 14-1 menunjukkan komentar dokumentasi buat sebuah fungsi add_one di dalam sebuah crate bernama my_crate.

Filename: src/lib.rs
/// 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
}
Listing 14-1: Sebuah komentar dokumentasi buat sebuah fungsi

Di sini, kita memberikan deskripsi tentang apa yang dilakukan sama fungsi add_one, memulai sebuah bagian (section) dengan judul Examples (Contoh), dan kemudian menyediakan kode yang mendemonstrasikan gimana cara memakai fungsi add_one. Kita bisa men-generate dokumentasi HTML dari komentar dokumentasi ini dengan menjalankan cargo doc. Perintah ini menjalankan tool rustdoc yang didistribusikan bersama Rust dan menaruh dokumentasi HTML hasilnya ke dalam direktori target/doc.

Biar lebih praktis, menjalankan cargo doc --open bakal mem-build HTML buat dokumentasi dari crate kita saat ini (beserta dokumentasi buat semua dependencies crate kita) lalu membuka hasilnya di web browser. Arahkan navigasi ke fungsi add_one dan kita bakal melihat gimana teks di komentar dokumentasi tersebut dirender, seperti yang ditunjukkan di Gambar 14-1.

Dokumentasi HTML yang dirender untuk fungsi `add_one` dari `my_crate`

Gambar 14-1: Dokumentasi HTML untuk fungsi add_one

Bagian-bagian yang Sering Dipakai

Kita memakai heading Markdown # Examples di Listing 14-1 buat membikin sebuah bagian di HTML-nya dengan judul “Examples.” Berikut ini beberapa bagian lain yang sering sekali dipakai oleh para pembuat crate di dokumentasi mereka:

  • Panics: Skenario-skenario di mana fungsi yang didokumentasikan ini bisa mengalami panic. Kode pemanggil fungsi ini yang tidak mau programnya mengalami panic harus memastikan kalau mereka tidak memanggil fungsi ini di situasi-situasi tersebut.
  • Errors: Kalau fungsinya mengembalikan sebuah Result, mendeskripsikan jenis-jenis error apa aja yang mungkin terjadi dan kondisi apa yang mungkin menyebabkan error-error itu dikembalikan bisa sangat ngebantu pemanggil agar mereka bisa nulis kode buat menangani berbagai jenis error dengan cara yang berbeda-beda.
  • Safety: Kalau fungsinya itu unsafe (tidak aman) buat dipanggil (kita membahas soal unsafety di Bab 20), harusnya ada bagian yang menjelaskan kenapa fungsi itu tidak aman dan mencakup invariants (batasan) apa yang diharapkan oleh fungsi tersebut buat dipatuhi sama pemanggilnya.

Kebanyakan komentar dokumentasi tidak perlu punya semua bagian ini, tapi ini adalah checklist yang bagus buat ngingetin kita soal aspek-aspek kode kita yang bakal bikin user tertarik buat tahu.

Komentar Dokumentasi Sebagai Tests (Pengujian)

Menambahkan blok-blok contoh kode di dalam komentar dokumentasi kita bisa membantu mendemonstrasikan gimana cara memakai library kita, dan melakukannya punya keuntungan ekstra: menjalankan cargo test bakal menjalankan contoh kode di dokumentasi kita tersebut sebagai pengujian! Tidak ada yang lebih baik dari dokumentasi yang disertai contoh. Tapi tidak ada yang lebih parah dari contoh yang tidak jalan gara-gara kodenya udah diubah sejak dokumentasinya ditulis. Kalau kita menjalankan cargo test dengan dokumentasi buat fungsi add_one dari Listing 14-1, kita bakal melihat sebuah bagian di hasil pengujian yang kelihatan kayak gini:

   Doc-tests my_crate

running 1 test
test src/lib.rs - add_one (line 5) ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.27s

Sekarang, kalau kita mengubah fungsinya atau contohnya sehingga assert_eq! di contoh tersebut mengalami panic, lalu menjalankan cargo test lagi, kita bakal melihat kalau doc tests bakal menangkap bahwa contoh dan kodenya sudah tidak sinkron lagi!

Mengomentari Item Penampungnya (Contained Items)

Gaya komentar dokumentasi //! menambahkan dokumentasi ke item yang menampung komentar tersebut, bukannya ke item-item yang mengikuti komentarnya. Kita biasanya memakai jenis komentar dokumentasi ini di dalam file crate root (src/lib.rs secara konvensi) atau di dalam sebuah modul buat mendokumentasikan crate atau modulnya secara keseluruhan.

Misalnya, buat menambahkan dokumentasi yang mendeskripsikan tujuan dari crate my_crate yang mengandung fungsi add_one, kita bisa menambahkan komentar dokumentasi yang dimulai dengan //! ke bagian paling awal dari file src/lib.rs, seperti yang ditunjukkan di Listing 14-2.

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

/// Adds one to the number given.
// --snip--
///
/// # Examples
///
/// ```
/// let arg = 5;
/// let answer = my_crate::add_one(arg);
///
/// assert_eq!(6, answer);
/// ```
pub fn add_one(x: i32) -> i32 {
    x + 1
}
Listing 14-2: Dokumentasi untuk crate my_crate secara keseluruhan

Perhatikan bahwa tidak ada kode apa pun setelah baris terakhir yang dimulai dengan //!. Karena kita memulai komentarnya dengan //! bukannya ///, kita mendokumentasikan item yang menampung komentar ini, bukannya item yang ada setelah komentar ini. Di kasus ini, item tersebut adalah file src/lib.rs, yang mana itu adalah crate root. Komentar-komentar ini mendeskripsikan crate-nya secara keseluruhan.

Pas kita menjalankan cargo doc --open, komentar-komentar ini bakal tampil di halaman depan dokumentasi untuk my_crate tepat di atas daftar item-item public di crate tersebut, seperti yang ditunjukkan di Gambar 14-2.

Dokumentasi HTML yang dirender dengan komentar buat _crate_ secara keseluruhan

Gambar 14-2: Dokumentasi yang dirender buat my_crate, termasuk komentar yang mendeskripsikan crate secara keseluruhan

Komentar dokumentasi yang ditaruh di dalam item sangat berguna buat mendeskripsikan crates dan juga modules (modul). Pakailah mereka buat menjelaskan tujuan keseluruhan dari wadah (container)-nya demi membantu para user kita memahami organisasi crate tersebut.

Mengekspor API Public yang Nyaman dengan pub use

Struktur dari API public kita adalah pertimbangan besar saat mempublikasikan sebuah crate. Orang-orang yang memakai crate kita itu kurang familier dengan strukturnya dibandingkan kita dan mungkin bakal kesusahan mencari bagian-bagian yang mau mereka pakai kalau crate kita punya hierarki modul yang besar.

Di Bab 7, kita sudah membahas gimana cara membikin item jadi public memakai keyword pub, dan gimana cara membawa item ke dalam scope memakai keyword use. Namun, struktur yang menurut kita masuk akal saat kita lagi ngembangin sebuah crate mungkin aja tidak terlalu nyaman buat para user kita. Kita mungkin mau mengatur structs kita di dalam sebuah hierarki yang terdiri dari beberapa tingkat, tapi nanti orang yang mau memakai tipe yang sudah kita definisikan jauh di kedalaman hierarki itu mungkin bakal kesulitan buat tahu kalau tipe tersebut ada. Mereka juga mungkin bakal jengkel karena harus mengetikkan use my_crate::some_module::another_module::UsefulType; bukannya sekadar use my_crate::UsefulType;.

Kabar baiknya adalah kalau struktur yang kita buat tidak nyaman buat orang lain pakai dari library mereka, kita tidak harus menata ulang organisasi internalnya: sebagai gantinya, kita bisa me-re-export (mengekspor ulang) item-item buat bikin sebuah struktur public yang beda dari struktur private kita dengan menggunakan pub use. Re-exporting mengambil sebuah item public di satu lokasi lalu membikinnya jadi public di lokasi lain, seolah-olah item tersebut didefinisikan di lokasi yang lain itu.

Misalnya, katakanlah kita bikin sebuah library bernama art untuk memodelkan konsep-konsep kesenian. Di dalam library ini ada dua modul: modul kinds yang berisi dua enum bernama PrimaryColor dan SecondaryColor, serta modul utils yang berisi fungsi bernama mix, seperti yang ditunjukkan di Listing 14-3.

Filename: src/lib.rs
//! # Art
//!
//! A library for modeling artistic concepts.

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 {
        // --snip--
        unimplemented!();
    }
}
Listing 14-3: Sebuah library art yang punya item-item yang diatur ke dalam modul kinds dan utils

Gambar 14-3 menunjukkan seperti apa jadinya halaman depan dokumentasi untuk crate ini yang di-generate oleh cargo doc.

Dokumentasi yang dirender untuk _crate_ `art` yang mendaftarkan modul `kinds` dan `utils`

Gambar 14-3: Halaman depan dokumentasi untuk art yang mendaftarkan modul kinds dan utils

Perhatikan bahwa tipe PrimaryColor dan SecondaryColor tidak terdaftar di halaman depan, fungsi mix juga tidak ada. Kita harus mengklik kinds dan utils buat melihat mereka.

Crate lain yang bergantung pada library ini bakal butuh statements use yang membawa item-item dari art ke dalam scope, dengan menentukan struktur modul yang saat ini didefinisikan. Listing 14-4 menunjukkan contoh sebuah crate yang memakai item PrimaryColor dan mix dari crate art.

Filename: src/main.rs
use art::kinds::PrimaryColor;
use art::utils::mix;

fn main() {
    let red = PrimaryColor::Red;
    let yellow = PrimaryColor::Yellow;
    mix(red, yellow);
}
Listing 14-4: Sebuah crate yang memakai item dari crate art dengan struktur internalnya yang terekspor

Pembuat kode di Listing 14-4, yang memakai crate art, harus mencari tahu kalau PrimaryColor ada di dalam modul kinds dan mix ada di dalam modul utils. Struktur modul dari crate art ini lebih relevan buat para developer yang mengerjakan crate art tersebut dibanding buat orang yang memakainya. Struktur internalnya tidak memberikan informasi yang berguna buat seseorang yang lagi mencoba buat paham gimana cara memakai crate art tersebut, melainkan malah bikin bingung karena developer yang memakainya harus nyari tahu di mana harus mencari, dan harus mengetikkan nama-nama modulnya di statement use.

Buat menghilangkan organisasi internalnya dari API public, kita bisa memodifikasi kode crate art di Listing 14-3 dengan menambahkan statements pub use buat me-re-export item-item itu di tingkat paling atas, seperti yang ditunjukkan di Listing 14-5.

Filename: src/lib.rs
//! # 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 {
    // --snip--
    /// 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 {
    // --snip--
    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
    }
}
Listing 14-5: Menambahkan statements pub use buat me-re-export item

Dokumentasi API yang di-generate sama cargo doc buat crate ini sekarang bakal mendaftarkan dan menaruh tautan ke re-exports tersebut di halaman depan, seperti yang ditunjukkan di Gambar 14-4, sehingga bikin tipe PrimaryColor dan SecondaryColor serta fungsi mix jadi lebih gampang dicari.

Dokumentasi yang dirender untuk _crate_ `art` dengan hasil *re-exports* di halaman depan

Gambar 14-4: Halaman depan dokumentasi buat art yang mendaftarkan hasil re-exports

Para pengguna crate art masih bisa melihat dan memakai struktur internalnya dari Listing 14-3 seperti yang didemonstrasikan di Listing 14-4, atau mereka bisa memakai struktur yang lebih nyaman dari Listing 14-5, seperti yang ditunjukkan di Listing 14-6.

Filename: src/main.rs
use art::PrimaryColor;
use art::mix;

fn main() {
    // --snip--
    let red = PrimaryColor::Red;
    let yellow = PrimaryColor::Yellow;
    mix(red, yellow);
}
Listing 14-6: Sebuah program yang memakai item yang di-re-export dari crate art

Di kasus di mana ada banyak modul yang bersarang (nested modules), me-re-export tipe di level teratas dengan pub use bisa bikin perbedaan yang sangat besar dalam pengalaman (experience) orang-orang yang memakai crate tersebut. Kegunaan umum lain dari pub use adalah buat me-re-export definisi dari sebuah dependency (dependensi) di crate saat ini buat bikin definisi crate itu jadi bagian dari API public crate kita.

Membikin struktur API public yang berguna itu lebih ke arah seni ketimbang sains eksak, dan kita bisa melakukan iterasi buat nemuin API apa yang bekerja paling baik buat para user kita. Memilih buat pakai pub use ngasih kita fleksibilitas dalam mengatur gimana struktur internal crate kita dan melepaskan kaitan (decouples) antara struktur internal itu dari apa yang kita tampilkan ke para user kita. Coba deh lihat beberapa kode dari crates yang udah kita instal buat melihat apakah struktur internal mereka berbeda dari API public mereka.

Menyiapkan Akun Crates.io

Sebelum kita bisa mempublikasikan crates apa pun, kita harus bikin akun dulu di crates.io dan dapetin API token. Buat melakukannya, kunjungi halaman depan di crates.io lalu login pakai akun GitHub. (Akun GitHub saat ini adalah syarat wajibnya, tapi situsnya mungkin bakal mendukung cara lain buat bikin akun di masa depan.) Setelah kita login, kunjungi pengaturan akun kita di https://crates.io/me/ lalu ambil kunci (key) API kita. Kemudian jalankan perintah cargo login dan paste kunci API kita pas diminta, kayak gini:

$ cargo login
abcdefghijklmnopqrstuvwxyz012345

Perintah ini bakal ngasih tahu Cargo soal token API kita lalu menyimpannya secara lokal di ~/.cargo/credentials.toml. Perhatikan bahwa token ini adalah sebuah rahasia (secret): jangan bagikan ke orang lain. Kalau kita membagikannya ke orang lain dengan alasan apa pun, kita harus menariknya (revoke) dan membuat token baru di crates.io.

Menambahkan Metadata ke Crate Baru

Katakanlah kita punya sebuah crate yang mau kita publikasikan. Sebelum dipublish, kita harus menambahkan beberapa metadata di bagian [package] dari file Cargo.toml milik crate tersebut.

Crate kita bakal butuh nama yang unik. Selama kita mengerjakan crate secara lokal, kita bisa menamai crate sesuka kita. Namun, nama crate di crates.io itu dialokasikan berdasarkan siapa cepat dia dapat (first-come, first-served). Begitu sebuah nama crate sudah diambil, tidak ada orang lain yang bisa mempublikasikan crate dengan nama tersebut. Sebelum mencoba buat mempublikasikan sebuah crate, carilah nama yang pengen kita pakai. Kalau nama tersebut sudah terpakai, kita harus mencari nama lain lalu mengedit field name di dalam file Cargo.toml di bawah bagian [package] buat memakai nama baru tersebut untuk publikasi, kayak gini:

Nama file: Cargo.toml

[package]
name = "guessing_game"

Meskipun kita sudah milih nama yang unik, saat kita menjalankan cargo publish buat mempublikasikan crate di titik ini, kita bakal dapat peringatan dan lalu sebuah error:

$ cargo publish
    Updating crates.io index
warning: manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
--snip--
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. Please see https://doc.rust-lang.org/cargo/reference/manifest.html for more information on configuring these fields

Ini menghasilkan error karena kita kelupaan beberapa informasi yang krusial: sebuah deskripsi (description) dan lisensi (license) diwajibkan supaya orang-orang bisa tahu apa yang dilakukan sama crate kita dan di bawah ketentuan (terms) apa mereka bisa memakainya. Di Cargo.toml, tambahkan sebuah deskripsi yang hanya terdiri dari satu atau dua kalimat aja, karena itu bakal muncul bareng crate kita di hasil pencarian. Buat field license, kita harus memberikan nilai pengenal lisensi (license identifier value). Software Package Data Exchange (SPDX) milik Linux Foundation mendaftarkan pengenal yang bisa kita pakai buat nilai ini. Misalnya, buat menentukan kalau kita melisensikan crate kita memakai Lisensi MIT, tambahkan pengenal MIT:

Nama file: Cargo.toml

[package]
name = "guessing_game"
license = "MIT"

Kalau kita mau memakai lisensi yang tidak muncul di SPDX, kita perlu menaruh teks dari lisensi tersebut di sebuah file, memasukkan file itu di project kita, lalu memakai license-file buat menentukan nama dari file tersebut sebagai ganti dari memakai key license.

Panduan soal lisensi mana yang pas buat project kita ada di luar cakupan buku ini. Banyak orang di komunitas Rust melisensikan project mereka pakai cara yang sama kayak Rust dengan memakai dual license (lisensi ganda) MIT OR Apache-2.0. Praktik ini menunjukkan kalau kita juga bisa menentukan lebih dari satu pengenal lisensi yang dipisahkan oleh OR buat punya banyak lisensi di project kita.

Dengan nama yang unik, versi, deskripsi kita, dan lisensi yang sudah ditambahkan, file Cargo.toml untuk project yang siap dipublish mungkin bakal kelihatan kayak gini:

Nama file: Cargo.toml

[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]

Dokumentasi Cargo mendeskripsikan metadata lain yang bisa kita tentukan buat memastikan orang lain bisa lebih gampang menemukan dan memakai crate kita.

Mempublikasikan ke Crates.io

Sekarang karena kita udah bikin akun, nyimpan token API kita, memilih nama buat crate kita, dan menentukan metadata yang dibutuhin, kita sudah siap buat melakukan publikasi! Mempublikasikan sebuah crate mengunggah versi spesifiknya ke crates.io biar orang lain bisa pakai.

Hati-hati ya, karena mempublikasikan itu sifatnya permanen. Versi itu tidak akan pernah bisa ditimpa (overwritten), dan kodenya tidak bisa dihapus kecuali di situasi-situasi tertentu. Salah satu tujuan utama dari Crates.io adalah bertindak sebagai arsip kode yang permanen sehingga proses build dari semua project yang bergantung pada crates dari crates.io bakal terus berfungsi. Mengizinkan penghapusan versi bakal bikin pemenuhan tujuan tersebut jadi mustahil. Namun, tidak ada batas buat seberapa banyak versi crate yang bisa kita publikasikan.

Jalankan perintah cargo publish lagi. Kali ini harusnya udah berhasil:

$ 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
(file:///projects/guessing_game/target/package/guessing_game-0.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`
note: waiting for `guessing_game v0.1.0` to be available at registry
`crates-io`.
You may press ctrl-c to skip waiting; the crate should be available shortly.
   Published guessing_game v0.1.0 at registry `crates-io`

Selamat! Kita sekarang sudah nge-share kode kita sama komunitas Rust, dan siapa pun bisa dengan gampang nambahin crate kita sebagai dependency di project mereka.

Mempublikasikan Versi Baru dari Crate yang Sudah Ada

Saat kita bikin perubahan di crate kita dan udah siap buat ngerilis versi baru, kita cukup ganti nilai version yang ditentukan di file Cargo.toml kita dan publish ulang (republish). Pakai aturan Semantic Versioning buat nentuin apa nomor versi selanjutnya yang paling pas, berdasarkan jenis perubahan yang sudah kita buat. Terus jalankan cargo publish buat mengunggah versi barunya.

Melarang Penggunaan Versi Lama dari Crates.io dengan cargo yank

Meskipun kita tidak bisa menghapus versi lama dari sebuah crate, kita bisa mencegah project-project di masa depan buat menambahkan versi tersebut sebagai dependency baru. Hal ini berguna pas sebuah versi crate ternyata rusak (broken) karena suatu alasan tertentu. Di situasi semacam itu, Cargo mendukung aksi “menyentak” (yanking) sebuah versi crate.

Yanking sebuah versi mencegah project baru untuk bisa bergantung pada versi tersebut sekaligus tetap membiarkan semua project yang sudah ada yang bergantung pada versi itu buat terus berjalan. Pada dasarnya, aksi yank berarti bahwa semua project yang sudah punya file Cargo.lock tidak akan rusak, dan file Cargo.lock apa pun yang di-generate di masa depan tidak bakal memakai versi yang di-yank tersebut.

Buat menge-yank sebuah versi crate, dari dalam direktori crate yang tadinya sudah kita publikasikan, jalankan cargo yank dan tentukan versi mana yang mau kita yank. Misalnya, kalau kita sudah mempublikasikan sebuah crate bernama guessing_game versi 1.0.1 dan kita mau menge-yank-nya, di dalam direktori project buat guessing_game kita bakal menjalankan:

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

Dengan menambahkan --undo ke dalam command-nya, kita juga bisa membatalkan aksi yank (meng-unyank) lalu mengizinkan project-project buat mulai bergantung lagi pada sebuah versi:

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

Aksi yank sama sekali tidak menghapus kode apa pun. Ia tidak bisa, misalnya, menghapus data rahasia (secrets) yang tidak sengaja terunggah. Kalau hal seperti itu terjadi, kita harus langsung nge-reset rahasia tersebut.