Depedency Management
1. Welcome and Icebreaker:
Welcome back!
If you could instantly add any pre-built “dependency” (like a skill, a tool, or a resource) to your life, what would it be and why?
2. Outline the Session:
Here’s the plan:
- Concept Explanation: We’ll discuss what dependencies are, why they’re important, and how Cargo helps manage them. We’ll cover key concepts like
Cargo.toml,Cargo.lock, crates.io, semantic versioning, and adding, updating, and removing dependencies. - Live Coding Demonstration: We’ll create a new project, add a dependency, use it in our code, and observe how Cargo handles the process. We’ll also demonstrate updating and removing dependencies.
- Tasks: You’ll get exercises to practice managing dependencies in your own projects.
Learning Outcomes: By the end of this session, you will be able to:
- Understand the concept of dependencies in software development.
- Use
Cargo.tomlto declare project dependencies. - Understand the role of
Cargo.lock. - Add dependencies to a project using
cargo add. - Use dependencies in your code.
- Update dependencies using
cargo update. - Remove dependencies using
cargo remove. - Understand the basics of semantic versioning (SemVer).
- Find and explore crates on crates.io.
Expectations: Dependency management is a core part of modern software development. Pay close attention to how Cargo simplifies this process for Rust projects.
3. Concept Explanation:
- Dependencies: Dependencies are external libraries (crates) that your project relies on. They provide pre-built functionality that you can use in your code.
- Why Use Dependencies?
- Code Reusability: Avoid reinventing the wheel.
- Faster Development: Leverage existing solutions.
- Community Contributions: Benefit from the work of other developers.
- Cargo’s Role: Cargo is Rust’s build system and package manager. It handles:
- Downloading and building dependencies.
- Managing dependency versions.
- Building your project.
- Running tests.
- Publishing your own crates.
Cargo.toml: This file is the manifest for your project. It contains:- Project metadata (name, version, authors).
- Dependencies: A list of the external crates your project depends on, along with their version requirements.
- Other configuration settings.
Cargo.lock: This file is automatically generated by Cargo. It locks the specific versions of all your dependencies (including transitive dependencies – dependencies of your dependencies) to ensure reproducible builds. You should not edit this file manually. It should be committed to version control.- **crates.io:** This is the official Rust package registry (like npm for JavaScript or PyPI for Python). It’s where Cargo downloads crates from.
- Semantic Versioning (SemVer): A versioning scheme (MAJOR.MINOR.PATCH) that helps manage compatibility:
- MAJOR: Incompatible API changes.
- MINOR: New features, but backwards-compatible.
- PATCH: Bug fixes, backwards-compatible.
- Cargo uses version specifiers (e.g.,
^,~, ) to control which versions of a dependency are acceptable.^1.2.3: Compatible with version 1.x.x, where x >= 2 and 3 (allows minor and patch updates). This is the default.~1.2.3: Compatible with version 1.2.x, where x >= 3 (allows only patch updates).- : Any version (generally not recommended).
1.2.3: Exactly version.
- Adding Dependencies:
cargo add(recommended):cargo add <crate_name>automatically adds the dependency toCargo.tomland downloads it.- Manually: You can edit
Cargo.tomldirectly, butcargo addis usually easier.
- Updating Dependencies:
cargo update: Updates dependencies to the latest compatible versions (according to the version specifiers inCargo.toml). It also updatesCargo.lock.
- Removing Dependencies:
cargo remove(recommended):cargo remove <crate_name>removes the dependency fromCargo.tomland updates the project.- Manually: You can edit
Cargo.tomldirectly.
4. Live Coding Demonstration:
Let’s create a new project and add the rand crate, which provides random number generation:
cargo new my_project
cd my_project
Open project in your IDE
1. Add a Dependency:
cargo add rand
This command does two things:
- Updates
Cargo.toml: It adds a line likerand = "0.8"(or whatever the latest version is) to the[dependencies]section. - Downloads the Crate: It downloads the
randcrate and its dependencies.
Cargo.toml (after cargo add rand):
[package]
name = "my_project"
version = "0.1.0"
edition = "2021"
[dependencies]
rand = "0.8" # The rand crate was added here
2. Use the Dependency:
Modify src/main.rs:
// src/main.rs
use rand::Rng; // Import the Rng trait from the rand crate
fn main() {
let mut rng = rand::thread_rng(); // Get a random number generator
let random_number = rng.gen_range(1..=100); // Generate a number between 1 and 100 (inclusive)
println!("Random number: {}", random_number);
}
3. Run the Project:
cargo run
Cargo will build the project (including the rand crate) and run it. You’ll see a random number printed to the console.
4. Update Dependencies (Optional):
cargo update
This command updates all dependencies to their latest compatible versions and updates Cargo.lock.
5. Remove a Dependency (Optional):
cargo remove rand
This command removes rand from Cargo.toml and updates Cargo.lock. You’ll also need to remove the use rand::Rng; line and the code that uses rand from src/main.rs to avoid compilation errors.
6. Exploring crates.io:
Open https://crates.io/ and find and analyze rand crate.
5. Tasks
- Add
ferris-says: Create a new project. Add theferris-sayscrate as a dependency. Use it to make Ferris (the Rust mascot) say something in your terminal. (You can find examples in theferris-saysdocumentation on crates.io). Cargo.tomlExploration: Examine theCargo.tomlfile after adding a dependency. Understand the different sections and the meaning of the version specifier.Cargo.lockExamination: Look at theCargo.lockfile. Notice how it lists the exact versions of all dependencies. Don’t modify this file manually!- Update and Observe: Add a dependency, run your project, then run
cargo update. CheckCargo.lockbefore and after the update to see how the versions might have changed. - Multiple Dependencies: Add two or three different dependencies to a project (e.g.,
rand,reqwestfor making HTTP requests,serdefor serialization/deserialization). Use them in your code. - Find a Crate: Go to crates.io and find a crate that interests you. Read its documentation. Add it to a new project and try using it.
- Version Specifiers: Experiment with different version specifiers in
Cargo.toml(e.g.,^,~, , a specific version number). Usecargo updateto see how the chosen version changes based on the specifier. Important: Be careful with (any version) – it’s generally not recommended for production code, as it can lead to unexpected breakage if a dependency makes a breaking change.