Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workspace reduce deps pr #452

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

dan-da
Copy link
Collaborator

@dan-da dan-da commented Feb 17, 2025

Creates a workspace with the following structure:

    neptune-cash
    ├── Cargo.lock
    ├── Cargo.toml
    ├── neptune-cli
    │   ├── Cargo.toml
    │   └── src
    │       └── main.rs
    ├── neptune-core
    │   ├── Cargo.toml
    │   └── src
    │       ├── lib.rs
    │       └── main.rs
    ├── neptune-dashboard
    │   ├── Cargo.toml
    │   └── src
    │       └── main.rs
    └── README.md

This PR came about as an attempt to reduce the number of deps when building neptune-core. neptune-dashboard in particular required extra deps such as ratatui, crossterm, and others.

I made a first commit that simply moves neptune-cli and neptune-dashboard into their own sub-crates with their own deps, but does not create a workspace. This worked, but had the limitation that each crate must be built separately, which nearly tripled build time to build them all.

By introducing a workspace at the top level, all three crates can be bulit together and share a single Cargo.lock. ie cargo build and cargo test work from the root dir.

The only limitation I have found is that cargo install --locked --path . no longer works due to a cargo bug. This is worked around by installing each separately:

cargo install --locked --path neptune-core
cargo install --locked --path neptune-cli
cargo install --locked --path neptune-dashboard

I updated the README installation instructions to reflect this.


There are some things I'm not sure about and have not tested:

  1. wix directory. I moved it into the workspace (root) dir.
  2. CI integration. This most likely breaks something. I might need help with that.

dep removal: cargo tree | wc -l dropped from 824 to 747 in the neptune-core crate.

regardless of deps, I think this is a useful organizational change because it makes it clear which deps are for which binary, whereas before they were all jumbled together.


note that each crate Cargo.toml defines its own version. So when making a release, each would need to be bumped to stay in sync, ideally via a release script.

This change reduces the number of dependencies in the neptune-core crate.

The logical structure becomes:

neptune-core
├── Cargo.lock
├── Cargo.toml
├── cli
│   ├── Cargo.lock
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── dashboard
│   ├── Cargo.lock
│   ├── Cargo.toml
│   └── src
│       └── main.rs
└── src
    ├── lib.rs
    └── main.rs
Creates a workspace with the following structure:

neptune-cash
├── Cargo.lock
├── Cargo.toml
├── neptune-cli
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── neptune-core
│   ├── Cargo.toml
│   └── src
│       ├── lib.rs
│       └── main.rs
├── neptune-dashboard
│   ├── Cargo.toml
│   └── src
│       └── main.rs
└── README.md
@dan-da dan-da force-pushed the workspace_reduce_deps_pr branch from 4c376b6 to 1d5c062 Compare February 17, 2025 21:00
@dan-da
Copy link
Collaborator Author

dan-da commented Feb 17, 2025

rebased to master.

@jan-ferdinand
Copy link
Member

jan-ferdinand commented Feb 18, 2025

I'm in favor of this change, thanks for taking it on. 👍

I recommend to use workspace dependencies. If all crates exclusively use some-dep.workspace = true over some-dep = "1.0", the risk of using multiple versions of the same dependency across our crates is eliminated.1

Footnotes

  1. Transitively, they might still pull in a different version, but avoiding this requires a lot of manual labor and is generally impossible.

@dan-da
Copy link
Collaborator Author

dan-da commented Feb 18, 2025

the risk of using multiple versions of the same dependency across our crates is eliminated

that's interesting, thx. I will look into it, but I think it could be a follow-up PR.


note: if crate (a) depends on crate (b) and (b) is correctly exporting any crate (c) that is used in its public API and if (a) is correctly using (c) via use b::c instead of a cargo dep, then c will already be the same version for both (a) and (b). This works even with public crates where no workspace is involved.

I guess where that falls down and workspace deps can help is if (b) uses (c) internally, and (a) also uses (c). But then isn't cargo supposed to pick a single version of (c) anyway, if possible?


edit: something that bothers me about workspace deps is they kind of mix deps across files. In this PR, it is very clear that neptune-core/Cargo.toml defines a set of deps and then neptune-cli/Cargo.toml depends on neptune-core, plus its own set of deps. Everything is self-contained, and pretty much like using a regular non workspace crate.

workspace deps change that model and require editing the root Cargo.toml in conjunction when making changes. So I have kind of mixed feelings about it, but that could be because I have no experience with using them.

Copy link
Contributor

@aszepieniec aszepieniec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much cleaner! I like it. That said, I am not familiar enough with the ins and outs of rust project configuration to have an educated opinion.

cargo install --locked --path neptune-core
cargo install --locked --path neptune-cli
cargo install --locked --path neptune-dashboard

Don't forget triton-vm-prover and please update the docs too (installation.md).

@dan-da
Copy link
Collaborator Author

dan-da commented Feb 19, 2025

Don't forget triton-vm-prover

it is still part of neptune-core, so installs with it. Actually I didn't even think about breaking it out since it doesn't add any additional deps. I guess it makes some sense for sake of symmetry/consistency. I don't think it even needs to depend on neptune_cash crate/lib. so yeah, I will put it into a separate crate also.

and please update the docs too (installation.md).

ah, forgot about that one, thx.


anyway, right now this PR Is breaking CI. I'm not planning to merge until we get the CI issue(s) worked out.

@jan-ferdinand
Copy link
Member

if crate (a) depends on crate (b) and (b) is correctly exporting any crate (c) that is used in its public API and if (a) is correctly using (c) via use b::c instead of a cargo dep, then c will already be the same version for both (a) and (b).

And if (b) fails to export (c), or if (a) pulls in (c) manually instead of using (b::c), then workspace dependencies won't be any help, of course.

I guess where that falls down and workspace deps can help is if (b) uses (c) internally, and (a) also uses (c). But then isn't cargo supposed to pick a single version of (c) anyway, if possible?

You are right, it should. If both (a) and (b) are part of the same workspace, it might never pull in multiple versions, and instead report unresolvable dependencies, like so:

cargo build
    Updating crates.io index
error: failed to select a version for `bincode`.
    ... required by package `two v0.1.0 (/home/triton/Code/tmp/two)`
versions that meet the requirements `^1.3.2` are: 1.3.2, 1.3.3

all possible versions conflict with previously selected packages.

  previously selected package `bincode v1.2.1`
    ... which satisfies dependency `bincode = "=1.2.1"` of package `one v0.1.0 (/home/triton/Code/tmp/one)`

failed to select a version for `bincode` which could resolve this conflict

That said, and even though the experiment above indicates that Cargo tries really hard, according to the book: “If crates in the workspace specify incompatible versions of the same dependency, Cargo will resolve each of them, but will still try to resolve as few versions as possible.” Apparently, de-duplication is not guaranteed. I'm not sure how to tweak my experiment to provoke duplicates, though.

something that bothers me about workspace deps is they kind of mix deps across files.

I see what you mean. I think I hadn't realized how hard Cargo tries to make sure there's only one version of a given dependency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants