-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Add --force
flag to cargo install
#2405
Conversation
r? @huonw (rust_highfive has picked a reviewer for you, use r? to override) |
Thanks for the PR @gkoz! There's a few technical aspects I'd tweak here, but I agree that the first thing to do here is probably to decide whether we want to do this in the first place. Let's discuss more on the issue, though, as that's probably the best place to have this discussion. (I'll write a comment over there shortly) |
if replace { | ||
return Ok(Some(p.clone())) | ||
} | ||
msg.push_str(&format!(" as part of `{}` (use --replace to override)", p)); | ||
} | ||
Err(human(msg)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've realized that it's safer to always list all conflicts when run without --replace
thus the error should probably be generated somewhere up the stack.
There doesn't seem to be any opposition to this change. |
Ok, @wycats and I had a chance to talk about this recently, and this seems like it's desirable as it's pretty orthogonal from the One thought we had was perhaps this could be renamed |
Yes I'll keep You had mentioned some implementation issues. I'm guessing you don't like the |
Ah I believe what I had in mind was the "transactional" nature of the install. Right now the uninstall happens first, but it probably wants to get delayed until right before the actual new binaries are moved into place (either that or nothing is really uninstalled, just metadata is updated). |
☔ The latest upstream changes (presumably #2421) made this pull request unmergeable. Please resolve the merge conflicts. |
ping @gkoz, any update on this? |
Oh wow, it's been a month? I'll revisit this in a few days. |
Sounds good to me! Feel free to ping me if you need help pushing over the finish line. |
To avoid any misunderstanding... The current patch calls |
Basically what I'm getting at is two properties:
So given that, the error that I'm worried about here is that we successfully remove something but then hit an I/O error copying in a new file, In that case we won't restore the just-removed binaries. Could this be updated to handle that? |
I've pushed a version, that copies all binaries into a temp subdirectory of the destination and only after that succeeds tries to replace the existing binaries. If overwriting is partially successful, it doesn't try to undo anything (should it? that could further increase complexity) but still updates the metadata. Another difference from former behavior is (when Error handling is not ideal here:
Oh and I haven't tested on Windows yet to make sure there's no issue with |
--replace
flag to cargo install--force
flag to cargo install
} | ||
} | ||
} | ||
// If `--bin` or `--example` weren't specified, uninstall obsolete |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems a little surprising to me, this is basically saying if package A installed foo and bar, then B installed foo, you'd remove A's bar? I'd probably expect that A's bar stuck around and you could uninstall it with cargo uninstall A
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All this time I'd been assuming it's a good idea for cargo install -f foo
to completely remove the remnants of the old package by default because that's probably what the user wants. :) If that's not the case I should probably add a hint "run 'cargo uninstall foo:{previous version}' to remove remaining binaries."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm yeah I guess it depends on how you look at it. On one hand you could have installed a package with a ton of binaries, some of which you never used, and then you overwrite one of the never used ones. On the other hand this could also hamstring a package to be useless if it's the one binary that counts.
To me though -f
just means "do this anyway" which doesn't necessarily imply "do the extra work of removing everything else", and I like the idea of adding a note that other binaries from the package are lying around and may wish to be removed.
Thanks @gkoz! Can you also write some tests for some of the corner cases here? Just to make sure the metadata is managed properly and everything works as expected. |
Still working on adding tests. Wondering how to imitate failure modes. Want to get this right first, and then add the hint about outdated binaries, possibly in another PR. |
It's ok to not necessarily exhaustively test them, it's fine to just smoke test a few simple ones like something already exists, a build failure when overwriting, etc. |
Close #2082 Adding `--force` (`-f`) instructs cargo to overwrite existing binaries (updating the metadata accordingly). This allows updating crates via `cargo install -f <crate>`. Installation happens in two stages now: binaries are copied into a temporary subdirectory of the destination first, then moved into destination. This should catch some errors earlier. In case of installation error cargo will remove new binaries but won't attempt to undo successful overwrites.
Try moving the binaries (and fall back to copying) if the build directory is a temporary one (source isn't a local path).
Added more tests and an optional optimization in a separate commit. |
Add `--force` flag to cargo install Close #2082. Adding `--force` (`-f`) instructs cargo to overwrite existing binaries (updating the metadata accordingly). This allows updating crates via `cargo install -f <crate>`. Installation happens in two stages now: binaries are copied into a temporary subdirectory of the destination first, then moved into destination. This should catch some errors earlier. In case of installation error cargo will remove new binaries but won't attempt to undo successful overwrites.
💔 Test failed - cargo-win-msvc-32 |
@bors: retry On Mon, May 2, 2016 at 10:21 AM, bors notifications@github.com wrote:
|
⚡ Previous build results for cargo-linux-32, cargo-linux-64, cargo-mac-32, cargo-mac-64, cargo-win-gnu-64, cargo-win-msvc-64 are reusable. Rebuilding only cargo-cross-linux, cargo-win-gnu-32, cargo-win-msvc-32... |
☀️ Test successful - cargo-cross-linux, cargo-linux-32, cargo-linux-64, cargo-mac-32, cargo-mac-64, cargo-win-gnu-32, cargo-win-gnu-64, cargo-win-msvc-32, cargo-win-msvc-64 |
Close #2082.
Adding
--force
(-f
) instructs cargo to overwrite existing binaries (updating the metadata accordingly).This allows updating crates via
cargo install -f <crate>
.Installation happens in two stages now: binaries are copied into a temporary subdirectory of the destination first, then moved into destination. This should catch some errors earlier.
In case of installation error cargo will remove new binaries but won't attempt to undo successful overwrites.