Skip to content

Independent workspace members get rebuild unnecessarily #323

@preiter93

Description

@preiter93

I've noticed that using cargo-chef independent workspace members get rebuilt unnecessarily.

Problem

For example say we have a workspace

├── Cargo.toml
├── bar
└── foo

where foo and bar do not depend on each other, and foo depends on the "either" crate. If I change a dependency of foo (e.g. I upgrade its "either" version), cargo-chef prepare --bin bar still produces a recipe that references foo and its dependencies and thus the cache gets invalidated.

The recipe thats currently produced with

cargo-chef prepare --bin bar`

contains the manifests of foo and its dependencies in the lock_file:

{
  "skeleton": {
    "manifests": [
      {
        "relative_path": "Cargo.toml",
        "contents": "[workspace]\nmembers = [\"bar\"]\nresolver = \"3\"\n[workspace.dependencies]\neither = \"1.15.0\""
      },
      {
        "relative_path": "bar/Cargo.toml",
        "contents": "[package]\nname = \"bar\"\nversion = \"0.0.1\"\n"
      },
      {
        "relative_path": "foo/Cargo.toml",
        "contents": "[package]\nname = \"foo\"\nversion = \"0.0.1\"\n\n[dependencies.either]\n"
      }
    ],
    "lock_file": "version = 4\n[[package]]\nname = \"bar\"\nversion = \"0.0.1\"\n[[package]]\nname = \"either\"\nversion = \"1.15.0\"[[package]]\nname = \"foo\"\nversion = \"0.0.1\"\ndependencies = [\"either\"]\n"
  }
}

As a result a change in foo’s dependencies invalidates the Docker cache for bar.

Solution

I've drafted a recipe-reducer (https://github.com/preiter93/cargo-reduce-recipe) which reduces this down to

{
  "skeleton": {
    "manifests": [
      {
        "relative_path": "Cargo.toml",
        "contents": "[workspace]\nmembers = [\"bar\"]\nresolver = \"3\"\n[workspace.dependencies]\neither = \"1.15.0\""
      },
      {
        "relative_path": "bar/Cargo.toml",
        "contents": "[package]\nname = \"bar\"\nversion = \"0.0.1\"\n"
      }
    ],
    "lock_file": "version = 4\n[[package]]\nname = \"bar\"\nversion = \"0.0.1\"\n[[package]]\nname = \"either\"\nversion = \"1.15.0\""
  }
}

(the lock_file could even be reduced further, removing the "either" completely but I haven't done that (yet)...)

This leads to a lot less cache invalidations. That is a big improvement, especially in a large workspace like is often the case in a microservice architecture.

IMO the best would be if cargo-chef could support this directly. If you're interested I could draft a PR?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions