2022-04-23 07:40:29 +03:00
|
|
|
---
|
2022-04-23 16:41:58 +03:00
|
|
|
title: "git-subtrac and Zig"
|
2022-04-23 07:40:29 +03:00
|
|
|
date: 2022-04-23T05:37:51+03:00
|
|
|
|
draft: true
|
|
|
|
---
|
|
|
|
|
2022-04-23 16:41:58 +03:00
|
|
|
TLDR: I wish plain `git clone <repository>` would check out submodules if they
|
|
|
|
are in the same repository.
|
2022-04-23 07:40:29 +03:00
|
|
|
|
2022-04-23 16:41:58 +03:00
|
|
|
I use [`git-subtrac`][git-subtrac] for some of my projects, and am not very
|
2022-04-23 07:40:29 +03:00
|
|
|
enthusiastic about Zig getting it's own package manager (can we all use
|
|
|
|
git-subtrac and be done with it?). A few weeks ago in a park in Milan my
|
|
|
|
conversation with [Andrew Kelley](https://andrewkelley.me/) was something like:
|
|
|
|
|
2022-04-23 16:41:58 +03:00
|
|
|
- me: "git-subtrac yadda yadda yadda submodules but better yadda yadda yadda".
|
2022-04-23 07:40:29 +03:00
|
|
|
- Andrew: "if I clone a repository that uses git-subtrac with no extra
|
|
|
|
parameters, will it work as expected?"
|
|
|
|
- me: "no, you have to pass `--recursive`, so git will checkout submodules...
|
2022-04-23 16:41:58 +03:00
|
|
|
even if they are already fetched."
|
2022-04-23 07:40:29 +03:00
|
|
|
- Andrew: "then it's a piece-of-shit-approach."
|
|
|
|
|
2022-04-23 16:41:58 +03:00
|
|
|
Uh, I agree. People have not grown muscle memory to clone repositories with
|
|
|
|
`--recursive` flag and never will, so it's impossible to adopt git-subtrac
|
|
|
|
beyond well-controlled silos. Which is why we will have a
|
2022-04-23 07:40:29 +03:00
|
|
|
yet-another-programming-language-specific-package-manager, this time for zig.
|
|
|
|
Or at least my argument for using git-subtrac stops right there.
|
|
|
|
|
2022-04-23 16:41:58 +03:00
|
|
|
Why git-subtrac?
|
|
|
|
----------------
|
|
|
|
|
|
|
|
[`git-subtrac`][git-subtrac] is like "classic" git submodules, but all refs of
|
|
|
|
the dependencies stay in the same repository. Wait, stop here. Repeat after me:
|
|
|
|
_it is git submodules, but all refs stay in the same repository_. I also call
|
|
|
|
it "good vendoring". Since all the deps are in our repo, no external force can
|
|
|
|
make our dependency unavailable.
|
|
|
|
|
|
|
|
It is, howerver, harder to *add* a dependency with submodules than with, say,
|
|
|
|
`go get <dependency>`. Let's talk about adding dependencies.
|
|
|
|
|
|
|
|
Adding dependencies
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
All of the programming languages I've used professionally whose name does not
|
|
|
|
start with "c"[^1] have package managers[^2], which make "dependency
|
|
|
|
management" easy. These package managers will download and build the dependency
|
|
|
|
tree, sometimes conveniently generate a "lock file", so your project has an
|
|
|
|
illusion of being "reproducible".
|
|
|
|
|
|
|
|
C/C++ projects I've been involved usually had 1-5 non-system dependencies,
|
|
|
|
whereas all others -- tens or hundreds. This uncovers an obvious correlation:
|
|
|
|
if it's easy to add dependencies, they will be added. En masse. Not adding
|
|
|
|
dependencies in Go/Python/whatever requires discipline. Slip once, add some
|
|
|
|
crap -- it will be very hard to remove, as changing dependencies often require
|
|
|
|
large rewrites. Not adding dependencies in C/C++, however, is the path of least
|
|
|
|
resistance. However, in the long term, my C/C++ projects tended to survive
|
|
|
|
longest (or required least amount of changes to build and run after the world
|
|
|
|
moved on) just because of this.
|
|
|
|
|
|
|
|
Making it easy to depend on external code is is convenient during development,
|
|
|
|
but frees (or denies, depending how one looks at it) developers from their
|
|
|
|
basic right (or obligation?) to understand them. And adds real long-term
|
|
|
|
maintenance costs.
|
|
|
|
|
|
|
|
To sum up, the "modern" languages optimize for initial development experience,
|
|
|
|
not maintenance. And as [Corbet says][linux-rust]. "We can't understand why
|
|
|
|
Kids These Days just don't want to live that way". Kids want to build, John,
|
2022-04-24 06:45:41 +03:00
|
|
|
not maintain. This house is in desperate need of maintenance, but my son
|
|
|
|
refuses to do so, and builds a new car instead.
|
|
|
|
|
2022-04-24 07:03:24 +03:00
|
|
|
{{<img src="https://dl.jakstys.lt/mtpad/house.jpg"
|
2022-04-24 06:45:41 +03:00
|
|
|
alt="House of Duplo pieces"
|
|
|
|
caption="House of Duplo pieces"
|
|
|
|
width="50%"
|
|
|
|
>}}
|
2022-04-23 16:41:58 +03:00
|
|
|
|
|
|
|
This is why I am always hesitant to pull in code to my project, and have a my
|
|
|
|
dependency checklist:
|
2022-04-23 07:40:29 +03:00
|
|
|
|
|
|
|
- Obvious: does it work at all?
|
|
|
|
- How easy is it to build, run and run it's tests?
|
|
|
|
- Is it well written? API surface, documentation, tests, error handling, error
|
|
|
|
signaling, logging, metrics (if applicable), etc.
|
|
|
|
- It's system dependencies.
|
|
|
|
- It's transitive dependencies.
|
|
|
|
|
|
|
|
Zooming into the last part: C projects tend to do it well. For Go and Python
|
|
|
|
projects a small number of dependencies is often a sign of care and quality on
|
|
|
|
other areas, too. [mattn/go-sqlite3](https://github.com/mattn/go-sqlite3),
|
|
|
|
[google/brotli](https://github.com/google/brotli),
|
|
|
|
[apenwarr/redo](https://github.com/apenwarr/redo),
|
|
|
|
[cmph](http://cmph.sourceforge.net/) are good examples.
|
|
|
|
|
|
|
|
If a dependency is well written, but has more transitive dependencies than I
|
|
|
|
need and there is no good alternative, I will fork it and remove unnecessary
|
|
|
|
code and dependencies. My recent example is
|
|
|
|
[sql-migrate](https://github.com/motiejus/sql-migrate).
|
|
|
|
|
|
|
|
If I may combine Corbet's views with mine: if we understand and audit our
|
|
|
|
dependencies (and transitive ones), we will have less dependencies and a more
|
|
|
|
maintainable system. Win-win.
|
|
|
|
|
|
|
|
Which brings us to...
|
|
|
|
|
|
|
|
Transitive dependencies and git-subtrac
|
|
|
|
---------------------------------------
|
|
|
|
|
|
|
|
[`git-subtrac`][git-subtrac] does not deal with transitive dependencies. At
|
|
|
|
least not directly. Or I am not aware of it. Ok, I haven't tried.
|
|
|
|
|
|
|
|
If we audit and thus understand our dependencies, we will be able to add
|
|
|
|
transitive ones to our project even without support of git-subtrac. So perhaps
|
|
|
|
git-subtrac shouldn't care?
|
|
|
|
|
|
|
|
Conclusion
|
|
|
|
----------
|
|
|
|
|
2022-04-23 16:41:58 +03:00
|
|
|
Can git checkout local submodules when they are in the same repository, so our
|
|
|
|
conversation of reconsidering (or not having) a zig package manager doesn't
|
|
|
|
stop after 5 seconds?
|
|
|
|
|
|
|
|
[^1]: Alphabetically: Erlang, Go, Javascript, PHP, Perl, Python.
|
|
|
|
[^2]: Usually written in the same language. Zoo of package managers (sometimes
|
|
|
|
a couple of popular ones for the same programming language) is a can of worms
|
|
|
|
in an on itself worth another blog post.
|
2022-04-23 07:40:29 +03:00
|
|
|
|
|
|
|
[git-subtrac]: https://github.com/apenwarr/git-subtrac/
|
|
|
|
[linux-rust]: https://lwn.net/SubscriberLink/889924/a733d6630e3b5115/
|