rust-vmm / community

rust-vmm community content
495 stars 27 forks source link

Proposal: Improve Cargo dependency format #131

Closed wllenyj closed 2 years ago

wllenyj commented 2 years ago

The crates in rust-vmm use >= comparison-requirements to specify specific dependencies. This places a significant maintenance burden on the user who uses it.

This issue is the same as vm-memory issues.

Problem

We use vm-memory as an example because the structure of vm-memory runs through the vmm ecosystem and cannot use two different versions. See version-incompatibility-hazards for reasons.

  1. When I develop a library my-lib 0.1.0, it depends on linux-loader and vm-memory, and linux-loader depends on vm-memory >= 0.6. The version of my-lib that depends on vm-memory requires:
    • If use default Caret requirements, then you can only use the latest 0.8.0, not older versions.
    • Also use >=, Finally, it will also use the latest 0.8.0.
  2. When an incompatible version of vm-memory 0.9.0 is released, it will be a disaster. Since cargo's strategy is to use the greatest version. Then, all libraries that depend on vm-memory >= must be fixed and released a new version. And the previous my-lib 0.1.0 will not work. This break is silent.
  3. If we don't want to do an update. Can lock the old version for binary crates. But for libraries, we need to use some hacks. e.g. cargo update -p vm-memory:0.9.0 --precise 0.8.0. And we have to lock the linux-loader as well. But when my-lib is released, it still can't work.

Solution

According to cargo recommendations:

Use caret requirements for dependencies, such as 1.2.3, for most situations. This ensures that the resolver can be maximally flexible in choosing a version while maintaining build compatibility.

And most open sources also use the SemVer version requirement(x.y.z), which is equivalent to Caret requirements(^x.y.z). Mentioned in document specifying-dependencies:

It actually specifies a range of versions and allows SemVer compatible updates. An update is allowed if the new version number does not modify the left-most non-zero digit in the major, minor, patch grouping.

The SemVer version requirement can solve the problems mentioned earlier.

  1. We can specify any version, as they all have a corresponding compatibility range. e.g. linux-loader 0.5.x corresponds to vm-memory 0.9.x, x upgrade does not break compatibility either.
  2. Incompatible versions are released, and will not affect other crates.
  3. If you do not upgrade the dependencies, it will also compile normally. An incompatible version means different from the left-most non-zero digit in x.y.z grouping.

Drawbacks

  1. When an incompatible version is released, the rust-vmm crate that depends on this crate needs to provide a new version. So that users can choose when they need to upgrade.
  2. When an incompatible version is released, it may be necessary to create a corresponding branch, in order to prepare for a patch release later. You can also not create it, then the incompatible version needs to be released immediately after the API incompatible change is merged.

Required Work

  1. Version releases need to be strictly follow SemVer Compatibility to determine API compatibility, and release the corresponding version number.
  2. Modify all rust-vmm crate dependencies to SemVer version requirements. and release a new incompatible version.
  3. [Option] Create branches for incompatible versions.

Thanks.