Support Cargo workspace/path-only dependencies and the pnpm workspace protocol - #397
Merged
Merged
Conversation
Dependencies declared with { workspace = true } inherit their version
from the workspace root manifest, and path-only dependencies have no
version requirement at all. Read both as version-less instead of
throwing so bumps flow through; the write path already leaves
version-less declarations untouched.
1 task
`workspace:*` / `workspace:^` / `workspace:~` declarations resolve to the version the workspace holds and are rewritten by the package manager at publish, so there is no version in them to bump; bumping a dependent previously corrupted them to a bare major version (e.g. "0"). Leave them untouched, and for an embedded range like `workspace:^1.2.3` keep the protocol prefix and bump the range within it.
Contributor
Package Changes Through a861b7eThere are 9 changes which include action with minor, @covector/assemble with minor, @covector/files with minor, covector with minor, @covector/apply with minor, @covector/changelog with minor, @covector/command with minor, @covector/toml with minor, @covector/types with minor Planned Package VersionsThe following package releases are the planned based on the context of changes in this pull request.
Add another change file through the GitHub UI by following this link. Read about change files or the docs at github.com/jbolda/covector |
jbolda
approved these changes
Jul 3, 2026
jbolda
left a comment
Owner
There was a problem hiding this comment.
Super appreciate it! Looks great!
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #369. I lost write access to the fork that branch lives on (left the org), so this is the same change rebuilt from scratch on current main: one commit, tests written against the Effection v4 / vitest v4 setup, no lockfile churn this time.
And your February question deserves an actual answer, so:
The second one. Every crate keeps its own
[package] versionin its own manifest; the root version inheritance covector already supports isn't involved. What breaks is two dependency shapes that are legitimately version-less in Cargo:dep = { workspace = true }: the version lives in the root[workspace.dependencies], not in the member manifest covector is readingdep = { path = "../pkg" }: no version anywhere, which is normal for internal crates that never touch a registryThe real-world setup this came from (a private aviation monorepo, ~60 covector-managed crates): the root
[workspace.dependencies]declares each internal crate as{ path = "...", version = "*" }, members consume them with{ workspace = true }, covector runs the version/changelog cascade, and nothing publishes to crates.io.getPackageFileVersionthrows on both shapes today, socovector versioncan't run at all on that repo.Your intent (bump a dep's declared version if it has one) is preserved:
versionbump exactly as before.setPackageFileVersionalready skips version-less object deps, so the manifest is left untouched and cargo resolves through the workspace/path. There's an apply test now asserting a{ workspace = true }table survives a cascade bump byte-for-byte.One honest flag: the existing validate test for path-only deps flips from "expects an error" to "expects success". That IS the behavior change, not collateral damage.
What this deliberately does not do: bump versions inside the root
[workspace.dependencies]table, which a workspace that publishes to crates.io with real requirements there would eventually want. Happy to take that as a follow-up if you're interested.For whatever it's worth: this exact change ran in production on that monorepo for about six months of releases before I left. It held up.
Update: pnpm/yarn
workspace:protocol for JS packages (second commit, same branch)Following up from Discord: the JS side had the same class of bug. A
"workspace:*"dependency contains no., soderiveVersionConsideringPartialstreated it as a partial version pin and rewrote it to the dep's bare major version —"0"for any 0.x package.workspace:^became"^0", andworkspace:~1.2.3lost its protocol prefix entirely.Handling now lives in
getDepBumpVersion:workspace:*/workspace:^/workspace:~(and aliasedworkspace:name@rangedeclarations) are left untouched: they pin to whatever version the workspace holds and the package manager rewrites them at publish time, so there is no version in the declaration to bump.workspace:^1.2.3keeps the protocol prefix and bumps the range within it (so a minor bump of the dep yieldsworkspace:^1.3.0), preserving the existing partial-pin semantics.An apply-level test (new fixture
pkg.js-pnpm-workspace) asserts the float forms survive a cascade bump byte-for-byte, the embedded range bumps in place, and the dependent's own version still bumps.