rust-lang / cargo

The Rust package manager
https://doc.rust-lang.org/cargo
Apache License 2.0
12.58k stars 2.39k forks source link

Allow having broken symlinks in the packaged cargo archive #11203

Open Ekleog opened 1 year ago

Ekleog commented 1 year ago

Problem

In https://github.com/Ekleog/kannader/tree/main/smtp-queue-fs, I have a res/ folder that intentionally contains a broken symlink. This folder is properly tracked by git, and used by tests to validate that smtp-queue-fs behaves correctly when faced with a queue that has a broken symlink

Proposed Solution

It would be nice if cargo were able to store the same types of files as git, so including broken symlinks. This would make it possible to upload this kind of crates with its tests on crates.io

Notes

I guess an alternative would be to not have the broken symlink be checked-in, and instead handle the test creation and validation differently. However, it makes it harder to just add tests, given that it means manual care needs to be given to each test that has a broken symlink.

I would understand if you think that'd be a non-feature and you didn't want to allow including broken symlinks in the crate on crates.io, but I thought it was worth opening this issue to gather feedback over whether it'd be of interest. Sorry if it has already been discussed elsewhere!

weihanglo commented 1 year ago

Thank you for the proposal!

I totally understand what you're trying to solve. Also have no idea why Cargo implemented like this, as the logic dates back to Cargo v0.0.1-pre😆. However, I do have concerns on this being implemented.

Cargo tries its best to make every .crate file always compile. Based on that fact, Cargo resolves all symlinks, and copies target contents over into tarball. A common use case is sharing root README and LICENSE file within a workspace, so that each member gets a real copy of that file and published to crates.io with a sense of integrity.

If Cargo now switches the behaviour to align with git, some projects will start failing as they cannot find the actual contents during compiling. If we keep the current behaviour and only treat broken symlinks as you proposed, the inconsistency sounds even more confusing, at least to me.

We may loose the restriction a bit, such like when Cargo.toml includes explicitly includes a broken symlink, just includes it and emits a warning. I am not entirely sure what it might cause if we go this route. People might find their files missing after publish and that is really unfortunate.

Ekleog commented 1 year ago

Hmmm… as you're saying, I guess silently changing the behavior or reusing include wouldn't make much sense.

Maybe introducing an as-symlink = ["file1", ..., "fileN"] option, that would copy the symlink verbatim without dereferencing, would make sense? And then it could error out if file* ever were to not be a symlink, or to be excluded.

weihanglo commented 1 year ago

Hmm… It could be a solution but not optimal in my opinion. There are some concerns around it.

Though I don't have any better idea than what you propose so far. 😞

Ekleog commented 1 year ago

Hmm you're right, but I don't see any better option that'd avoid backwards-compatibility hazards either :/ guess I'll leave this open hoping for other people to come in with ideas!