But if you compare to C/C++ at least with Rust you _can_ but aren't required to use dependencies. In C/C++ if you want to, it's a _massive_ pain.
[edit] typos
As someone who works in cybersecurity and works closely with our developers, a lot of them tend to inherently trust third-party code with no auditing of the supply chain. I am always fighting that while yes, we don't need to reinvent the wheel and libraries/packages are important, our organzation and developers need to be aware of what we are bringing into our network and our codebase.
This is how I think it should be of course. Like I said, I'm not against the use of third-party code or dependencies, I'm against using them without performing any audit of that code.
Perplexingly, the original commenter seems to understand that this doesn't matter, and then handwaves away the correct conclusion.
I'd like to be able to pick a few libraries without incurring a huge ongoing audit burden. If I have to exclude many popular libraries because they have oodles of dependencies, that both makes searching more laborious and limits my choices.
Yes, knowing that would be helpful!
Is there a way to whitelist owners/publishers in Cargo?
There is really just a handful of crates that nearly often get pulled in and probably like 5 authors across them.
Supply chain harderning is pretty easy in rust: caro-deny, cargo-suply-chain, cargo-crev, cargo-vet, cargo-{s}bom and probably a few more I can't remember.
This starts from explaining outright which dependencies they have and why.
It's not so much direct dependencies that bother me: it's an exponential explosion of transitive dependencies.
Also, seeing an “end product” with dozens of dependencies doesn't bother me much; a library does.
Should every physics/ML/etc library have to write their own array abstractions and operators? If every networking library had to write and ship their own async executor logic, I can safely posit that would be about 100x worse than it is now.
The alternative to “zero dependencies” isn’t full “JS/NPM-dumpster-fire”.
So how many dependencies are there truly when you peel away the first layer of the onion?
The obvious answer is "N crates is N dependencies", because each crate represents a discrete sequence of atomic software release packages.
In the absence of a standardized mechanism to group crates together, we have to fall back to informal methods, like "I know all these authors personally because I'm an insider", or "these crates seem to be related even though I'm unsure how to guarantee they'll stay that way".
You can take a hard line and insist that nobody should run a single line of code they haven't reviewed, but that severely constrains the ability of a typical org to use the wider ecosystem at all. Not every org has the expertise on staff to pore over diverse Rust code and confidently state that it has no issues, and even those that do have to consider whether paying that cost is good risk management.
It would be nice if there was a more reliable way to simplify the evaluation of publisher trust centers, especially for orgs who aren't going to audit code but don't want to blindly take in anything.
What's the status of potential distributed code review systems like cargo-crev?
No, and I think this is the crucial thing that people who have experience with NPM overlook when it comes to Rust. Rust emphatically does not have a culture of single-function microlibraries, instead libraries are split out by purpose, in the same way you would modularize a C codebase.
Remember, Rust crates are not just units of distribution, they are also units of translation (a.k.a. compilation units), so the same pressures that cause people to split C projects into multiple files results in people splitting Rust projects into multiple crates.
Distributed code review is a brute-force style solution. Republishing collections of crates under a single name/version is a dimensionality-reduction and responsibility-concentration style solution. I suspect pure-PR style solutions will be ineffective. What other kind of solutions are there?
It is not as simple as you say. Sometime it is better to know all of you dependencies are static linked at build time and specified when you are releasing your code. And the more sane you build system is the harder it is to add shellcode to your dependency's tarball and build scripts without turning peoples heads with random unsafe code.
If the xz backdoor had not been found due to dumb luck, it could have persisted for a long time. Backdoors have persisted for years before, maybe even decades. It's also a package with a lot of eyes on it compared to obscure packages. So I don't think you're right even a little bit, especially in huge projects or projects with LOTS of dependencies.
When projects ship 600 dependencies it's really easy.
> not easy, fast or reliable for long.
It does not need to be long. One day is enough to compromise a system or a thousand.
Isn’t the best argument for open source code that it has so many people, most companies can not afford such a global quality assurance.
The amount of code you have to review stays the same.
Lots of packages have a `-macros` or `-derive` transient dependency, meaning a single dependency can end up coutning as 3 additional dependencies.
Rust makes it simple to split packages into workspaces - for example, regex[1] consists of `regex-automata` and `regex-syntax` packages.
This composition and separation of concerns is a sign of good design, and not an npm-esque hellhole.
This is assuming that the audit consists of validating dependency authorship, and not the more labor-intensive approach of reviewing dependency code.
That’s… the whole rationale about not liking lots of small packages.
Either way, with rust it's a handful of authors, but just because they are proven to be good faith actors, doesn't mean trust in their code is implied when we're talking about supply chain hardening.
> This is assuming that the audit consists of validating dependency authorship, and not the more labor-intensive approach of reviewing dependency code.
So, obviously: authors.
I took your reply of "hard no" to be a rejection of validating authors as sufficient hardening and an assertion that only line-by-line code review meets your standards. Fine, but if your answer is always going to be "doesn't matter, not good enough", we can't have a reasonable conversation about how best to validate authors.
e.g. go dependencies are counted on modules (roughly git repos), rather than packages (directories, compilation units). java is counted in packages rather than classes.
(I would genuinely be interesting in an experiment which pushes this as far as possible: what if each function was a 'package'? There's already a decent understanding of how dependencies within a library work in the compiler, what if that extended to the package manager? You would know exactly what code you actually needed, and would only pull in exactly what was necessary)
A non-obvious issue is that database engines have peculiar requirements for how libraries are designed and implemented which almost no conventional library satisfies. To make matters worse, two different database implementations may have different requirements in this regard, so you can't even share libraries between databases. There are no black boxes in good database engines.
Looking at the dependencies list (https://gist.github.com/tisonkun/06550d2dcd9cf6551887ee6305e...) I see plenty of reasonable things like:
* Base64/checksum/compression encoding libraries
* Encryption/hash libraries
* Platform-specific bindings (likely conditional dependencies)
* Bit hacking/casting/zero-copy libraries like bytemuck, zerocopy, zero-vec, etc.
* "Small"/stack allocated data structure libraries (smallvec, tinystr, etc.)
* Unicode libraries
There are certainly things that would add bloat too, but I think it's silly to pretend like everything here is something a database engine would need custom implementations of.
Combine this with the challenge of implementations being async, non-allocating, compatible with explicitly paged memory, etc and it generally becomes worth the effort.
You'll find more libraries used at the periphery for integration and compatibility where it matters less but not in the core.
I'd rather an author pulls in a tinyvec/serde than tries to make a bespoke implementation.
That’s fine, I have not objection to hot takes, but don’t conflate your limited experience with reality.
I get it that you work on a geospatial database and understand this field better than I do, but why so rude and dismissive? Work on that.
In the case where the answer is "zero", then that means that one does not actually need a package manager at all, in which case the features of the package manager are not relevant to the choice of language. This would imply that the parent commenter has no need to reject Rust.
TBF this has nothing to do with dependency complexity and everything to do with semantic complexity. You could easily do this without using any dependencies at all.
unless you're downloading dependencies during the build or something like that, of course.
With over 600 dependencies, the probability goes up and up.