Skip to content
Open
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
80b9ddf
Create 0000-nested-publish.md
kpreid Jul 1, 2023
126b2b4
Clarify some terms and discuss workspaces and normalization
kpreid Jul 1, 2023
ef9a157
Discuss trait coherence relaxation
kpreid Jul 1, 2023
a1d4425
Reposition footnote-links
kpreid Jul 1, 2023
35184e0
Add PR number
kpreid Jul 1, 2023
c4dd372
Clarify `path` behavior and existing dev-dependency behavior
kpreid Jul 1, 2023
e71a953
Avoid "lockstep" and discuss a version duplication hazard
kpreid Jul 1, 2023
3da9eeb
Add Definitions section.
kpreid Jul 6, 2023
7f9c09f
Discuss more alternatives for marking packages; define "nested package"
kpreid Jul 6, 2023
130ceb0
Clarify “is private”
kpreid Jul 6, 2023
42bdb61
Require dependencies to be explicitly nested.
kpreid Feb 5, 2024
25d86b1
More motivation and drawbacks.
kpreid Feb 5, 2024
743d531
Define “nested publishing”.
kpreid Feb 5, 2024
34a19dc
Discuss postponed RFC 2224 as prior art.
kpreid Feb 5, 2024
b75a519
Mention vendoring.
kpreid Feb 5, 2024
d7e8dea
Discuss “subcrate dependencies” in prior art.
kpreid Feb 5, 2024
6670428
Discuss “Inline crates” in prior art.
kpreid Feb 5, 2024
da547de
Rewrite reference-level explanation to focus more on effects than cha…
kpreid Feb 5, 2024
b4923ac
Expand alternatives and move inline-crates discussion there.
kpreid Feb 5, 2024
68ad634
Move license and version ideas.
kpreid Feb 11, 2024
33d1c6e
Specify that package names must be unique.
kpreid Feb 11, 2024
680709c
Typo
kpreid Feb 11, 2024
2af4921
Mention feature flattening.
kpreid Feb 11, 2024
0deba10
Discuss workspace inheritance.
kpreid Feb 11, 2024
b999976
Move `dependencies.*.publish = false` to future possibilities.
kpreid Feb 11, 2024
3edb308
Replace `package.publish = "nested"` with `package.publish.nested = t…
kpreid Feb 11, 2024
dd90f20
Refine explanation of `package.publish` being a table.
kpreid Feb 11, 2024
07b058d
Rephrase name conflict rule to avoid "transitive closure".
kpreid Mar 11, 2024
2c220ee
Always error on `workspace.dependencies.*.publish`.
kpreid Mar 11, 2024
4bc77cb
Rewrite feature flattening section.
kpreid Mar 11, 2024
e470314
Rationale for name uniqueness.
kpreid Mar 13, 2024
2a5474e
Polishing.
kpreid Mar 13, 2024
db9e7fa
Update comparison with packages-as-namespaces given that that RFC has…
kpreid Mar 13, 2024
4817861
Explicitly state that nested names are non-unique *outside* of the pa…
kpreid Mar 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Mention vendoring.
  • Loading branch information
kpreid committed Feb 5, 2024
commit b75a5197f1600c2a89dfcfb63fb9cca95f94547d
10 changes: 9 additions & 1 deletion text/0000-nested-publish.md
Copy link
Member

Choose a reason for hiding this comment

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

A minor question: If a Git repository contains a package with nested packages, can the other package depends on any of those nested packages as a Git dependency? Currently Git dependency searches packages whose name matches recursively inside the repository.

Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,21 @@ The presence or absence of a `[workspace]` has no effect on the new behavior, ju
[drawbacks]: #drawbacks

* This increases the number of differences between “Cargo package (on disk)” from “Cargo package (that may be published in a registry, or downloaded as a unit)” in a way which may be confusing; it would be good if we have different words for these two entities, but we don't.

* It is not possible to publish a bug fix to a nested package without republishing the entire parent package; this is the cost we pay for the benefit of not needing to take care with versioning for nested packages.
Copy link
Contributor

Choose a reason for hiding this comment

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

However, for the proc-macro case, = version requirements are frequently used and so both would need to be published anyways in that case.


* Suppose `foo` has a nested package `foo-core`. Multiple major versions of `foo` cannot share the same instance of `foo-core` as they could if `foo-core` were separately published and the `foo`s depended on the same version of `foo-core`. Thus, choosing nested publishing may lead to type incompatibilities (and greater compile times) that would not occur if the same libraries had been separately published.
* If this situation comes up, it can be recovered from by newly publishing `foo-core` separately (as would have been done if nested publishing were not used) and using the [semver trick](https://github.com/dtolnay/semver-trick) to maintain compatibility.
Copy link
Member

Choose a reason for hiding this comment

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

Semver trick does solve this problem, but only when those package bumps their MSRV, so this feature won't get adopted until some point. Some popular crates using proc-macros hold a relatively conservative MSRV. The adoption rate might be mild annoying in the short-mid term.
(Granted, other alternatives would have the same issue)


* Support for duplicative nested publishing (that is, nested packages that are nested within more than one parent package) has the following consequences:
* May increase the amount of source code duplicated between different published packages, increasing download sizes and compilation time. It's currently possible to duplicate code into multiple packages via symlinks, but this would make it an “official feature”.
Copy link
Member

Choose a reason for hiding this comment

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

Along with this, as a side effect, this might provide an easier route for people to vendor code more than it was. The Rust ecosystem is different from 5 years ago, but the initial idea of Cargo/crates.io is to encourage everybody to publish and share codes. And whenever possible, play nice and help fix bugs in upstream.

Again, Rust is not Rust anymore. The old rules might not suitable nowadays since enterprise and other large projects starts using it more. Regardless, the potential consequence of paradigm shift is something we need to be aware of.

Copy link
Contributor

Choose a reason for hiding this comment

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

Along with this, as a side effect, this might provide an easier route for people to vendor code more than it was.

At first I wasn't too concerned about it but then I thought of what insta had to do to vendor yaml-rust. They have to copy the code in, merge any dependencies, and update any crate:: relative references.

With this feature, its copy the package directory in, mark it as nested, and you are done.

Copy link
Contributor

Choose a reason for hiding this comment

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

Looking over #2224, two of the participants specifically called out wanting to use it for private forks :/

* If packages A and B are separately published with nested package C, and A also depends on B, then A may see two copies of C's items, one direct and one transitive. This may cause a set of packages to fail to compile due to type/trait mismatches when published. [RFC 3516 public/private dependencies](https://rust-lang.github.io/rfcs/3516-public-private-dependencies.html) may be able to reduce problems of this type if we encourage, by documentation and lint, authors to think twice before allowing a multiply-used nested dependency to also be a RFC 3516 public dependency.

* Build and packaging systems that replace or wrap Cargo (e.g. mapping Cargo packages into Linux distribution packages) may have 1 library:1 package assumptions that are broken by this change.

* In the discussion of [RFC 2224], it came up that a feature like this could be used for vendoring libraries with patches not yet accepted upstream, where people sometimes currently resort to publishing forks to crates.io. Using nested packages for vendoring has the advantage of not cluttering crates.io, but also results in hidden code duplication. We may wish to decide whether to encourage or discourage this use of the feature.


# Rationale and alternatives
[rationale-and-alternatives]: #rationale-and-alternatives

Expand Down Expand Up @@ -198,7 +205,7 @@ There are several ways we could mark packages for nested publishing, rather than
# Prior art
[prior-art]: #prior-art

* Postponed [RFC 2224](https://github.com/rust-lang/rfcs/pull/2224) is broadly similar to this RFC, and proposed using `publish = false` to mean what we mean by `publish = "nested"`. This RFC is more detailed and addresses the questions that were raised in discussion of 2224.
* Postponed [RFC 2224] is broadly similar to this RFC, and proposed using `publish = false` to mean what we mean by `publish = "nested"`. This RFC is more detailed and addresses the questions that were raised in discussion of 2224.

I am not aware of other package systems that have a relevant similar concept, but I am not broadly informed about package systems. I have designed this proposal to be a **minimal addition to Cargo**, building on the existing concept of `path` dependencies to add lots of power with little implementation cost; not necessarily to make sense from a blank slate.

Expand Down Expand Up @@ -245,3 +252,4 @@ This RFC does not propose implementing a dependency declared as `{ git = "...",

[artifact dependencies]: https://github.com/rust-lang/rfcs/pull/3028
[#3243 packages as namespaces]: https://github.com/rust-lang/rfcs/pull/3243
[RFC 2224]: https://github.com/rust-lang/rfcs/pull/2224