finished ch14.2

This commit is contained in:
darkicewolf50 2025-02-26 12:04:05 -07:00
parent 29f8753827
commit 43816205f3
5 changed files with 181 additions and 4 deletions

1
Cargo Workspaces.md Normal file
View File

@ -0,0 +1 @@
# Cargo Workspaces

View File

@ -7,7 +7,7 @@ Cargo can do so much more
This chapter will go over some more advanced features like:
- [Customize your build](./Custome%20Build%20Profiles.md) through release profiles
- [Publish libraries](./Publishing%20libraries.md) on [crates.io](https://crates.io/)
- Organize large projects with workspaces
- Organize large projects with [workspaces](./Cargo%20Workspaces.md)
- Install binaries from [crates.io](https://crates.io/)
- Extend Cargo using custom commands

View File

@ -274,4 +274,180 @@ Choosing `pub use` gives you flexibility in how you structure your crate interna
Look at some of the code of crates you have used previously to see if their internal struct differs from their public API.
## Setting Up a Crates.io Account
Before being able to create
Before being able to publish creates, you need an account on [crates.io](https://crates.io) and get an API toekn
You can do ths by
1. visit the homepage at [crates.io](https://crates.io)
2. Log in via a Github account (could use any other type that is supported)
3. Once logged in, go to your account settings at [https://crates.io/me/](https://crates.io/me/)
4. Retrieve your API key
5. Run the `cargo login` command nad paste the API key when prompted
Here is an example
```
$ cargo login
abcdefghijklmnopqrstuvwxyz012345
```
This will inform Cargo of your API token and store it locally in *~/.cargo/credentials*
Note that this tken is a *secret*. DO NOT SHARE IT
You can revoke it and generate a new token on [crate.io](https://crates.io) if you do accidentally share it.
## Adding Metadata to a New Crate
Lets say you gave a crate you want ot publish.
Before doing that you need to add some metadata in the `[package] section of the crate's *Cargo.toml* file.
You need a unqiue crate name.
When working locally you can name a crate anything you like.
However crate names on [crates.io](https://crates.io) are allocated on a first-come, first-serverd basis.
Once a crate name is taken, no one else can publish a crate with that same name.
SUPER GOOD ADVICE: Before attempting to publish a crate search for the name you want to use.
If the name has been used, you will need to find another name and edit the `name` field in the *Cargo.toml* file under the `[package]` section to use the new name for publishing.
Here is an example of this
```toml
[package]
name = "guessing_game"
```
Even if you chose a unqiue name when you run `cargo publish` to publish the crate at this point you will get a warning then an error.
Here is an example of this output
```
$ 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 field
```
These errors are caused by missing some crucial information:
- A description
- A license
Both of these are required so people will know what your crate does and under what terms they can use it.
In *Cargo.toml* add a description that that is a sentence or two. This will appear with your crate in search results.
For the `license` field you need to give a *license identifier value*
The [Linux Foundations Software Package Data Exchange (SPDX)](https://spdx.org/licenses/) lists identifers you can use for this value.
For example to specify that you are licensing your crate using the MIT License add the `MIT` identifier
```toml
[package]
name = "guessing_game"
license = "MIT"
```
If you want to use a license that isnt in te SPDX, you will need to plcae the text of that license in a file.
Include that file in your porject and then use `license-file` to specify the name of that file instead of using the `license` key.
Guidance on which license is appropriate for your project is a highly personal and higly techincal.
Please read through the license to pick the most approprate one for your case use with any considerations to dependances.
Many people in the Rust community license their projects in the same way as Rust by using a dual license of `MIT OR Apache-2.0`
This demonstrates that you can also specify multiple license identifiers separated by `OR` to have multiple licenses for your project.
With a unique name, the version, the description and a license added. The *Cargo.toml* file for a project that is ready to publish would look similar to this:
```toml
[package]
name = "guessing_game"
version = "0.1.0"
edition = "2021"
description = "A fun game where you guess what number the computer has chosen."
license = "MIT OR Apache-2.0"
[dependencies]
```
[Cargo's documentation](https://doc.rust-lang.org/cargo/) describes other metadata you can specify to ensure othes can discover and use your crate more easily.
## Publishing to Crates.io
Now that you have an account, cargo has saved your API otken, chosen a name for your crate and specified the required metadata. Yuo are ready to publish.
Publishing a crate uploads a specific version to [crates.io](https://crates.io) for others to use.
A Publish is *PERMANENT*.
The version can never be overwritten and the code cannot be deleted.
One major goal of [crates.io](https://crates.io) is to act as a permanent archive of code so that builds of all projects that depend on crates from [crates.io](https://crates.io) will continue to always work.
Allowing version deletions would make this goal impossible.
There is no limit to the number of crate versions you can publish.
If you run `cargo publish` again it should succeed now.
Here is the output now
```
$ cargo publish
Updating crates.io index
Packaging guessing_game v0.1.0 (file:///projects/guessing_game)
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)
```
This is a successful output and indicates you have successfully shared your code with the Rst community and now anyone can easily add your crate as a dependency of their project.
## Publishing a New Version of an Exisiting Crate
When you made changes to your crate and are ready to release a new version.
First you change the `version` value specified in your *Cargo.toml* file and republish.
Use [Semantic Versioning rules](http://semver.org/) to decide what an appropriate nexxt version based on the kinds of changes made.
Finally run `cargo publish` to upload a new version
### Deprecaitng Versions for mCrates.io with `cargo yank`
Even though you can remove previous versions of a crate, you can prevent any future projects fom adding them as a new dependency.
This is useful when a crate version is broken for some reason.
In such situations, Cargo supports *yanking* a crate version.
Yanking a version prevents new projects form depending on that version while allowing all exisitng projects to continue to depend on that version.
This essentially means a yank won't break any exisiting projects with a *Cargo.lock* with that version will not break. But any new *Cargo.lock* files generated will not be able to use the yanked version.
To yank a version of a create.
1. Go to the directory of the crate that has been previously publish.
2. Run `cargo yank` and specify which version to yank.
For example lets say we have published a create named `guessing_game` version 1.0.1 and we want to yank it.
In the project directory for the `guessing_game` crate we would run
```
$ cargo yank --vers 1.0.1
Updating crates.io index
Yank guessing_game@1.0.1
```
If we wanted to undo that we would add `--undo` to the command.
This would allow prjects to start depending on that version again
```
$ cargo yank --vers 1.0.1 --undo
Updating crates.io index
Unyank guessing_game@1.0.1
```
ONCE AGAIN NOTICE a yank does *NOT* delete any code.
If you accidentally uploaded secrets, you must reset those secrets immediately.

View File

@ -1 +1 @@
{"rustc_fingerprint":4305361489769004817,"outputs":{"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.85.0 (4d91de4e4 2025-02-17)\nbinary: rustc\ncommit-hash: 4d91de4e48198da2e33413efdcd9cd2cc0c46688\ncommit-date: 2025-02-17\nhost: x86_64-unknown-linux-gnu\nrelease: 1.85.0\nLLVM version: 19.1.7\n","stderr":""},"13331785392996375709":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/brock/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}}
{"rustc_fingerprint":4305361489769004817,"outputs":{"2063776225603076451":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/brock/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""},"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.85.0 (4d91de4e4 2025-02-17)\nbinary: rustc\ncommit-hash: 4d91de4e48198da2e33413efdcd9cd2cc0c46688\ncommit-date: 2025-02-17\nhost: x86_64-unknown-linux-gnu\nrelease: 1.85.0\nLLVM version: 19.1.7\n","stderr":""},"13331785392996375709":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/brock/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}}

View File

@ -1 +1 @@
{"rustc_fingerprint":4305361489769004817,"outputs":{"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.85.0 (4d91de4e4 2025-02-17)\nbinary: rustc\ncommit-hash: 4d91de4e48198da2e33413efdcd9cd2cc0c46688\ncommit-date: 2025-02-17\nhost: x86_64-unknown-linux-gnu\nrelease: 1.85.0\nLLVM version: 19.1.7\n","stderr":""},"13331785392996375709":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/brock/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}}
{"rustc_fingerprint":4305361489769004817,"outputs":{"2063776225603076451":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/brock/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""},"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.85.0 (4d91de4e4 2025-02-17)\nbinary: rustc\ncommit-hash: 4d91de4e48198da2e33413efdcd9cd2cc0c46688\ncommit-date: 2025-02-17\nhost: x86_64-unknown-linux-gnu\nrelease: 1.85.0\nLLVM version: 19.1.7\n","stderr":""},"13331785392996375709":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/brock/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}}