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 inheritance #6089

Closed
wants to merge 15 commits into from
Closed

Workspace inheritance #6089

wants to merge 15 commits into from

Conversation

dani162
Copy link

@dani162 dani162 commented Sep 24, 2022

Objective

Solution

  • Use the new cargo workspace inheritance feature

@alice-i-cecile alice-i-cecile added C-Dependencies A change to the crates that Bevy depends on C-Code-Quality A section of code that is hard to understand or change labels Sep 24, 2022
Cargo.toml Outdated Show resolved Hide resolved
Cargo.toml Show resolved Hide resolved
@mockersf
Copy link
Member

mockersf commented Sep 24, 2022

job "check-missing-examples-in-docs" is missing rust update.
You can update it by adding this code block https://github.com/bevyengine/bevy/blob/main/.github/workflows/ci.yml#L31-L34 in this job https://github.com/bevyengine/bevy/blob/main/.github/workflows/ci.yml#L252

@dani162
Copy link
Author

dani162 commented Sep 24, 2022

What about the other dependencies, like serde, ron etc, should these be included in the workspace as well?

@alice-i-cecile
Copy link
Member

alice-i-cecile commented Sep 24, 2022

So, I'd like to specify a single workspace level version to use. Does including them at the workspace level still let us build the constituent crates without these optional dependencies?

EDIT: looks like the answer is no :(

Dependencies from this table cannot be declared as optional

https://doc.rust-lang.org/cargo/reference/workspaces.html#the-dependencies-table

I suspect we should leave at this for now, rather than shipping pointless dependencies to users of the smaller crates.

@mockersf
Copy link
Member

mockersf commented Sep 25, 2022

What about the other dependencies, like serde, ron etc, should these be included in the workspace as well?

Let's try like this for now, and maybe check later for those. not convinced it would improve a lot

This PR also probably remove the need for https://github.com/bevyengine/bevy/blob/main/.github/workflows/release.yml and https://github.com/bevyengine/bevy/blob/main/.github/workflows/post-release.yml which were there to help with the version updates across all crates. @cart do you have an opinion on keeping the auto workflows (that does not support yet workspace inheritance - crate-ci/cargo-release#499)

@dani162
Copy link
Author

dani162 commented Sep 25, 2022

So, I'd like to specify a single workspace level version to use. Does including them at the workspace level still let us build the constituent crates without these optional dependencies?

EDIT: looks like the answer is no :(

Dependencies from this table cannot be declared as optional

https://doc.rust-lang.org/cargo/reference/workspaces.html#the-dependencies-table

I suspect we should leave at this for now, rather than shipping pointless dependencies to users of the smaller crates.

I just assumed that u can not set the optional at the workspace level, but u can still set it in the specific dependencies sections of the child creates.
But i am not sure about this behaviour, i am relativ new to rust 😄

Edit:
https://rust-lang.github.io/rfcs/2906-cargo-workspace-deduplicate.html#new-dependency-directives
It seems like it is possible if i understand this correctly.

@tguichaoua
Copy link
Contributor

So, I'd like to specify a single workspace level version to use. Does including them at the workspace level still let us build the constituent crates without these optional dependencies?
EDIT: looks like the answer is no :(

Dependencies from this table cannot be declared as optional

https://doc.rust-lang.org/cargo/reference/workspaces.html#the-dependencies-table
I suspect we should leave at this for now, rather than shipping pointless dependencies to users of the smaller crates.

I just assumed that u can not set the optional at the workspace level, but u can still set it in the specific dependencies sections of the child creates. But i am not sure about this behaviour, i am relativ new to rust 😄

Edit: https://rust-lang.github.io/rfcs/2906-cargo-workspace-deduplicate.html#new-dependency-directives It seems like it is possible if i understand this correctly.

Yes, this is actually possible, there is an example here

[project]
name = "bar"
version = "0.2.0"

[dependencies]
regex = { workspace = true, features = ["unicode"] }

[build-dependencies]
cc.workspace = true

[dev-dependencies]
rand = { workspace = true, optional = true }

Important point : crate level features is additive with workspace level features and default-feature cannot be used at crate level, it's inherited from workspace.

@dani162
Copy link
Author

dani162 commented Sep 25, 2022

Important point : crate level features is additive with workspace level features and default-feature cannot be used at crate level, it's inherited from workspace.

So for these one with the default features disabled we have to stick to the old syntax?

So i need to revert the changes where the default features are disabled, right?
For Example

[dependencies]
bevy_dylib = { workspace = true, default-features = false, optional = true }

should use the old syntax

bevy_dylib = { path = "crates/bevy_dylib", version = "0.9.0-dev", default-features = false, optional = true }

@tguichaoua
Copy link
Contributor

tguichaoua commented Sep 25, 2022

Important point : crate level features is additive with workspace level features and default-feature cannot be used at crate level, it's inherited from workspace.

So for these one with the default features disabled we have to stick to the old syntax?

So i need to revert the changes where the default features are disabled, right? For Example

[dependencies]
bevy_dylib = { workspace = true, default-features = false, optional = true }

should use the old syntax

bevy_dylib = { path = "crates/bevy_dylib", version = "0.9.0-dev", default-features = false, optional = true }

Since bevy_dylib is only used in the root cargo.toml, I don't think this is necessary to put it in workspace dependencies.

Also, I think we should first establish rules for when using workspace dependencies or not.
For example if the dependency appears more than once using the same features.

@dani162
Copy link
Author

dani162 commented Sep 25, 2022

Since bevy_dylib is only used in the root cargo.toml, I don't think this is necessary to put it in workspace dependencies.

This was just an example for one dependency with default features, there are more of them, which are used at more places (e. g. bevy_ecs)
Edit:
Actually only these three:

bevy                -> bevy_dylib
bevy                -> bevy_internal
crates/bevy_app     -> bevy_ecs
crates/bevy_dylib   -> bevy_internal

Also, I think we should first establish rules for when using workspace dependencies or not.
For example if the dependency appears more than once using the same features.

So should i just revert the [workspace.dependency] inheritance changes (3c9f8a3) for now, and we only merge the [workspace.package] inheritances?

@dani162
Copy link
Author

dani162 commented Oct 4, 2022

So should i just revert the [workspace.dependency] inheritance changes (3c9f8a3) for now, and we only merge the [workspace.package] inheritances?

I will just do that and resolve the merge conflicts, that we can close this

@dani162 dani162 marked this pull request as ready for review October 4, 2022 15:05
@dani162
Copy link
Author

dani162 commented Oct 4, 2022

This pr only inculdes the [workspace.package] inheritances

Copy link
Contributor

@tguichaoua tguichaoua left a comment

Choose a reason for hiding this comment

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

LGTM

@mockersf
Copy link
Member

mockersf commented Oct 4, 2022

Could you also add the license field to the package level?

This PR would break the workflows release and post-release as cargo-release doesn't understand yet those workspace value. Either this PR is blocked on support, or those workflows should be removed

@dani162
Copy link
Author

dani162 commented Oct 4, 2022

Any ideas why this action failed before and now it just passed?

@alice-i-cecile
Copy link
Member

Flaky test :( There's an open issue.

@alice-i-cecile alice-i-cecile added the S-Blocked This cannot move forward until something else changes label Oct 4, 2022
Copy link
Member

@NiklasEi NiklasEi left a comment

Choose a reason for hiding this comment

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

I think for most crates, we could also inherit the keywords.

Cargo.toml Show resolved Hide resolved
Cargo.toml Show resolved Hide resolved
Cargo.toml Show resolved Hide resolved
@bjorn3
Copy link
Contributor

bjorn3 commented Oct 9, 2022

I think for most crates, we could also inherit the keywords.

No, the graphics keyword doesn't apply to most crates.

@NiklasEi
Copy link
Member

NiklasEi commented Oct 10, 2022

I think for most crates, we could also inherit the keywords.

No, the graphics keyword doesn't apply to most crates.

I am not saying we should inherit all of them as they currently are defined for the parent crate. A minimum of ["bevy"] can be inherited for sure. That's what most crates currently define.

Co-authored-by: bjorn3 <[email protected]>
@james7132
Copy link
Member

cargo-release now supports workspace inheritance as of 0.22 which landed on 10/21/2022. Is there any other blocker for this PR?

@alice-i-cecile alice-i-cecile removed the S-Blocked This cannot move forward until something else changes label Dec 4, 2022
Cargo.toml Outdated
@@ -23,6 +10,26 @@ members = [
"errors",
]

[workspace.package]
version = "0.9.0-dev"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
version = "0.9.0-dev"
version = "0.10.0-dev"

Copy link
Author

Choose a reason for hiding this comment

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

I am not sure if we should bump the version in this pull request, in my opinion we should do this in another pr?
If we do, we also need to update all the dependencies, because the version of the dependencies is not inherited at the moment (see conversation above).
I guess their is an GitHub-Action for that?

.github/workflows/ci.yml Outdated Show resolved Hide resolved
.github/workflows/ci.yml Outdated Show resolved Hide resolved
@cart
Copy link
Member

cart commented Dec 5, 2022

I'd like to hear some arguments for using workspace inheritance for "bevy_x crate version numbers", as right now I'm seeing a number of downsides and no upsides:

  1. Currently, this PR doesn't solve the "version number automation problem" because bevy_x dependencies do not use workspace inheritance. If we chose to add workspace inheritance for these crates, we couldn't use it for "optional bevy_x dependencies", which we have a good number of throughout the workspace. Optional dependencies would need to manually specify the Bevy version. This means that we will still need to run our "release" and "post release" workflows.
  2. For a given crate, this change makes it harder to determine its version number. Users trying to find the Bevy version for a specific crate will need to know how this system works (and find the file where the global version is defined). I would consider this an acceptable loss if it could actually consider the number to be the global source of truth. But as outlined in (1), this is not possible.
  3. In the event that we choose to use inheritance for non-optional bevy_x dependencies, this creates refactor weirdness where we go from bevy_animation = { workspace = true } to bevy_animation = { version = "0.9.0", path = "../bevy_animation", optional = true}.

@paul-hansen
Copy link
Contributor

I think you can still use workspace dependencies that are optional, you just declare them as optional at the crate level not at the workspace level. (Sorry if I misunderstood and you already knew that)

Example:

./Cargo.toml

[dependencies]
# Root bevy crate optional dep
bevy_dylib = { workspace = true, optional = true}

[workspace.dependencies]
# Can't use optional here, the crates choose that individually
bevy_dylib = { path = "crates/bevy_dylib", version = "0.9.0", default-features = false }
bevy_math = { path = "crates/bevy_math", version = "0.9.0" }

./bevy_reflect/Cargo.toml

[dependencies]
# bevy_x crate with optional dep from workspace
bevy_math = { workspace = true, version = "0.9.0", features = ["serialize"], optional = true }

@dani162
Copy link
Author

dani162 commented Dec 6, 2022

I would agree that the version number inheritance is not beneficial for us at the moment, since we can't use the dependency inheritance as we would like to.

There is an open issue/pull-request at the cargo repository about the problem, that you can only use the default features for all or for none packages, if the package inherits the workspace package.
rust-lang/cargo#11409
rust-lang/cargo#11329

If the cargo/rust community decides to allow at least to disable default-features on the workspace level and then enable it at the child, we could use the dependency inheritance. I think this could be possible since in the current rfc (https://rust-lang.github.io/rfcs/2906-cargo-workspace-deduplicate.html) it's not allowed to define the default feature in the package level (but there is no error/warning if you define it anyway, it is just not working if you do so), so it shouldn't be a breaking change.

Then at least we could use the following:

[workspace.dependencies]
foo = { version = "0.1.0", default-features = false}

[dependencies]
foo = { workspace = true, default-features = true }

@cart
Copy link
Member

cart commented Dec 16, 2022

I think you can still use workspace dependencies that are optional, you just declare them as optional at the crate level not at the workspace level. (Sorry if I misunderstood and you already knew that)

Ah I wasn't aware of this. That does change things. Does that mean that if a "workspace dependency" is not referenced by a crate anywhere in the workspace, it won't actually be built?

@paul-hansen
Copy link
Contributor

Does that mean that if a "workspace dependency" is not referenced by a crate anywhere in the workspace, it won't actually be built?

Hmm, that's what I had thought from reading the docs but I just tried it and I was able to use a dependency from the workspace without specifying it in the child library's cargo.toml at all so I guess I was wrong. Seems less useful than I was originally thinking.

@alice-i-cecile
Copy link
Member

I'm going to close this out then. If there's a strong reason found I'm happy to try again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-Code-Quality A section of code that is hard to understand or change C-Dependencies A change to the crates that Bevy depends on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use workspace inheritance
10 participants