]> git.proxmox.com Git - rustc.git/blame - src/doc/book/src/ch14-02-publishing-to-crates-io.md
New upstream version 1.63.0+dfsg1
[rustc.git] / src / doc / book / src / ch14-02-publishing-to-crates-io.md
CommitLineData
13cf67c4
XL
1## Publishing a Crate to Crates.io
2
dc9dc135 3We’ve used packages from [crates.io](https://crates.io/)<!-- ignore --> as
13cf67c4
XL
4dependencies of our project, but you can also share your code with other people
5by publishing your own packages. The crate registry at
dc9dc135 6[crates.io](https://crates.io/)<!-- ignore --> distributes the source code of
13cf67c4
XL
7your packages, so it primarily hosts code that is open source.
8
04454e1e
FG
9Rust and Cargo have features that make your published package easier for people
10to find and use. We’ll talk about some of these features next and then explain
11how to publish a package.
13cf67c4
XL
12
13### Making Useful Documentation Comments
14
15Accurately documenting your packages will help other users know how and when to
16use them, so it’s worth investing the time to write documentation. In Chapter
173, we discussed how to comment Rust code using two slashes, `//`. Rust also has
18a particular kind of comment for documentation, known conveniently as a
19*documentation comment*, that will generate HTML documentation. The HTML
20displays the contents of documentation comments for public API items intended
21for programmers interested in knowing how to *use* your crate as opposed to how
22your crate is *implemented*.
23
24Documentation comments use three slashes, `///`, instead of two and support
25Markdown notation for formatting the text. Place documentation comments just
26before the item they’re documenting. Listing 14-1 shows documentation comments
5099ac24 27for an `add_one` function in a crate named `my_crate`.
13cf67c4
XL
28
29<span class="filename">Filename: src/lib.rs</span>
30
31```rust,ignore
74b04a01 32{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-01/src/lib.rs}}
13cf67c4
XL
33```
34
35<span class="caption">Listing 14-1: A documentation comment for a
36function</span>
37
38Here, we give a description of what the `add_one` function does, start a
39section with the heading `Examples`, and then provide code that demonstrates
40how to use the `add_one` function. We can generate the HTML documentation from
41this documentation comment by running `cargo doc`. This command runs the
42`rustdoc` tool distributed with Rust and puts the generated HTML documentation
43in the *target/doc* directory.
44
45For convenience, running `cargo doc --open` will build the HTML for your
46current crate’s documentation (as well as the documentation for all of your
47crate’s dependencies) and open the result in a web browser. Navigate to the
48`add_one` function and you’ll see how the text in the documentation comments is
49rendered, as shown in Figure 14-1:
50
51<img alt="Rendered HTML documentation for the `add_one` function of `my_crate`" src="img/trpl14-01.png" class="center" />
52
53<span class="caption">Figure 14-1: HTML documentation for the `add_one`
54function</span>
55
56#### Commonly Used Sections
57
58We used the `# Examples` Markdown heading in Listing 14-1 to create a section
59in the HTML with the title “Examples.” Here are some other sections that crate
60authors commonly use in their documentation:
61
62* **Panics**: The scenarios in which the function being documented could
63 panic. Callers of the function who don’t want their programs to panic should
64 make sure they don’t call the function in these situations.
65* **Errors**: If the function returns a `Result`, describing the kinds of
66 errors that might occur and what conditions might cause those errors to be
67 returned can be helpful to callers so they can write code to handle the
68 different kinds of errors in different ways.
69* **Safety**: If the function is `unsafe` to call (we discuss unsafety in
70 Chapter 19), there should be a section explaining why the function is unsafe
71 and covering the invariants that the function expects callers to uphold.
72
73Most documentation comments don’t need all of these sections, but this is a
04454e1e
FG
74good checklist to remind you of the aspects of your code users will be
75interested in knowing about.
13cf67c4
XL
76
77#### Documentation Comments as Tests
78
79Adding example code blocks in your documentation comments can help demonstrate
80how to use your library, and doing so has an additional bonus: running `cargo
81test` will run the code examples in your documentation as tests! Nothing is
82better than documentation with examples. But nothing is worse than examples
83that don’t work because the code has changed since the documentation was
84written. If we run `cargo test` with the documentation for the `add_one`
85function from Listing 14-1, we will see a section in the test results like this:
86
74b04a01
XL
87<!-- manual-regeneration
88cd listings/ch14-more-about-cargo/listing-14-01/
89cargo test
90copy just the doc-tests section below
91-->
92
13cf67c4
XL
93```text
94 Doc-tests my_crate
95
96running 1 test
97test src/lib.rs - add_one (line 5) ... ok
98
6a06907d 99test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.27s
13cf67c4
XL
100```
101
102Now if we change either the function or the example so the `assert_eq!` in the
103example panics and run `cargo test` again, we’ll see that the doc tests catch
104that the example and the code are out of sync with each other!
105
106#### Commenting Contained Items
107
04454e1e
FG
108The style of doc comment `//!` adds documentation to the item that contains the
109comments rather than to the items following the comments. We typically use
110these doc comments inside the crate root file (*src/lib.rs* by convention) or
111inside a module to document the crate or the module as a whole.
13cf67c4 112
04454e1e
FG
113For example, to add documentation that describes the purpose of the `my_crate`
114crate that contains the `add_one` function, we add documentation comments that
115start with `//!` to the beginning of the *src/lib.rs* file, as shown in Listing
11614-2:
13cf67c4
XL
117
118<span class="filename">Filename: src/lib.rs</span>
119
120```rust,ignore
74b04a01 121{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-02/src/lib.rs:here}}
13cf67c4
XL
122```
123
124<span class="caption">Listing 14-2: Documentation for the `my_crate` crate as a
125whole</span>
126
127Notice there isn’t any code after the last line that begins with `//!`. Because
128we started the comments with `//!` instead of `///`, we’re documenting the item
129that contains this comment rather than an item that follows this comment. In
04454e1e
FG
130this case, that item is the *src/lib.rs* file, which is the crate root. These
131comments describe the entire crate.
13cf67c4
XL
132
133When we run `cargo doc --open`, these comments will display on the front
134page of the documentation for `my_crate` above the list of public items in the
135crate, as shown in Figure 14-2:
136
137<img alt="Rendered HTML documentation with a comment for the crate as a whole" src="img/trpl14-02.png" class="center" />
138
139<span class="caption">Figure 14-2: Rendered documentation for `my_crate`,
140including the comment describing the crate as a whole</span>
141
142Documentation comments within items are useful for describing crates and
143modules especially. Use them to explain the overall purpose of the container to
144help your users understand the crate’s organization.
145
146### Exporting a Convenient Public API with `pub use`
147
13cf67c4
XL
148The structure of your public API is a major consideration when publishing a
149crate. People who use your crate are less familiar with the structure than you
150are and might have difficulty finding the pieces they want to use if your crate
151has a large module hierarchy.
152
04454e1e
FG
153In Chapter 7, we covered how to make items public using the `pub` keyword, and
154bring items into a scope with the `use` keyword. However, the structure that
155makes sense to you while you’re developing a crate might not be very convenient
156for your users. You might want to organize your structs in a hierarchy
157containing multiple levels, but then people who want to use a type you’ve
158defined deep in the hierarchy might have trouble finding out that type exists.
159They might also be annoyed at having to enter `use`
160`my_crate::some_module::another_module::UsefulType;` rather than `use`
161`my_crate::UsefulType;`.
162
13cf67c4
XL
163The good news is that if the structure *isn’t* convenient for others to use
164from another library, you don’t have to rearrange your internal organization:
165instead, you can re-export items to make a public structure that’s different
166from your private structure by using `pub use`. Re-exporting takes a public
167item in one location and makes it public in another location, as if it were
168defined in the other location instead.
169
170For example, say we made a library named `art` for modeling artistic concepts.
171Within this library are two modules: a `kinds` module containing two enums
172named `PrimaryColor` and `SecondaryColor` and a `utils` module containing a
173function named `mix`, as shown in Listing 14-3:
174
175<span class="filename">Filename: src/lib.rs</span>
176
fc512014 177```rust,noplayground,test_harness
136023e0 178{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-03/src/lib.rs:here}}
13cf67c4
XL
179```
180
181<span class="caption">Listing 14-3: An `art` library with items organized into
182`kinds` and `utils` modules</span>
183
184Figure 14-3 shows what the front page of the documentation for this crate
185generated by `cargo doc` would look like:
186
187<img alt="Rendered documentation for the `art` crate that lists the `kinds` and `utils` modules" src="img/trpl14-03.png" class="center" />
188
189<span class="caption">Figure 14-3: Front page of the documentation for `art`
190that lists the `kinds` and `utils` modules</span>
191
192Note that the `PrimaryColor` and `SecondaryColor` types aren’t listed on the
193front page, nor is the `mix` function. We have to click `kinds` and `utils` to
194see them.
195
196Another crate that depends on this library would need `use` statements that
197bring the items from `art` into scope, specifying the module structure that’s
198currently defined. Listing 14-4 shows an example of a crate that uses the
199`PrimaryColor` and `mix` items from the `art` crate:
200
201<span class="filename">Filename: src/main.rs</span>
202
203```rust,ignore
74b04a01 204{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-04/src/main.rs}}
13cf67c4
XL
205```
206
207<span class="caption">Listing 14-4: A crate using the `art` crate’s items with
208its internal structure exported</span>
209
210The author of the code in Listing 14-4, which uses the `art` crate, had to
211figure out that `PrimaryColor` is in the `kinds` module and `mix` is in the
212`utils` module. The module structure of the `art` crate is more relevant to
04454e1e
FG
213developers working on the `art` crate than to those using it. The internal
214structure doesn’t contain any useful information for someone trying to
215understand how to use the `art` crate, but rather causes confusion because
216developers who use it have to figure out where to look, and must specify the
217module names in the `use` statements.
13cf67c4
XL
218
219To remove the internal organization from the public API, we can modify the
220`art` crate code in Listing 14-3 to add `pub use` statements to re-export the
221items at the top level, as shown in Listing 14-5:
222
223<span class="filename">Filename: src/lib.rs</span>
224
225```rust,ignore
74b04a01 226{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-05/src/lib.rs:here}}
13cf67c4
XL
227```
228
229<span class="caption">Listing 14-5: Adding `pub use` statements to re-export
230items</span>
231
232The API documentation that `cargo doc` generates for this crate will now list
233and link re-exports on the front page, as shown in Figure 14-4, making the
234`PrimaryColor` and `SecondaryColor` types and the `mix` function easier to find.
235
236<img alt="Rendered documentation for the `art` crate with the re-exports on the front page" src="img/trpl14-04.png" class="center" />
237
238<span class="caption">Figure 14-4: The front page of the documentation for `art`
239that lists the re-exports</span>
240
241The `art` crate users can still see and use the internal structure from Listing
24214-3 as demonstrated in Listing 14-4, or they can use the more convenient
243structure in Listing 14-5, as shown in Listing 14-6:
244
245<span class="filename">Filename: src/main.rs</span>
246
247```rust,ignore
74b04a01 248{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-06/src/main.rs:here}}
13cf67c4
XL
249```
250
251<span class="caption">Listing 14-6: A program using the re-exported items from
252the `art` crate</span>
253
254In cases where there are many nested modules, re-exporting the types at the top
255level with `pub use` can make a significant difference in the experience of
923072b8
FG
256people who use the crate. Another common use of `pub use` is to re-export
257definitions of a dependency in the current crate to make that crate's
258definitions part of your crate’s public API.
13cf67c4
XL
259
260Creating a useful public API structure is more of an art than a science, and
261you can iterate to find the API that works best for your users. Choosing `pub
262use` gives you flexibility in how you structure your crate internally and
263decouples that internal structure from what you present to your users. Look at
264some of the code of crates you’ve installed to see if their internal structure
265differs from their public API.
266
267### Setting Up a Crates.io Account
268
269Before you can publish any crates, you need to create an account on
dc9dc135 270[crates.io](https://crates.io/)<!-- ignore --> and get an API token. To do so,
04454e1e
FG
271visit the home page at [crates.io](https://crates.io/)<!-- ignore --> and log
272in via a GitHub account. (The GitHub account is currently a requirement, but
273the site might support other ways of creating an account in the future.) Once
13cf67c4
XL
274you’re logged in, visit your account settings at
275[https://crates.io/me/](https://crates.io/me/)<!-- ignore --> and retrieve your
276API key. Then run the `cargo login` command with your API key, like this:
277
f035d41b 278```console
13cf67c4
XL
279$ cargo login abcdefghijklmnopqrstuvwxyz012345
280```
281
282This command will inform Cargo of your API token and store it locally in
283*~/.cargo/credentials*. Note that this token is a *secret*: do not share it
284with anyone else. If you do share it with anyone for any reason, you should
dc9dc135 285revoke it and generate a new token on [crates.io](https://crates.io/)<!-- ignore
13cf67c4
XL
286-->.
287
288### Adding Metadata to a New Crate
289
04454e1e
FG
290Let’s say you have a crate you want to publish. Before publishing, you’ll need
291to add some metadata in the `[package]` section of the crate’s *Cargo.toml*
292file.
13cf67c4
XL
293
294Your crate will need a unique name. While you’re working on a crate locally,
295you can name a crate whatever you’d like. However, crate names on
dc9dc135 296[crates.io](https://crates.io/)<!-- ignore --> are allocated on a first-come,
13cf67c4 297first-served basis. Once a crate name is taken, no one else can publish a crate
9fa01778 298with that name. Before attempting to publish a crate, search for the name you
04454e1e
FG
299want to use. If the name has been used, you will need to find another name and
300edit the `name` field in the *Cargo.toml* file under the `[package]` section to
301use the new name for publishing, like so:
13cf67c4
XL
302
303<span class="filename">Filename: Cargo.toml</span>
304
305```toml
306[package]
307name = "guessing_game"
308```
309
310Even if you’ve chosen a unique name, when you run `cargo publish` to publish
311the crate at this point, you’ll get a warning and then an error:
312
74b04a01
XL
313<!-- manual-regeneration
314cd listings/ch14-more-about-cargo/listing-14-01/
315cargo publish
316copy just the relevant lines below
317-->
318
f035d41b 319```console
13cf67c4 320$ cargo publish
74b04a01
XL
321 Updating crates.io index
322warning: manifest has no description, license, license-file, documentation, homepage or repository.
323See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
13cf67c4 324--snip--
5099ac24
FG
325error: failed to publish to registry at https://crates.io
326
327Caused by:
328 the remote server responded with an error: missing or empty metadata fields: description, license. Please see https://doc.rust-lang.org/cargo/reference/manifest.html for how to upload metadata
13cf67c4
XL
329```
330
04454e1e 331This errors because you’re missing some crucial information: a description and
13cf67c4 332license are required so people will know what your crate does and under what
04454e1e
FG
333terms they can use it. In *Cargo.toml*, add a description that's just a
334sentence or two, because it will appear with your crate in search results. For
335the `license` field, you need to give a *license identifier value*. The [Linux
336Foundation’s Software Package Data Exchange (SPDX)][spdx] lists the identifiers
337you can use for this value. For example, to specify that you’ve licensed your
338crate using the MIT License, add the `MIT` identifier:
13cf67c4
XL
339
340<span class="filename">Filename: Cargo.toml</span>
341
342```toml
343[package]
344name = "guessing_game"
345license = "MIT"
346```
347
348If you want to use a license that doesn’t appear in the SPDX, you need to place
349the text of that license in a file, include the file in your project, and then
350use `license-file` to specify the name of that file instead of using the
351`license` key.
352
353Guidance on which license is appropriate for your project is beyond the scope
354of this book. Many people in the Rust community license their projects in the
355same way as Rust by using a dual license of `MIT OR Apache-2.0`. This practice
356demonstrates that you can also specify multiple license identifiers separated
357by `OR` to have multiple licenses for your project.
358
136023e0 359With a unique name, the version, your description, and a license added, the
13cf67c4
XL
360*Cargo.toml* file for a project that is ready to publish might look like this:
361
362<span class="filename">Filename: Cargo.toml</span>
363
364```toml
365[package]
366name = "guessing_game"
367version = "0.1.0"
a2a8927a 368edition = "2021"
13cf67c4
XL
369description = "A fun game where you guess what number the computer has chosen."
370license = "MIT OR Apache-2.0"
371
372[dependencies]
373```
374
375[Cargo’s documentation](https://doc.rust-lang.org/cargo/) describes other
376metadata you can specify to ensure others can discover and use your crate more
377easily.
378
379### Publishing to Crates.io
380
381Now that you’ve created an account, saved your API token, chosen a name for
382your crate, and specified the required metadata, you’re ready to publish!
383Publishing a crate uploads a specific version to
dc9dc135 384[crates.io](https://crates.io/)<!-- ignore --> for others to use.
13cf67c4 385
04454e1e
FG
386Be careful, because a publish is *permanent*. The version can never be
387overwritten, and the code cannot be deleted. One major goal of
388[crates.io](https://crates.io/)<!-- ignore --> is to act as a permanent archive
389of code so that builds of all projects that depend on crates from
dc9dc135 390[crates.io](https://crates.io/)<!-- ignore --> will continue to work. Allowing
13cf67c4
XL
391version deletions would make fulfilling that goal impossible. However, there is
392no limit to the number of crate versions you can publish.
393
394Run the `cargo publish` command again. It should succeed now:
395
74b04a01
XL
396<!-- manual-regeneration
397go to some valid crate, publish a new version
398cargo publish
399copy just the relevant lines below
400-->
401
f035d41b 402```console
13cf67c4 403$ cargo publish
74b04a01
XL
404 Updating crates.io index
405 Packaging guessing_game v0.1.0 (file:///projects/guessing_game)
406 Verifying guessing_game v0.1.0 (file:///projects/guessing_game)
407 Compiling guessing_game v0.1.0
13cf67c4 408(file:///projects/guessing_game/target/package/guessing_game-0.1.0)
74b04a01
XL
409 Finished dev [unoptimized + debuginfo] target(s) in 0.19s
410 Uploading guessing_game v0.1.0 (file:///projects/guessing_game)
13cf67c4
XL
411```
412
413Congratulations! You’ve now shared your code with the Rust community, and
414anyone can easily add your crate as a dependency of their project.
415
416### Publishing a New Version of an Existing Crate
417
418When you’ve made changes to your crate and are ready to release a new version,
419you change the `version` value specified in your *Cargo.toml* file and
420republish. Use the [Semantic Versioning rules][semver] to decide what an
421appropriate next version number is based on the kinds of changes you’ve made.
422Then run `cargo publish` to upload the new version.
423
04454e1e
FG
424<!-- Old link, do not remove -->
425<a id="removing-versions-from-cratesio-with-cargo-yank"></a>
13cf67c4 426
04454e1e 427### Deprecating Versions from Crates.io with `cargo yank`
13cf67c4
XL
428
429Although you can’t remove previous versions of a crate, you can prevent any
430future projects from adding them as a new dependency. This is useful when a
431crate version is broken for one reason or another. In such situations, Cargo
432supports *yanking* a crate version.
433
04454e1e
FG
434Yanking a version prevents new projects from depending on that version while
435allowing all existing projects that depend on it to continue. Essentially, a
436yank means that all projects with a *Cargo.lock* will not break, and any future
437*Cargo.lock* files generated will not use the yanked version.
13cf67c4 438
04454e1e
FG
439To yank a version of a crate, in the directory of the crate that you’ve
440previously published, run `cargo yank` and specify which version you want to
923072b8
FG
441yank. For example, if we've published a crate named `guessing_game` version
4421.0.1 and we want to yank it, in the project directory for `guessing_game` we'd
443run:
13cf67c4 444
f035d41b 445```console
13cf67c4 446$ cargo yank --vers 1.0.1
923072b8
FG
447 Updating crates.io index
448 Yank guessing_game:1.0.1
13cf67c4
XL
449```
450
451By adding `--undo` to the command, you can also undo a yank and allow projects
452to start depending on a version again:
453
f035d41b 454```console
13cf67c4 455$ cargo yank --vers 1.0.1 --undo
923072b8
FG
456 Updating crates.io index
457 Unyank guessing_game_:1.0.1
13cf67c4
XL
458```
459
04454e1e
FG
460A yank *does not* delete any code. It cannot, for example, delete accidentally
461uploaded secrets. If that happens, you must reset those secrets immediately.
462
463[spdx]: http://spdx.org/licenses/
464[semver]: http://semver.org/