aboutsummaryrefslogtreecommitdiff
path: root/_posts/2020-10-05-swift2nix-run-swift-inside-nix-builds.md
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2020-10-05 09:28:27 -0300
committerEuAndreh <eu@euandre.org>2020-10-05 09:28:27 -0300
commitec72d34d1aa92d63dac80aaf27f28e44607b7d3b (patch)
treed82b3b30cca9f7b447ee3a05bf762657792beb7d /_posts/2020-10-05-swift2nix-run-swift-inside-nix-builds.md
parentdb post: Add "mediator" category (diff)
downloadeuandre.org-ec72d34d1aa92d63dac80aaf27f28e44607b7d3b.tar.gz
euandre.org-ec72d34d1aa92d63dac80aaf27f28e44607b7d3b.tar.xz
swift2nix: proofread on the browser
Diffstat (limited to '_posts/2020-10-05-swift2nix-run-swift-inside-nix-builds.md')
-rw-r--r--_posts/2020-10-05-swift2nix-run-swift-inside-nix-builds.md47
1 files changed, 27 insertions, 20 deletions
diff --git a/_posts/2020-10-05-swift2nix-run-swift-inside-nix-builds.md b/_posts/2020-10-05-swift2nix-run-swift-inside-nix-builds.md
index cee39e0..3173165 100644
--- a/_posts/2020-10-05-swift2nix-run-swift-inside-nix-builds.md
+++ b/_posts/2020-10-05-swift2nix-run-swift-inside-nix-builds.md
@@ -1,5 +1,5 @@
---
-title: swift2nix: Run Swift inside Nix builds
+title: "swift2nix: Run Swift inside Nix builds"
date: 2020-10-05
layout: post
lang: en
@@ -48,7 +48,7 @@ Swift believes it has already downloaded and checked-out all dependencies, and
just moves on to building them.
I've worked on it just enough to make it usable for myself, so beware of
-unimplemented cases.
+unimplemented cases. Patches welcome.
[nix]: https://nixos.org/
[swift2nix]: https://git.euandreh.xyz/swift2nix/about/
@@ -78,16 +78,15 @@ control of the entire build of the dependencies.
This is a recurrent problem in package managers, but I don't see it as an
inherit one. There's nothing about a "package manager" that prevents it from
*declaring* what it expects to encounter and in which format. The *declaring*
-part is important: it should be a file with data, not code, otherwise you're
-back in the same problem (JSON, TOML, edn, etc.). Those work in any language,
-and they can cooperate happily. That's not the same as a lockfile: those are
-just pinned versions of packages in the dependency tree.
+part is important: it should be data, not code, otherwise you're back in the
+same problem, just like lockfiles are just data. Those work in any language, and
+tools can cooperate happily.
-There's no need for this expectation to be standartized, or be made compatible
-across languages. That would lead to a poor format that no package manager
-really likes. Instead, If every package manager could say out loud what it wants
-to see exactly, than more tools like swift2nix could exist, and they would be
-more reliable.
+There's no need for this declarative expectation to be standartized, or be made
+compatible across languages. That would lead to a poor format that no package
+manager really likes. Instead, If every package manager could say out loud what
+it wants to see exactly, than more tools like swift2nix could exist, and they
+would be more reliable.
This could even work fully offline, and be simply a mapping from the lockfile
(the `Package.resolved` in Swift's case) to the filesystem representation. For
@@ -101,8 +100,9 @@ usually have fuzzy boundaries and tight coupling between:
1. resolving the dependency tree and using some heuristic to pick a package
version;
2. generating a lockfile with the exact pinned versions;
-3. downloading the dependencies present on the lockfile into some local folder;
-4. arranging the dependencies in a meaniful way for itself;
+3. downloading the dependencies present on the lockfile into some local cache;
+4. arranging the dependencies from the cache in a meaniful way for itself inside
+ the project;
5. work using the dependencies while *assuming* that step 4 was done.
When you run `npm install` in a repository with no lockfile, it does 1~4. If you
@@ -115,9 +115,9 @@ Instead a much saner approach could be:
1. this stays the same;
2. this also stays the same;
-3. be able to generate some JSON which represents the local expected filesystem
- layout with dependencies (i.e. exposing what the package manager expects to
- find), let's call it `local-registry.json`;
+3. be able to generate some JSON/TOML/edn which represents the local expected
+ filesystem layout with dependencies (i.e. exposing what the package manager
+ expects to find), let's call it `local-registry.json`;
4. if a `local-registry.json` was provided, do a build using that. Otherwise
generate its own, by downloading the dependencies, arranging them, etc.
@@ -125,6 +125,10 @@ The point is just making what the package manager requires visible to the
outside world via some declarative data. If this data wasn't provided, it can
move on to doing its own automagic things.
+By making the expectation explicit and public, one can plug tools *à la carte*
+if desired, but doesn't prevent the default code path of doing things the exact
+same way they are now.
+
## Problems with "*2nix" tools
I have to admit: I'm unhappy with most of they.
@@ -133,10 +137,11 @@ They conflate "using Nix" with "replicating every command of the package manager
inside Nix".
The avoidance of an "easy" interface that I mentioned above comes from me
-fighting with some of the "*2nix" tools much like I have to fight with package
+fighting with some of the "\*2nix" tools much like I have to fight with package
managers: I don't want to offload all build responsabilities to the "*2nix"
tool, I just want to let it download some of the dependencies and get out of the
-way.
+way. I want to stick with `npm test` or `cargo build`, and Nix should only
+provide the environment.
This is something that [node2nix][node2nix] does right. It allows you to build
the Node.js environment to satisfy NPM, and you can keep using NPM for
@@ -144,6 +149,7 @@ everything else:
```shell
ln -s ${node2nix-package.shell.nodeDependencies}/lib/node_modules ./node_modules
+npm test
```
Its natural to want to put as much things into Nix as possible to benefit from
@@ -156,7 +162,8 @@ how NPM runs some things will be future-compatible, since node2nix isn't trying
to replicate what NPM does, or fiddling with NPM's internal.
**A "*2nix" tool should build the environment, preferebly from the lockfile
-directly and offload everything else to the package manager.**
+directly and offload everything else to the package manager**. Everything else
+is just nice-to-have.
swift2nix itself could provide an "easy" interface, something that allows you to
write:
@@ -180,7 +187,7 @@ dependencies to appear on the filesystem, i.e. `local-registry.json`. This
allows package managers to provide an API so that external tools can create
mirrors, offline builds, other registries, isolated builds, etc.
-"*2nix" tools should build simple functions that leverage that
+"\*2nix" tools should build simple functions that leverage that
`local-registry.json`[^local-registry] data and offload all the rest back to the
package manager itself. This allows the "*2nix" to not keep chasing the package
manager evolution, always trying to duplicate its behaviour.