about summary refs log tree commit diff homepage
path: root/blog/dedep.md
blob: c251880f3b198b1ea71f1090442a6afc1fa0b923 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
+++
rss = "Call for Participation: De-Dependency December"
date = Date(2022, 11, 10)
tags = ["fun", "pkg"]
+++

# De-Dependency December

> As we mature, the dependency graph matures with us.

## Exposition

In the [occasional fights] between system and language packagers,
[I'm known to take the downstream camp.][ipwhl]  As a user, there are
lots of things I take for granted.  I install the stuff I need,
occasionally upgrade the system, and everything gets updated.
Vulnerability in a library used by multiple programs?  Its patched version
gets swapped in within a few hours (given it's not [vendored or pinned]).
[Most][debian] [distributions][fedora] [even][arch] [apply][opensuse]
[hardening][gentoo] [flags][nixpkgs] that [some bugs aren't even exploitable
in the first place][openssl].  They create a [safe place] for me to comfortably
express myself at work and at home.

Recently on my work computer, I've switched to Guix System, which has yet
many packages.  Looking into the way to package programs I use
and ongoing efforts, I realized the colossal number of transitive dependencies
of [certain software] and the impracticality for a user union (i.e. a distro)
to maintain such set of [micro packages] in every language.

## Confrontation

This gave me a more serious thought on software sustainability.  Such topic
often reminds us of energy consumption, modularity, development model,
or even style (clean code).  End-users (including self-hosts),
on the other hand, ask the following questions to decide upon installing
and keeping a piece of software:

- Can I *trust* installing this won't do anything funny to my machine?
- How much [effort] I need to prevent people from doing funny things
  to my machine if the software includes [something that gets on the front page
  of some magazines][heartbleed] tomorrow?
- How much of my limited resources will it take to run or [simply exist]?

There are certain intersections in concerns of enterprises and users,
however it's worth noticing that distributions are almost exclusively optimized
to cater for the users' need.  Not only they [fight for the users][tron],
they *are* the users.  Suppose you don't want to write yellow-glowing programs,
you should [make the life of downstream package maintainers easier][distros].
No, it does not count if you push them to give in to run [`go mod vendor`][go]
or [download from NPM recursively][node2nix].

## Resolution

*So how do I write software that is easy to package*, you may ask.
If you followed the articles linked above, you've probably already
figured that out.  It's less about what you *write* and more about
what you *use*.  When someone complains a program is difficult
to build from source, certainly it's not about how hard it is to type,
say `make install`, but acquiring the dependencies for that to run
successfully and the result will work.

Lower the number of dependencies will absolutely help.  To put it bluntly,
you can't have a problem with dependencies if there's none of them.
This sounds like reinventing the wheel, but if the use case is common enough,
you might find what you need in the standard library.[^rust]
I've been restricting myself from using third-party libraries
for new side projects and it actually worked for my most recent ones:

- [Phylactery], a static comics web server on Go with [CBZ] parsing
  and concurrent request handling
- [Fead], an [SSG] plugin in Python for advertising others’ feed
  with parallel HTTP request, parsing of RSS 2 and Atom and CLI argument parsing

Even for such simple use cases, there are still many libraries in the wild
that can handle more data formats, are more convenient to use
or more performant.  On the other hand, the amount of maintenance needed
to keep the programs safe indefinitely for a user is much lower
thanks to the small dependency footprint.

What I'm asking you to give a try in the advent days[^advent] is not as drastic.
Look through your works, find a library you require for a small portion
of its [power], or something can be implemented specifically for your project
using reasonable effort (w.r.t. the whole codebase).  This is not just
for the sake of maintainability: [being less general, the new implementation
can likely outperform the replaced public library][context].

![Multiple types of sockets installed on the same wall](/assets/outlets.jpg)

In many cases, you will find yourself making use of the standard library.
Standards make life much easier, [if only][standards] people can come up
with an agreement.  Or maybe they don't have to.  Maybe each could choose
among the [utilities libraries].  At the end of the day, it's the total number
of packages that can have bugs to be reported upstream and patched that matters.

That being said, please keep an eye on the standard library the same way
you (should) watch your other dependencies, just in case what you need
is finally added.  Worry not of backward incompatibility, [users of LTS systems
are content with older versions][old] of your software.

## Fall and Catastrophe

Just kidding, I'm offering [answers], not [tragedies].  Winter is coming,
join me in a De-Dependency December and fight for the users!

[^rust]: Unless you use Rust.
[^advent]: I'm not Christian, but I had fun with [AoC] and [Neopets] before.

[occasional fights]: https://www.youtube.com/watch?v=stChOsejLEQ
[ipwhl]: https://man.sr.ht/~cnx/ipwhl
[vendored or pinned]: https://blogs.gentoo.org/mgorny/2021/02/19/the-modern-packagers-security-nightmare
[debian]: https://wiki.debian.org/Hardening
[fedora]: https://fedoraproject.org/wiki/Changes/Harden_All_Packages
[arch]: https://wiki.archlinux.org/title/Arch_package_guidelines/Security
[gentoo]: https://wiki.gentoo.org/wiki/Hardened/Toolchain#Changes
[opensuse]: https://en.opensuse.org/openSUSE:Security_Features
[nixpkgs]: https://nixos.org/manual/nixpkgs/stable#sec-hardening-in-nixpkgs
[openssl]: https://xeiaso.net/blog/openssl-alarm-fatigue
[safe place]: https://www.youtube.com/watch?v=205ODJgAEik
[certain software]: https://issues.guix.gnu.org/55903
[micro packages]: https://raku-advent.blog/2021/12/06/unix_philosophy_without_leftpad

[effort]: https://xkcd.com/303
[heartbleed]: https://heartbleed.com
[simply exist]: https://ludocode.com/blog/flatpak-is-not-the-future
[tron]: https://en.wikipedia.org/wiki/Tron
[distros]: https://drewdevault.com/2021/09/27/Let-distros-do-their-job.html
[go]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/go/module.nix
[node2nix]: https://github.com/svanderburg/node2nix

[Phylactery]: https://trong.loang.net/phylactery
[CBZ]: https://en.wikipedia.org/wiki/Comic_book_archive
[Fead]: https://trong.loang.net/~cnx/fead
[SSG]: https://en.wikipedia.org/wiki/Static_site_generator
[power]: https://www.youtube.com/watch?v=3Mpyias9ek4
[context]: https://guide.handmade-seattle.com/c/2021/context-is-everything
[standards]: https://xkcd.com/927
[utilities libraries]: https://raku-advent.blog/2021/12/11/unix_philosophy_without_leftpad_part2
[old]: https://wiki.debian.org/DontBreakDebian#Don.27t_suffer_from_Shiny_New_Stuff_Syndrome

[answers]: https://en.wikipedia.org/wiki/Three-act_structure
[tragedies]: https://en.wikipedia.org/wiki/Dramatic_structure#Freytag's_pyramid
[AoC]: https://adventofcode.com
[Neopets]: https://breezewiki.com/neopets/wiki/Advent_Calendar