Crates auf crates.io veröffentlichen
Wir haben Pakete von crates.io als Abhängigkeiten (dependencies) unseres Projekts verwendet. Du kannst deinen Programmcode jedoch auch für andere Personen freigeben, indem du eigene Pakete veröffentlichst. Die Registrierung von Crates auf crates.io verteilt den Quellcode deiner Pakete, daher wird primär Open Source Programmcode gehostet.
Rust und Cargo verfügen über Funktionalitäten, die es Benutzern erleichtern, ihr veröffentlichtes Paket zu finden und zu verwenden. Wir werden nun über einige dieser Funktionalitäten sprechen und dann erklären, wie ein Paket veröffentlicht wird.
Sinnvolle Dokumentationskommentare erstellen
Die genaue Dokumentation deiner Pakete hilft anderen Benutzern zu verstehen, wie
diese zu verwenden sind, daher lohnt es sich, Zeit in die Dokumentationen zu
investieren. In Kapitel 3 haben wir besprochen, wie man Rust-Code mit zwei
Schrägstrichen // kommentiert. Rust hat auch eine eigene Art von Kommentar für
die Dokumentation, die passenderweise als Dokumentationskommentar bezeichnet
wird und HTML-Dokumentation generiert. Der HTML-Code zeigt den Inhalt von
Dokumentationskommentaren für öffentliche API-Elemente an, die für Programmierer
bestimmt sind, die wissen möchten, wie deine Crate benutzt wird, und nicht,
wie deine Crate implementiert ist.
Dokumentationskommentare verwenden drei Schrägstriche /// anstelle von zwei
und unterstützen Markdown-Notation zum Formatieren des Textes. Platziere
Dokumentationskommentare nur vor dem zu dokumentierenden Element. Listing
14-1 zeigt Dokumentationskommentare für eine Funktion add_one in einer Crate
mit dem Namen my_crate.
Dateiname: 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: Ein Dokumentationskommentar für eine Funktion
Hier geben wir eine Beschreibung der Funktionsweise der Funktion add_one an,
beginnen einen Abschnitt mit der Überschrift Examples gefolgt vom
Programmcode, der die Verwendung der Funktion add_one demonstriert. Wir können
die HTML-Dokumentation aus diesem Dokumentationskommentar generieren, indem wir
cargo doc ausführen. Dieser Befehl führt das mit Rust verbreitete Werkzeug
rustdoc aus und legt die generierte HTML-Dokumentation im Verzeichnis
target/doc ab.
Wenn du cargo doc --open ausführst, wird der HTML-Code für die Dokumentation
deiner aktuellen Crate (und auch die Dokumentation aller Abhängigkeiten
(dependencies) deiner Crate) erstellt und das Ergebnis in einem Webbrowser
geöffnet. Wenn du zur Funktion add_one navigierst, wirst du sehen, wie der
Text in den Dokumentationskommentaren gerendert wird. Siehe Abbildung 14-1.
Abbildung 14-1: HTML-Dokumentation für die Funktion
add_one
Häufig verwendete Abschnitte
Wir haben die Markdown-Überschrift # Examples in Listing 14-1 verwendet, um
einen Abschnitt im HTML-Code mit dem Titel Examples zu erstellen. Hier sind
einige andere Abschnitte, die Autoren von Crates häufig in ihrer Dokumentation
verwenden:
- Panics: Das sind die Szenarien, in denen die dokumentierte Funktion abbricht. Aufrufer der Funktion, die nicht möchten, dass ihre Programme abbrechen, sollten sicherstellen, dass sie die Funktion in solchen Situationen nicht aufrufen.
- Errors: Wenn die Funktion ein
Resultzurückgibt, kann die Beschreibung der möglichen Fehlerarten und der Bedingungen, unter denen diese Fehler zurückgegeben werden, den Aufrufenden dabei helfen, Code zu schreiben, der die verschiedenen Fehlerarten jeweils anders behandelt. - Safety: Wenn der Aufruf der Funktion unsicher (
unsafe) ist (wir behandeln Unsafe im Kapitel 20), sollte ein Abschnitt existieren, in dem erläutert wird, warum die Funktion unsicher ist, und die Invarianten behandelt werden, die die Funktion vom Aufrufenden erwartet.
Die meisten Dokumentationskommentare benötigen nicht alle Abschnitte, aber dies ist eine gute Checkliste, um dich an die Aspekte deines Programmcodes erinnern, die für Benutzer interessant sein werden.
Dokumentationskommentare als Tests
Das Hinzufügen von Beispiel-Codeblöcken in deinen Dokumentationskommentaren kann
dabei hilfreich sein, die Verwendung deiner Programmbibliothek darzustellen.
Dies hat einen zusätzlichen Bonus: Das Ausführen von cargo test führt die
Codeblöcke in deiner Dokumentation als Test aus! Nichts ist besser als eine
Dokumentation mit Beispielen, aber nichts ist schlimmer als eine Dokumentation
mit Beispielen, die nicht funktionieren, da sich der Code seit dem Schreiben der
Dokumentation geändert hat. Wenn wir cargo test für die Dokumentation der
Funktion add_one aus Listing 14-1 aufrufen, sehen wir folgenden Abschnitt in
den Testergebnissen:
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
Wenn wir nun entweder die Funktion oder das Beispiel so ändern, dass assert_eq!
im Beispiel panic aufruft und erneut cargo test aufrufen, werden wir
bemerken, dass cargo test feststellt, dass das Beispiel und der Code nicht
synchron miteinander sind!
Enthaltene Elemente kommentieren
Der Stil des Dokumentationskommentars //! fügt dem Element, das die
Kommentare enthält, Dokumentation hinzu, anstatt den Elementen, die auf die
Kommentare folgen. Wir verwenden diese Dokumentationskommentare üblicherweise
in der Wurzeldatei (laut Konvention src/lib.rs) oder in einem Modul, um die
Crate oder das Modul als Ganzes zu dokumentieren.
Um beispielsweise eine Dokumentation hinzuzufügen, die den Zweck der Crate
my_crate beschreibt, die die Funktion add_one enthält, können wir am Anfang
der Datei src/lib.rs Dokumentationskommentare hinzufügen, die mit //!
beginnen. Siehe Listing 14-2.
Dateiname: 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.
// --abschneiden--
///
/// # 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: Dokumentation für die gesamte Crate
my_crate
Beachte, dass nach der letzten Zeile, die mit //! beginnt, kein Programmcode
mehr vorhanden ist. Da wir die Kommentare mit //! anstatt /// begonnen
haben, dokumentieren wir das Element, das diesen Kommentar enthält und nicht
ein Element, das diesem Kommentar folgt. In diesem Fall ist dieses Element die
Datei src/lib.rs, dabei handelt es sich um das Wurzelverzeichnis der Crate.
Diese Kommentare beschreiben die gesamte Crate.
Wenn wir cargo doc --open ausführen, werden diese Kommentare auf der
Startseite der Dokumentation für my_crate angezeigt, oberhalb der Liste der
veröffentlichten Elemente in der Crate. Siehe Abbildung 14-2.
Dokumentationskommentare innerhalb von Elementen sind besonders nützlich, um Crates und Module zu beschreiben. Erkläre anhand dieser Informationen den allgemeinen Zweck des Elements, damit seine Benutzer die Aufteilung der Crate besser verstehen können.
Abbildung 14-2: Gerenderte Dokumentation für my_crate,
einschließlich des Kommentars, der die Crate als Ganzes beschreibt
Exportieren einer komfortablen öffentlichen API
Die Struktur deiner öffentlichen API spielt beim Veröffentlichen einer Crate eine wichtige Rolle. Personen, die deine Crate verwenden, sind mit der Struktur weniger vertraut als du und haben vielleicht Schwierigkeiten, die Teile zu finden, die sie verwenden möchten, wenn deine Crate eine große Modulhierarchie aufweist.
In Kapitel 7 wurde erläutert, wie wir unseren Programmcode mithilfe des
Schlüsselworts mod in Module organisieren, Elemente mit dem Schlüsselwort
pub veröffentlichen und Elemente mit dem Schlüsselwort use in einen
Gültigkeitsbereich (scope) bringen. Die Struktur, die für dich während der
Entwicklung einer Crate sinnvoll ist, ist für ihre Benutzer jedoch
möglicherweise nicht sehr benutzerfreundlich. Vielleicht möchtest du Strukturen
in einer Hierarchie mit mehreren Ebenen organisieren, aber Personen, die einen
Typ verwenden möchten, den du tief in der Hierarchie definiert hast, haben
möglicherweise Probleme, herauszufinden, ob dieser Typ vorhanden ist. Sie
könnten sich auch darüber ärgern, dass sie use
my_crate::some_module::another_module::UsefulType; eingeben müssen anstatt
use my_crate::UsefulType;.
Die gute Nachricht ist, dass du die interne Organisation nicht neu anordnen
musst, wenn sie für andere aus einer anderen Bibliothek nicht geeignet ist.
Stattdessen kannst du Elemente erneut exportieren, um mit pub use eine
veränderte öffentliche Struktur von deiner privaten Struktur zu erstellen.
Beim Re-Exportieren wird ein öffentliches Element an einem Speicherort genommen
und an einem anderen Speicherort öffentlich gemacht, als ob es stattdessen am
anderen Speicherort definiert worden wäre.
Nehmen wir zum Beispiel an, wir haben eine Bibliothek mit dem Namen art
erstellt, um künstlerische Konzepte zu modellieren. In dieser Bibliothek sind
zwei Module enthalten: Ein Modul kinds mit zwei Aufzählungen (enums) namens
PrimaryColor und SecondaryColor und ein Modul utils, das eine Funktion
namens mix beinhaltet. Siehe Listing 14-3.
Dateiname: 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 {
// --abschneiden--
unimplemented!();
}
}
Listing 14-3: Eine Bibliothek art mit Elementen, die in
Modulen kinds und utils organisiert sind
Abbildung 14-3 zeigt, wie die Startseite der Dokumentation für diese Crate
generiert von cargo doc aussehen würde.
Abbildung 14-3: Startseite der Dokumentation für art
mit den Modulen kinds und utils auflistet
Beachte, dass die Typen PrimaryColor, SecondaryColor und die Funktion mix
nicht auf der Startseite angeführt sind. Wir müssen auf kinds und utils
klicken, um sie zu sehen.
Eine Crate, die von dieser Bibliothek abhängt, würde use-Anweisungen
benötigen, die die Elemente aus art in den Gültigkeitsbereich bringen und die
derzeit definierte Modulstruktur angeben. Listing 14-4 zeigt ein Beispiel für
eine Crate, in der die Elemente PrimaryColor und mix aus der Crate art
verwendet werden.
Dateiname: 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: Eine Crate, die die Elemente der Crate art
mit ihrer internen Struktur exportiert
Der Autor des Programmcodes in Listing 14-4, der die Crate art verwendet,
musste herausfinden, dass sich PrimaryColor im Modul kinds und mix im
Modul utils befindet. Die Modulstruktur der Crate art ist für Entwickler,
die an der Crate art arbeiten, relevanter als für Entwickler, die die Crate
art verwenden. Die interne Struktur enthält keine nützlichen Informationen für
jemanden, der diese benutzen möchte, sondern sorgt für Verwirrung, da diese
herausfinden müssen, wo sie suchen müssen und die Struktur ist unpraktisch, da
Entwickler die Modulnamen in den use-Anweisungen angeben müssen.
Um die interne Organisation aus der öffentlichen API zu entfernen, können wir
den Programmcode der Crate art ändern, um pub use-Anweisungen hinzuzufügen,
um die Elemente der obersten Ebene erneut zu exportieren, wie in Listing 14-5
gezeigt.
Dateiname: 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 {
// --abschneiden--
/// 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 {
// --abschneiden--
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: Hinzufügen von pub use, um Elemente erneut
zu exportieren
Die Dokumentation der API, die von cargo doc generiert wurde, wird nun
aufgelistet und die erneut exportierten Links werden auf der Startseite, wie in
Abbildung 14-4 ersichtlich, angezeigt, so sind die Typen PrimaryColor und
SecondaryColor leichter zu finden.
Abbildung 14-4: Die Startseite der Dokumentation von
art mit den aufgelisteten erneuten Exporten
Die Benutzer der Crate art können weiterhin die interne Struktur aus Listing
14-3 sehen und verwenden, wie es in Listing 14-4 gezeigt wurde, oder sie
können die benutzerfreundliche Struktur in Listing 14-5 verwenden, wie es im
Listing 14-6 gezeigt wurde.
Dateiname: src/main.rs
use art::mix;
use art::PrimaryColor;
fn main() {
// --abschneiden--
let red = PrimaryColor::Red;
let yellow = PrimaryColor::Yellow;
mix(red, yellow);
}
Listing 14-6: Ein Programm, das die erneut exportierten
Elemente der Crate art verwendet
In Fällen, in denen es viele verschachtelte Module gibt, kann das erneute
Exportieren der Typen auf der obersten Ebene mit pub use die Erfahrung der
Benutzer der Crate signifikant verbessern. Eine andere häufige Verwendung von
pub use ist es, Definitionen einer Abhängigkeit in der aktuellen Crate zu
re-exportieren, um die Definitionen dieser Crate zu einem Teil der öffentlichen
API deiner Crate zu machen.
Das Erstellen einer sinnvollen öffentlichen API-Struktur ist eher eine Kunst als
eine Wissenschaft, und du kannst iterieren, um die API zu finden, die für
Benutzer am besten geeignet ist. Wenn man pub use wählt, erhält man
Flexibilität bei der internen Strukturierung einer Crate und entkoppelt diese
interne Struktur von dem, was man ihren Benutzern präsentiert. Sieh dir einige
der Programmcodes von Crates an, die du installiert hast, um festzustellen, ob
sie intern strukturiert sind und ob sich ihre interne Struktur von der
öffentlichen API unterscheidet.
Einrichten eines Accounts auf crates.io
Bevor man eine Crate veröffentlichen kann, muss man einen Account auf
crates.io erstellen, um ein API-Token zu erhalten. Besuche dazu die
Homepage auf crates.io und melde dich über einen GitHub-Account an. (Derzeit ist
ein GitHub-Account eine Voraussetzung, aber die Seite wird möglicherweise in
Zukunft andere Wege anbieten, um einen Account zu erstellen.) Sobald du
angemeldet bist, gehe zu Kontoeinstellungen (account settings) auf
https://crates.io/me/ und erhalte deinen API-Schlüssel. Rufe
anschließend das Kommando cargo login mit deinem API-Schlüssel auf:
$ cargo login
abcdefghijklmnopqrstuvwxyz012345
Dieses Kommando informiert Cargo über dein API-Token und speichert es lokal in ~/.cargo/credentials.toml. Beachte, dass dieses Token ein Geheimnis ist: Gib es nicht an andere weiter. Wenn du es aus irgendeinem Grund mit jemandem geteilt hast, solltest du es widerrufen und ein neues Token auf crates.io erzeugen.
Metadaten zu einer neuen Crate hinzufügen
Angenommen, du hast eine Crate, die du veröffentlichen möchtest. Vor dem
Veröffentlichen musst du deiner Crate einige Metadaten im Abschnitt [package]
der Datei Cargo.toml der Crate hinzufügen.
Deine Crate benötigt einen eindeutigen Namen. Während du vor Ort an einer Crate
arbeitest, kannst du eine Crate beliebig benennen. Allerdings werden Crate-Namen
auf crates.io nach Verfügbarkeit vergeben. Sobald ein Crate-Name vergeben ist,
kann niemand mehr eine Crate mit diesem Namen veröffentlichen. Suche vor dem
Versuch, eine Crate zu veröffentlichen, nach dem Namen, den du verwenden
möchtest. Wenn der Name von einer anderen Crate verwendet wurde, wirst du einen
anderen Namen suchen müssen und das Feld name in der Datei Cargo.toml im
Abschnitt [package] bearbeiten, um den neuen Namen für die Veröffentlichung zu
verwenden:
Dateiname: Cargo.toml
[package]
name = "guessing_game"
Selbst wenn du einen eindeutigen Namen gewählt hast, wird beim Ausführen von
cargo publish zum Veröffentlichen der Crate an dieser Stelle eine Warnung und
anschließend ein Fehler angezeigt:
$ 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.
--abschneiden--
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 field
Dies schlägt fehl, weil einige wichtige Informationen fehlen: Eine Beschreibung
und eine Lizenz sind erforderlich, damit die Benutzer wissen, was deine Crate
tut und unter welchen Bedingungen man sie verwenden kann. Ergänze in der Datei
Cargo.toml eine Beschreibung hinzu, die nur ein oder zwei Sätze umfasst, da
sie zusammen mit deiner Crate in den Suchergebnissen angezeigt wird. Für das
Feld license musst du einen Lizenzkennungswert (license identifier value)
angeben. In Linux Foundation’s Software Package Data Exchange (SPDX)
sind die Bezeichner aufgeführt, die Sie für diesen Wert verwenden können. Um
beispielsweise anzugeben, dass du deine Crate mit der MIT-Lizenz lizenziert
hast, füge die MIT-Identifikation hinzu:
Dateiname: Cargo.toml
[package]
name = "guessing_game"
license = "MIT"
Wenn man eine Lizenz verwenden möchte, die nicht in SPDX angezeigt wird, muss
man den Text dieser Lizenz in eine Datei einfügen, die Datei in das Projekt
aufnehmen und dann den Dateinamen unter license-file angeben, anstelle der
Verwendung des license-Schlüssels.
Die Anleitung, welche Lizenz für dein Projekt geeignet ist, geht über den
Rahmen dieses Buches hinaus. Viele Leute in der Rust-Gemeinschaft lizenzieren
ihre Projekte genauso wie Rust mit einer Doppellizenz von MIT OR Apache-2.0.
Diese Übung zeigt, dass man durch OR auch mehrere Lizenzkennungen getrennt
angeben kann, um mehrere Lizenzen für ein Projekt zu haben.
Mit einem eindeutigen Namen, der Version, deiner Beschreibung und einer hinzugefügten Lizenz könnte die Datei Cargo.toml für ein Projekt, das zur Veröffentlichung bereit ist, folgendermaßen aussehen:
Dateiname: 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]
Die Cargo-Documentation beschreibt andere Metadaten, die du angeben kannst, um sicherzustellen, dass andere deine Crate leichter entdecken und verwenden können.
Veröffentlichen auf crates.io
Nachdem man einen Account erstellt, den API-Token gespeichert, einen Namen für seine Crate ausgewählt und die erforderlichen Metadaten angegeben hat, kann man sie veröffentlichen! Durch das Veröffentlichen einer Crate wird eine bestimmte Version auf crates.io hochgeladen, damit andere sie verwenden können.
Sei vorsichtig, da eine Veröffentlichung dauerhaft ist. Die Version kann niemals überschrieben und der Programmcode nur in speziellen Fällen gelöscht werden. Ein Hauptziel von crates.io ist es, als permanentes Archiv von Code zu fungieren, sodass alle Projekte, die erstellt werden und von Crates aus crates.io abhängen, weiter funktionieren werden. Das Zulassen von Versionslöschungen würde das Erreichen dieses Ziels unmöglich machen. Die Anzahl der Crate-Versionen, die man veröffentlichen kann, ist jedoch unbegrenzt.
Rufe cargo publish erneut auf. Diesmal sollte es funktionieren:
$ 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`
Herzlichen Glückwunsch! Du hast deinen Programmcode nun für die Rust-Gemeinschaft freigegeben. Jeder kann deine Crate einfach als Abhängigkeit für sein Projekt hinzufügen.
Veröffentlichen einer neuen Version einer vorhandenen Crate
Wenn du Änderungen an deiner Crate vorgenommen hast und eine neue Version
veröffentlichen möchtest, passt du den in deiner Cargo.toml angegebenen
Versionswert an und veröffentlichst erneut. Entscheide anhand der Regeln für
die semantische Versionierung, welche nächste Versionsnummer angemessen
ist. Führe anschließend cargo publish aus, um die neue Version hochzuladen.
Versionen auf crates.io als veraltet kennzeichnen
Obwohl man frühere Versionen einer Crate nicht entfernen kann, kann man verhindern, dass zukünftige Projekte sie als neue Abhängigkeit hinzufügen. Dies ist nützlich, wenn eine Crate-Version aus dem einen oder anderen Grund defekt ist. In solchen Situationen unterstützt Cargo das Herausziehen (yanking) einer Crate-Version.
Durch das Herausziehen einer Version wird verhindert, dass neue Projekte von dieser Version abhängen, während alle vorhandenen Projekte, die davon abhängen, weiterhin heruntergeladen werden können. Im Wesentlichen bedeutet Herausziehen (yank), dass alle Projekte mit einem Cargo.lock nicht kaputt gehen und zukünftige generierte Cargo.lock-Dateien nicht die herausgezogene Version verwenden.
Um eine Version einer Crate herauszuziehen, rufe cargo yank auf und
spezifiziere welche Version du herausziehen möchtest. Wenn wir zum Beispiel eine
Crate mit dem Namen guessing_game in Version 1.0.1 veröffentlicht haben und
sie herausziehen wollen, würden wir im Projektverzeichnis für guessing_game
Folgendes ausführen:
$ cargo yank --vers 1.0.1
Updating crates.io index
Yank guessing_game@1.0.1
Durch Hinzufügen von --undo kann man das Herausziehen rückgängig machen und
Projekten wieder erlauben von der Version abzuhängen:
$ cargo yank --vers 1.0.1 --undo
Updating crates.io index
Unyank guessing_game@1.0.1
Das Herausziehen löscht keinen Programmcode. Es kann zum Beispiel keine versehentlich hochgeladenen Geheimnisse löschen. Falls das passiert sein sollte, musst du diese Geheimnisse sofort zurücksetzen.