Published on

Virtual Manifest and Package Manifest

Authors

In general manifest refers to a file that contains all the metadata about a project. For example, its dependencies and other configuration details. In Rust, it is the Cargo.toml file which is used by Rust’s package manager and build system.

Package Manifest

A package manifest is the cargo.toml file that defines a single Rust package. It’s contains the package name, author name, dependencies specific to that package and such.

Here is an example of how the Cargo.toml will look like for a package manifest:

[package]
name = "test_package_one"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = "1.0"
media: "1.18.0"

Virtual Manifest

A virtual manifest is the cargo.toml file in a Rust workspace that does not define a Rust package by itself. Instead, it is used to manage multiple packages within the same workspace. It’s very useful when you want to manage dependencies and metadata that are common between all the packages.

Here is an example of how the Cargo.toml will look like for a virtual manifest:

[workspace]
members = [
    "test_package_one",
    "test_package_two",
    "test_package_three",
]

Now let’s see how a package and virtual manifest look in a big project structure that has several packages.

In this structure, my_project is a workspace that contains two packages: test_package_one and test_package_two. Each package has its own Cargo.toml file (Package Manifest), and there's a top-level Cargo.toml file in my_project (Virtual Manifest) for the workspace.

my_project/
|-- Cargo.toml       (Virtual Manifest)
|-- test_package_one/
|   |-- Cargo.toml   (Package Manifest for test_package_one)
|-- test_package_two/
    |-- Cargo.toml   (Package Manifest for test_package_two)

Using Virtual Manifest to override dependency in Package Manifest

We can use [patch] in cargo.toml of the virtual manifest to override the dependencies in package manifest. In our test_package_one we used the media: "1.18.0" dependency and now if we want to override it from virtual manifest, this is how we can do it:

[workspace]
members = [
    "test_package_one",
    "test_package_two",
    "test_package_three",
]

[patch.crates-io]
media = { path = "../../media" }

You can also use a git repository directly:

[workspace]
members = [
    "test_package_one",
    "test_package_two",
    "test_package_three",
]

[patch.crates-io]
media = { git = "https://github.com/servo/media" }

This is especially useful when you locally want to modify the media and test those changes in your project. For example: you can clone the media repository from GitHub and make the changes you want. After that you can use your local path to media under [patch.crates-io] in Cargo.toml of your virtual manifest to test how your changes in media affect your project.

😊--😊