←back to thread

441 points longcat | 1 comments | | HN request time: 0s | source
Show context
f311a ◴[] No.45038992[source]
People really need to start thinking twice when adding a new dependency. So many supply chain attacks this year.

This week, I needed to add a progress bar with 8 stats counters to my Go project. I looked at the libraries, and they all had 3000+ lines of code. I asked LLM to write me a simple progress report tracking UI, and it was less than 150 lines. It works as expected, no dependencies needed. It's extremely simple, and everyone can understand the code. It just clears the terminal output and redraws it every second. It is also thread-safe. Took me 25 minutes to integrate it and review the code.

If you don't need a complex stats counter, a simple progress bar is like 30 lines of code as well.

This is a way to go for me now when considering another dependency. We don't have the resources to audit every package update.

replies(17): >>45039115 #>>45039225 #>>45039464 #>>45039724 #>>45039994 #>>45040021 #>>45040056 #>>45040113 #>>45040151 #>>45040162 #>>45040972 #>>45041479 #>>45041745 #>>45044165 #>>45045435 #>>45045983 #>>45052913 #
coldpie ◴[] No.45039464[source]
> People really need to start thinking twice when adding a new dependency. So many supply chain attacks this year.

I was really nervous when "language package managers" started to catch on. I work in the systems programming world, not the web world, so for the past decade, I looked from a distance at stuff like pip and npm and whatever with kind of a questionable side-eye. But when I did a Rust project and saw how trivially easy it was to pull in dozens of completely un-reviewed dependencies from the Internet with Cargo via a single line in a config file, I knew we were in for a bad time. Sure enough. This is a bad direction, and we need to turn back now. (We won't. There is no such thing as computer security.)

replies(12): >>45039683 #>>45039767 #>>45039803 #>>45039880 #>>45042370 #>>45043322 #>>45043362 #>>45045627 #>>45045717 #>>45046052 #>>45046055 #>>45046709 #
rootnod3 ◴[] No.45039683[source]
Fully agree. That is why I vendor all my dependencies. On the common lisp side a new tool emerged a while ago for that[1].

On top of that, I try to keep the dependencies to an absolute minimum. In my current project it's 15 dependencies, including the sub-dependencies.

[1]: https://github.com/fosskers/vend

replies(2): >>45039849 #>>45039853 #
skydhash ◴[] No.45039849[source]
Vendoring is nice. Using the system version is nicer. If you can’t run on $current_debian, that’s very much a you problem. If postgres and nginx can do it, you can too.
replies(4): >>45040065 #>>45040128 #>>45040130 #>>45042347 #
imiric ◴[] No.45042347[source]
That is an impossible task in practice for most developers.

Many distros, and Debian in particular, apply extensive patches to upstream packages. Asking a developer to depend on every possible variation of such packages, across many distros, is a tall order. Postgres and Nginx might be able to do it, but those are established projects with large teams behind them and plenty of leverage. They might even be able to influence distro maintainers to their will, since no distro will want to miss out on carrying such popular packages.

So vendoring is in practice the only sane choice for smaller teams and projects.

Besides, distro package managers carrying libraries for all programming languages is an insane practice that is impossible to scale and maintain. It exists in this weird unspecified state that can technically be useful for end users, but is completely useless for developers. Are they supposed to develop on a specific distro for some reason? Should it carry sources or only binaries? Is the dependency resolution the same for all languages? Should language tooling support them? It's an entirely ridiculous practice that should be abandoned altogether.

Yes, it's also silly that every language has to reinvent the wheel for managing dependencies, and that it can introduce novel supply chain attack vectors, but the alternative is a far more ludicrous proposition.

replies(2): >>45042526 #>>45042660 #
skydhash ◴[] No.45042526[source]
You do not depends on a package, you depends on its API. Implementation details shouldn't matter if behavior stays the same. Why do you care if the distro reimplemented ffmpeg or libcurl, or use an alternative version built with musl? Either the library is there or it's not. Or the minimum version you want is there or it's not. You've already provided the code and the requirement list, it's up to the distro maintainer or the user to meet them. If the latter patch the code, why do you care that much?

And if a library have a feature flags, check them before using the part that is gated.

replies(2): >>45043069 #>>45043378 #
imiric ◴[] No.45043378{3}[source]
There's no guarantee that software/library vX.Y.Z packaged by distro A will be identical in behavior to one packaged by distro B. Sure, distro maintainers have all sorts of guidelines, but in reality, mistakes happen, and there can be incompatibilities between the version a developer has been testing against, and one the end user is using.

Relying on feature flags is a pie in the sky solution, and realistically developers shouldn't have to be concerned with such environmental issues. Dependency declarations should be relied on to work 100% of the time, whether they're specified as version numbers or checksums. Since they're not reliable in practice, vendoring build and runtime dependencies is the only failproof method.

This isn't to say that larger teams shouldn't support specific distros directly, but my point is that smaller teams simply don't have the resources to do so.

replies(1): >>45043540 #
skydhash ◴[] No.45043540{4}[source]
But why do you care that much about how the user is running your code?

Maybe my laptop is running Alpine and I patches some libraries to support musl and now some methods are NOP. As the developer, why does it matter to you?

You would want me to have some chroot or container installation for me to install a glibc based system so that you can have a consistent behavior on every computer that happens to run your code? Even the ones you do not own?

replies(2): >>45043806 #>>45045125 #
1. imiric ◴[] No.45043806{5}[source]
It matters because as a developer I'll get support requests from users who claim that my software has issues, even when the root cause is unrelated to my code. If I explicitly document that I support a single way of deploying the software, and that way is a self-contained artifact with all the required runtime dependencies, which was previously thoroughly tested in my CI pipeline, then I can expect far less support requests from users.

Again, this matters a lot to smaller projects and teams. Larger projects have the resources to offer extended support for various environments and deployment procedures, but smaller ones don't have this luxury. A flood of support requests can lead to exhaustion, demotivation, and burnout, especially in open source projects and those without a profitable business model. Charging for support wouldn't fix this if the team simply doesn't have the bandwidth to address each request.