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