]> git.proxmox.com Git - rustc.git/blame - src/doc/book/src/ch14-02-publishing-to-crates-io.md
New upstream version 1.52.0~beta.3+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
9Rust and Cargo have features that help make your published package easier for
10people to use and to find in the first place. We’ll talk about some of these
11features next and then explain how to publish a package.
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
27for an `add_one` function in a crate named `my_crate`:
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
74good checklist to remind you of the aspects of your code that people calling
75your code will be interested in knowing about.
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
108Another style of doc comment, `//!`, adds documentation to the item that
109contains the comments rather than adding documentation to the items following
110the comments. We typically use these doc comments inside the crate root file
111(*src/lib.rs* by convention) or inside a module to document the crate or the
112module as a whole.
113
114For example, if we want to add documentation that describes the purpose of the
115`my_crate` crate that contains the `add_one` function, we can add documentation
116comments that start with `//!` to the beginning of the *src/lib.rs* file, as
117shown in Listing 14-2:
118
119<span class="filename">Filename: src/lib.rs</span>
120
121```rust,ignore
74b04a01 122{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-02/src/lib.rs:here}}
13cf67c4
XL
123```
124
125<span class="caption">Listing 14-2: Documentation for the `my_crate` crate as a
126whole</span>
127
128Notice there isn’t any code after the last line that begins with `//!`. Because
129we started the comments with `//!` instead of `///`, we’re documenting the item
130that contains this comment rather than an item that follows this comment. In
131this case, the item that contains this comment is the *src/lib.rs* file, which
132is the crate root. These comments describe the entire crate.
133
134When we run `cargo doc --open`, these comments will display on the front
135page of the documentation for `my_crate` above the list of public items in the
136crate, as shown in Figure 14-2:
137
138<img alt="Rendered HTML documentation with a comment for the crate as a whole" src="img/trpl14-02.png" class="center" />
139
140<span class="caption">Figure 14-2: Rendered documentation for `my_crate`,
141including the comment describing the crate as a whole</span>
142
143Documentation comments within items are useful for describing crates and
144modules especially. Use them to explain the overall purpose of the container to
145help your users understand the crate’s organization.
146
147### Exporting a Convenient Public API with `pub use`
148
149In Chapter 7, we covered how to organize our code into modules using the `mod`
150keyword, how to make items public using the `pub` keyword, and how to bring
151items into a scope with the `use` keyword. However, the structure that makes
152sense to you while you’re developing a crate might not be very convenient for
153your users. You might want to organize your structs in a hierarchy containing
154multiple levels, but then people who want to use a type you’ve defined deep in
155the hierarchy might have trouble finding out that type exists. They might also
156be annoyed at having to enter `use`
157`my_crate::some_module::another_module::UsefulType;` rather than `use`
158`my_crate::UsefulType;`.
159
160The structure of your public API is a major consideration when publishing a
161crate. People who use your crate are less familiar with the structure than you
162are and might have difficulty finding the pieces they want to use if your crate
163has a large module hierarchy.
164
165The good news is that if the structure *isn’t* convenient for others to use
166from another library, you don’t have to rearrange your internal organization:
167instead, you can re-export items to make a public structure that’s different
168from your private structure by using `pub use`. Re-exporting takes a public
169item in one location and makes it public in another location, as if it were
170defined in the other location instead.
171
172For example, say we made a library named `art` for modeling artistic concepts.
173Within this library are two modules: a `kinds` module containing two enums
174named `PrimaryColor` and `SecondaryColor` and a `utils` module containing a
175function named `mix`, as shown in Listing 14-3:
176
177<span class="filename">Filename: src/lib.rs</span>
178
fc512014
XL
179```rust,noplayground,test_harness
180{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-03/src/lib.rs}}
13cf67c4
XL
181```
182
183<span class="caption">Listing 14-3: An `art` library with items organized into
184`kinds` and `utils` modules</span>
185
186Figure 14-3 shows what the front page of the documentation for this crate
187generated by `cargo doc` would look like:
188
189<img alt="Rendered documentation for the `art` crate that lists the `kinds` and `utils` modules" src="img/trpl14-03.png" class="center" />
190
191<span class="caption">Figure 14-3: Front page of the documentation for `art`
192that lists the `kinds` and `utils` modules</span>
193
194Note that the `PrimaryColor` and `SecondaryColor` types aren’t listed on the
195front page, nor is the `mix` function. We have to click `kinds` and `utils` to
196see them.
197
198Another crate that depends on this library would need `use` statements that
199bring the items from `art` into scope, specifying the module structure that’s
200currently defined. Listing 14-4 shows an example of a crate that uses the
201`PrimaryColor` and `mix` items from the `art` crate:
202
203<span class="filename">Filename: src/main.rs</span>
204
205```rust,ignore
74b04a01 206{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-04/src/main.rs}}
13cf67c4
XL
207```
208
209<span class="caption">Listing 14-4: A crate using the `art` crate’s items with
210its internal structure exported</span>
211
212The author of the code in Listing 14-4, which uses the `art` crate, had to
213figure out that `PrimaryColor` is in the `kinds` module and `mix` is in the
214`utils` module. The module structure of the `art` crate is more relevant to
215developers working on the `art` crate than to developers using the `art` crate.
216The internal structure that organizes parts of the crate into the `kinds`
217module and the `utils` module doesn’t contain any useful information for
218someone trying to understand how to use the `art` crate. Instead, the `art`
219crate’s module structure causes confusion because developers have to figure out
220where to look, and the structure is inconvenient because developers must
221specify the module names in the `use` statements.
222
223To remove the internal organization from the public API, we can modify the
224`art` crate code in Listing 14-3 to add `pub use` statements to re-export the
225items at the top level, as shown in Listing 14-5:
226
227<span class="filename">Filename: src/lib.rs</span>
228
229```rust,ignore
74b04a01 230{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-05/src/lib.rs:here}}
13cf67c4
XL
231```
232
233<span class="caption">Listing 14-5: Adding `pub use` statements to re-export
234items</span>
235
236The API documentation that `cargo doc` generates for this crate will now list
237and link re-exports on the front page, as shown in Figure 14-4, making the
238`PrimaryColor` and `SecondaryColor` types and the `mix` function easier to find.
239
240<img alt="Rendered documentation for the `art` crate with the re-exports on the front page" src="img/trpl14-04.png" class="center" />
241
242<span class="caption">Figure 14-4: The front page of the documentation for `art`
243that lists the re-exports</span>
244
245The `art` crate users can still see and use the internal structure from Listing
24614-3 as demonstrated in Listing 14-4, or they can use the more convenient
247structure in Listing 14-5, as shown in Listing 14-6:
248
249<span class="filename">Filename: src/main.rs</span>
250
251```rust,ignore
74b04a01 252{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-06/src/main.rs:here}}
13cf67c4
XL
253```
254
255<span class="caption">Listing 14-6: A program using the re-exported items from
256the `art` crate</span>
257
258In cases where there are many nested modules, re-exporting the types at the top
259level with `pub use` can make a significant difference in the experience of
260people who use the crate.
261
262Creating a useful public API structure is more of an art than a science, and
263you can iterate to find the API that works best for your users. Choosing `pub
264use` gives you flexibility in how you structure your crate internally and
265decouples that internal structure from what you present to your users. Look at
266some of the code of crates you’ve installed to see if their internal structure
267differs from their public API.
268
269### Setting Up a Crates.io Account
270
271Before you can publish any crates, you need to create an account on
dc9dc135
XL
272[crates.io](https://crates.io/)<!-- ignore --> and get an API token. To do so,
273visit the home page at [crates.io](https://crates.io/)<!-- ignore --> and log in
13cf67c4
XL
274via a GitHub account. (The GitHub account is currently a requirement, but the
275site might support other ways of creating an account in the future.) Once
276you’re logged in, visit your account settings at
277[https://crates.io/me/](https://crates.io/me/)<!-- ignore --> and retrieve your
278API key. Then run the `cargo login` command with your API key, like this:
279
f035d41b 280```console
13cf67c4
XL
281$ cargo login abcdefghijklmnopqrstuvwxyz012345
282```
283
284This command will inform Cargo of your API token and store it locally in
285*~/.cargo/credentials*. Note that this token is a *secret*: do not share it
286with anyone else. If you do share it with anyone for any reason, you should
dc9dc135 287revoke it and generate a new token on [crates.io](https://crates.io/)<!-- ignore
13cf67c4
XL
288-->.
289
290### Adding Metadata to a New Crate
291
292Now that you have an account, let’s say you have a crate you want to publish.
293Before publishing, you’ll need to add some metadata to your crate by adding it
294to the `[package]` section of the crate’s *Cargo.toml* file.
295
296Your crate will need a unique name. While you’re working on a crate locally,
297you can name a crate whatever you’d like. However, crate names on
dc9dc135 298[crates.io](https://crates.io/)<!-- ignore --> are allocated on a first-come,
13cf67c4 299first-served basis. Once a crate name is taken, no one else can publish a crate
9fa01778
XL
300with that name. Before attempting to publish a crate, search for the name you
301want to use on the site. If the name has been used by another crate, you will
302need to find another name and edit the `name` field in the *Cargo.toml* file
303under the `[package]` section to use the new name for publishing, like so:
13cf67c4
XL
304
305<span class="filename">Filename: Cargo.toml</span>
306
307```toml
308[package]
309name = "guessing_game"
310```
311
312Even if you’ve chosen a unique name, when you run `cargo publish` to publish
313the crate at this point, you’ll get a warning and then an error:
314
74b04a01
XL
315<!-- manual-regeneration
316cd listings/ch14-more-about-cargo/listing-14-01/
317cargo publish
318copy just the relevant lines below
319-->
320
f035d41b 321```console
13cf67c4 322$ cargo publish
74b04a01
XL
323 Updating crates.io index
324warning: manifest has no description, license, license-file, documentation, homepage or repository.
325See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
13cf67c4 326--snip--
74b04a01 327error: api errors (status 200 OK): 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
328```
329
330The reason is that you’re missing some crucial information: a description and
331license are required so people will know what your crate does and under what
332terms they can use it. To rectify this error, you need to include this
333information in the *Cargo.toml* file.
334
335Add a description that is just a sentence or two, because it will appear with
336your crate in search results. For the `license` field, you need to give a
337*license identifier value*. The [Linux Foundation’s Software Package Data
338Exchange (SPDX)][spdx] lists the identifiers you can use for this value. For
339example, to specify that you’ve licensed your crate using the MIT License, add
340the `MIT` identifier:
341
342[spdx]: http://spdx.org/licenses/
343
344<span class="filename">Filename: Cargo.toml</span>
345
346```toml
347[package]
348name = "guessing_game"
349license = "MIT"
350```
351
352If you want to use a license that doesn’t appear in the SPDX, you need to place
353the text of that license in a file, include the file in your project, and then
354use `license-file` to specify the name of that file instead of using the
355`license` key.
356
357Guidance on which license is appropriate for your project is beyond the scope
358of this book. Many people in the Rust community license their projects in the
359same way as Rust by using a dual license of `MIT OR Apache-2.0`. This practice
360demonstrates that you can also specify multiple license identifiers separated
361by `OR` to have multiple licenses for your project.
362
363With a unique name, the version, the author details that `cargo new` added
364when you created the crate, your description, and a license added, the
365*Cargo.toml* file for a project that is ready to publish might look like this:
366
367<span class="filename">Filename: Cargo.toml</span>
368
369```toml
370[package]
371name = "guessing_game"
372version = "0.1.0"
373authors = ["Your Name <you@example.com>"]
69743fb6 374edition = "2018"
13cf67c4
XL
375description = "A fun game where you guess what number the computer has chosen."
376license = "MIT OR Apache-2.0"
377
378[dependencies]
379```
380
381[Cargo’s documentation](https://doc.rust-lang.org/cargo/) describes other
382metadata you can specify to ensure others can discover and use your crate more
383easily.
384
385### Publishing to Crates.io
386
387Now that you’ve created an account, saved your API token, chosen a name for
388your crate, and specified the required metadata, you’re ready to publish!
389Publishing a crate uploads a specific version to
dc9dc135 390[crates.io](https://crates.io/)<!-- ignore --> for others to use.
13cf67c4
XL
391
392Be careful when publishing a crate because a publish is *permanent*. The
393version can never be overwritten, and the code cannot be deleted. One major
dc9dc135 394goal of [crates.io](https://crates.io/)<!-- ignore --> is to act as a permanent
13cf67c4 395archive of code so that builds of all projects that depend on crates from
dc9dc135 396[crates.io](https://crates.io/)<!-- ignore --> will continue to work. Allowing
13cf67c4
XL
397version deletions would make fulfilling that goal impossible. However, there is
398no limit to the number of crate versions you can publish.
399
400Run the `cargo publish` command again. It should succeed now:
401
74b04a01
XL
402<!-- manual-regeneration
403go to some valid crate, publish a new version
404cargo publish
405copy just the relevant lines below
406-->
407
f035d41b 408```console
13cf67c4 409$ cargo publish
74b04a01
XL
410 Updating crates.io index
411 Packaging guessing_game v0.1.0 (file:///projects/guessing_game)
412 Verifying guessing_game v0.1.0 (file:///projects/guessing_game)
413 Compiling guessing_game v0.1.0
13cf67c4 414(file:///projects/guessing_game/target/package/guessing_game-0.1.0)
74b04a01
XL
415 Finished dev [unoptimized + debuginfo] target(s) in 0.19s
416 Uploading guessing_game v0.1.0 (file:///projects/guessing_game)
13cf67c4
XL
417```
418
419Congratulations! You’ve now shared your code with the Rust community, and
420anyone can easily add your crate as a dependency of their project.
421
422### Publishing a New Version of an Existing Crate
423
424When you’ve made changes to your crate and are ready to release a new version,
425you change the `version` value specified in your *Cargo.toml* file and
426republish. Use the [Semantic Versioning rules][semver] to decide what an
427appropriate next version number is based on the kinds of changes you’ve made.
428Then run `cargo publish` to upload the new version.
429
430[semver]: http://semver.org/
431
432### Removing Versions from Crates.io with `cargo yank`
433
434Although you can’t remove previous versions of a crate, you can prevent any
435future projects from adding them as a new dependency. This is useful when a
436crate version is broken for one reason or another. In such situations, Cargo
437supports *yanking* a crate version.
438
439Yanking a version prevents new projects from starting to depend on that version
440while allowing all existing projects that depend on it to continue to download
441and depend on that version. Essentially, a yank means that all projects with a
442*Cargo.lock* will not break, and any future *Cargo.lock* files generated will
443not use the yanked version.
444
445To yank a version of a crate, run `cargo yank` and specify which version you
446want to yank:
447
f035d41b 448```console
13cf67c4
XL
449$ cargo yank --vers 1.0.1
450```
451
452By adding `--undo` to the command, you can also undo a yank and allow projects
453to start depending on a version again:
454
f035d41b 455```console
13cf67c4
XL
456$ cargo yank --vers 1.0.1 --undo
457```
458
459A yank *does not* delete any code. For example, the yank feature is not
460intended for deleting accidentally uploaded secrets. If that happens, you must
461reset those secrets immediately.