I feel very uncomfortable seeing cargo being used as a tool to distribute software.
Cargo is a package manager.
It should build software.
I suppose it’s arguable that it should be able to install developer tooling to help you build things.
However, I feel uncomfortable seeing this type of thing.
Is the installed binary sandboxed? It is namespaced? Is it shared between projects? What causes it to be updated?
Can building a crate update the globally installed version of “foo” by “cargo install” installing a different crate that happens to have a binary with the same name? (Yes, via build.rs, but just as a dependency?)
How would I even know?
There are so many things wrong with this imo.
Building a crate should generally be sandboxed, but this (cargo install as a concept, not this particular app) feels like the goal is the opposite of a sandbox, instead it’s a shared arbitrary named tool that goes into your path by default and gets updated an unknown times.
I feel like this is going to bite the rust community in the foot at some point.
I think you're fundamentally misunderstanding what is going on here, because your questions about "namespacing", "being shared between objects", and "building installing things" suggest your imagining a system that doesn't exist here. Cargo, unlike a system like pip, doesn't have global files*, it doesn't have libraries installed to the system, there is no* global state to corrupt.
The only "side effect" of running a `cargo install` command is that a binary is placed in `~/.cargo/bin`, which most rust programmers will have on their PATH. There are no side effects of running a normal cargo build, it won't update anything outside of the crate you are building (and in the crate you are building, it will only change Cargo.lock and the target directory). There isn't any scary action at a distance.
> What causes it to be updated?
Nothing, except a user manually running `cargo install --force imgcatr`. This is the main criticism of using `cargo install`, it's not a package manager, it's a shortcut to doing the C equivalent of `git clone project && cd project && ./configure --prefix=~/.cargo/bin && make && make install` (but for binaries only, no libraries).
* There is a local cache of checked out code, and the index of crates, which is generally updated every time you run a `cargo build` command that might need anything that isn't local. You can use this cache without touching the internet by specifying `--offline`, at which point the contents of the cache matters. The only reason to do this is if you don't have internet. I'm also ignoring nonsense that people can put in `build.rs` files, but pretty much no one does. Rust will also look for certain global dependencies on your system (namely C style libraries), but it doesn't have any support for putting new ones there.
> command is that a binary is placed in `~/.cargo/bin`, which most rust programmers will have on their PATH
That is a global effect.
> Nothing, except a user manually running `cargo install --force imgcatr`.
I’m absolutely certain build.rs can also do this; you can choose to ignore that if you want.
I hope ignoring it makes it not a thing we have to ever worry about. I guess.
I get it, it’s convenient; but I think people are fooling themselves if they think having a binary on their path is no big deal, or that manually calling “cargo install” is the only way this can happen.
Yes, I agree, that's why I said it is the only one. Moreover the sole purpose of cargo install is to cause that side effect (otherwise you use cargo build, which builds the binaries but doesn't copy them to a shared directory).
> I’m absolutely certain build.rs can also do this
build.rs is running arbitrary code, it can do anything, that's part of what I disclaimed in my asterix. In practice it doesn't do anything. Every packaging system has an escape hatch like this.
Serde shipping a binary was someone embedding a chunk of opaque bytes in their "source code", it's completely unrelated to this discussion and has no effect on what `cargo install` does.
If you install binary blob from the internet, you trust exactly one person and no way to verify if binary matches the source.
If you build with cargo, you can at least verify that the current source matches the binary and the trust of the dependencies is decentralized, with many eyes on them.
There are better ways, but these better ways just use different package managers.
The above is no different than any ”build from source” method.
The go CLI does exactly the same. Python's pip (via setup.py) will do the same, and in an arguably less transparent way iirc. I don't disagree that there are better ways, but it's good enough to get you off the ground.
`pip --user` still installs things to a per-user-global shared folder, that doesn't exist with cargo. If you're going to compare to pip, it's got to be something like "pip, but everything you build gets its own venv".
> I feel very uncomfortable seeing cargo being used as a tool to distribute software. Cargo is a package manager.
but... that's exactly what a package manager is. a tool to package and distribute software. apt, dnf, nix, snap, flatpak, npm, cargo, pip... they're all package managers.
I think their thought was incomplete. It's a language-specific package manager. Out of that list I think there are some that have no business installing packages for use on the greater system. They work fine for development dependencies and project building, but they should stay in their lane when it comes to installing tools to use outside of project development.
oh, that makes sense. it just means the packaging hasn't been taken as far as it can go. once a project is set up for packaging using something like `cargo`, that means it will be that much easier for someone (anyone) to take it one step further and package it in higher-level package managers like `apt` or `dnf` on top. or `snap` or `flatpak`. or a nix/arch recipe.
By only allowing it to be on the PATH when you’re in a specific folder (eg. The binary only ever lives in project/bin, not $user/.shared/bin) and by making the binary filename have a prefix (eg. project-git) so you can’t possibly invoke it when expecting to call a normal cli command (eg git).
Since cargo manages these installs, both would be trivial for it to do; just inconvenient for cli app authors.
But this is not "sandboxed" in any conventional understanding of the term. "sandboxed" would mean that the binary has restricted access to resources like the filesystem, the network etc.
Ok, you’re right, sandboxed isn’t the right word; my bad.
However, it’s more isolated than what currently exists, even if it’s not totally isolated, and it’s an effort to prevent abuse, rather than doing nothing.
My point is that you can contain the impact of cli apps in various ways.
I feel very uncomfortable seeing cargo being used as a tool to distribute software.
Cargo is a package manager.
It should build software.
I suppose it’s arguable that it should be able to install developer tooling to help you build things.
However, I feel uncomfortable seeing this type of thing.
Is the installed binary sandboxed? It is namespaced? Is it shared between projects? What causes it to be updated?
Can building a crate update the globally installed version of “foo” by “cargo install” installing a different crate that happens to have a binary with the same name? (Yes, via build.rs, but just as a dependency?)
How would I even know?
There are so many things wrong with this imo.
Building a crate should generally be sandboxed, but this (cargo install as a concept, not this particular app) feels like the goal is the opposite of a sandbox, instead it’s a shared arbitrary named tool that goes into your path by default and gets updated an unknown times.
I feel like this is going to bite the rust community in the foot at some point.