From 43816205f372a66b22ab57d8f1a0bc0a754ae4d1 Mon Sep 17 00:00:00 2001 From: darkicewolf50 Date: Wed, 26 Feb 2025 12:04:05 -0700 Subject: [PATCH] finished ch14.2 --- Cargo Workspaces.md | 1 + Cargo and Cratesio.md | 2 +- Publishing libraries.md | 178 +++++++++++++++++++++++++- guessing_game/target/.rustc_info.json | 2 +- hello_cargo/target/.rustc_info.json | 2 +- 5 files changed, 181 insertions(+), 4 deletions(-) create mode 100644 Cargo Workspaces.md diff --git a/Cargo Workspaces.md b/Cargo Workspaces.md new file mode 100644 index 0000000..01c0df3 --- /dev/null +++ b/Cargo Workspaces.md @@ -0,0 +1 @@ +# Cargo Workspaces \ No newline at end of file diff --git a/Cargo and Cratesio.md b/Cargo and Cratesio.md index 78eecda..fc937cf 100644 --- a/Cargo and Cratesio.md +++ b/Cargo and Cratesio.md @@ -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 diff --git a/Publishing libraries.md b/Publishing libraries.md index 614b4b0..6883af6 100644 --- a/Publishing libraries.md +++ b/Publishing libraries.md @@ -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 \ No newline at end of file +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 Foundation’s 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. \ No newline at end of file diff --git a/guessing_game/target/.rustc_info.json b/guessing_game/target/.rustc_info.json index 0d44089..1e8278f 100644 --- a/guessing_game/target/.rustc_info.json +++ b/guessing_game/target/.rustc_info.json @@ -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":{}} \ No newline at end of file +{"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":{}} \ No newline at end of file diff --git a/hello_cargo/target/.rustc_info.json b/hello_cargo/target/.rustc_info.json index 0d44089..1e8278f 100644 --- a/hello_cargo/target/.rustc_info.json +++ b/hello_cargo/target/.rustc_info.json @@ -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":{}} \ No newline at end of file +{"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":{}} \ No newline at end of file