Skip to content

Independent workspace members get rebuild unnecessarily #323

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?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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