feat: add nixos hacks
This commit is contained in:
parent
caedd08804
commit
a7733d1d2b
2 changed files with 202 additions and 0 deletions
193
content/Hacks/nixos-cheat-sheet.md
Normal file
193
content/Hacks/nixos-cheat-sheet.md
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
---
|
||||||
|
id: nixos-cheat-sheet
|
||||||
|
aliases: []
|
||||||
|
tags:
|
||||||
|
- nixos
|
||||||
|
- nixpkgs
|
||||||
|
- linux
|
||||||
|
---
|
||||||
|
|
||||||
|
# Assorted NixOS hacks and tricks
|
||||||
|
|
||||||
|
The Nix package manager and NixOS Linux distribution are woefully
|
||||||
|
underdocumented. There are many, many powerful features that are difficult to
|
||||||
|
find, sans directly reading through source code.
|
||||||
|
|
||||||
|
I can't fix that, but this document serves as a personal cheat sheet of all the
|
||||||
|
small Nix features that I don't want to forget.
|
||||||
|
|
||||||
|
## Derivations
|
||||||
|
|
||||||
|
Stuff related to writing derivations of software.
|
||||||
|
|
||||||
|
### Sparse Checkout with fetchGit (and friends)
|
||||||
|
|
||||||
|
You can do sparse checkouts when using `fetchgit` and its friends
|
||||||
|
`fetchFromGitHub`, etc. This is useful if you're cloning a large repository and
|
||||||
|
know you only need one specific directory. If you only need a specific file,
|
||||||
|
consider `fetchurl`.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
fetchgit {
|
||||||
|
url = "https://github.com/foo/bar";
|
||||||
|
hash = "sha256-0000000000000000000000000000000";
|
||||||
|
|
||||||
|
# takes a list of directories that should be checked out
|
||||||
|
sparseCheckout = ["dir", "another/dir", "foo/bar/dir"];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### The `callPackage` pattern
|
||||||
|
|
||||||
|
This isn't even a note for myself since I use this feature so much, but I'm add
|
||||||
|
it anyways so I can point to it as a reference.
|
||||||
|
|
||||||
|
When you look at `package.nix` files in the source code of `nixpkgs`, you'll
|
||||||
|
see they typically take the form:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
stdenv,
|
||||||
|
libfoo,
|
||||||
|
libbar,
|
||||||
|
fetchFromGitHub,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
nativeBuildInputs = [ stdenv libfoo libbar ];
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
# blah blah
|
||||||
|
};
|
||||||
|
# rest of file omitted for brevity
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It's a lambda (anonymous function) that takes in an attrset of everything the
|
||||||
|
derivation needs, and returns the derivation. As you clearly see, the `...`
|
||||||
|
means that the attrset contains all of the attributes specified, but also
|
||||||
|
arbitrarily more.
|
||||||
|
|
||||||
|
Exactly what attributes are available in this input attrset? It turns out that
|
||||||
|
this attrset is actually populated with the _entirety of nixpkgs_. Basically,
|
||||||
|
any package that can be referencd from `pkgs.xxx` is available in that input
|
||||||
|
attrset.
|
||||||
|
|
||||||
|
This is very useful for writing clean derivations. Oftentimes I see people
|
||||||
|
haphazardly pass `pkgs` around to all their derivations and directly make use
|
||||||
|
of it. While this is fine in small derivations, it quickly gets messy in large
|
||||||
|
ones. I prefer to always write non-trivial derivations using the nixpkgs
|
||||||
|
pattern. However, how do we go from a file like the example above to an actual
|
||||||
|
package that we can, say, output from a flake?
|
||||||
|
|
||||||
|
There's a function called `pkgs.callPackage` that handles precisely this task.
|
||||||
|
It takes in two arguments. Here is its pseudo type signature:
|
||||||
|
|
||||||
|
```
|
||||||
|
callPackage :: file -> attrset -> package
|
||||||
|
```
|
||||||
|
|
||||||
|
The first argument is the file that contains the derivation as shown in the
|
||||||
|
example. The second argument is an attrset that allows you to pass or overwrite
|
||||||
|
any values in the attrset passed to argument 1.
|
||||||
|
|
||||||
|
Oftentimes the second argument is not even needed and so you simply pass an
|
||||||
|
empty attrset (`{ }`).
|
||||||
|
|
||||||
|
```nix
|
||||||
|
packages.default = pkgs.callPackage ./my-derivation.nix { };
|
||||||
|
```
|
||||||
|
|
||||||
|
An example of the second argument in use is in a situation where you have a
|
||||||
|
flake that provides multiple packages, but one of these packages depends on the
|
||||||
|
other. Then, you can pass the packages to each other using the attrset
|
||||||
|
argument.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
packages = rec {
|
||||||
|
foo = pkgs.callPackage ./foo.nix { inherit bar; };
|
||||||
|
bar = pkgs.callPackage ./bar.nix { };
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, in the corresponding derivation of `foo`, `bar` will be available as an input:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# file: foo.nix
|
||||||
|
{
|
||||||
|
stdenv,
|
||||||
|
libblah,
|
||||||
|
bar, # the bar package we provided is now available here
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
buildInputs = [ bar ];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## nixpkgs and the nixpkgs lib
|
||||||
|
|
||||||
|
General stuff related to quirks in nixpkgs and `lib`.
|
||||||
|
|
||||||
|
## Flakes
|
||||||
|
|
||||||
|
Niche features of Nix flakes.
|
||||||
|
|
||||||
|
### Nix flake inputs have additional properties
|
||||||
|
|
||||||
|
Everyone knows the common properties of Nix flake inputs: the standard outputs
|
||||||
|
like `packages`, `apps`, `nixosModules`, etc.
|
||||||
|
|
||||||
|
However, there a few that I have seen seldom used and hard to find mentions of
|
||||||
|
in documentation
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
inputs.cool-flake.url = "github:hackerman/cool-flake";
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{ self, cool-flake, ...}:
|
||||||
|
{
|
||||||
|
# gives the commit hash of the flake
|
||||||
|
rev = cool-flake.rev;
|
||||||
|
|
||||||
|
# gives the UNIX timestamp of the commit of the flake
|
||||||
|
lastModified = cool-flake.lastModified;
|
||||||
|
|
||||||
|
# you can also get these attributes on the current flake using `self`
|
||||||
|
|
||||||
|
# gets current git commit hash
|
||||||
|
# caveat: this property isn't defined if the git tree is dirty (there are uncommitted changes)
|
||||||
|
selfRev = self.rev;
|
||||||
|
|
||||||
|
# I often use this pattern due to the above reason
|
||||||
|
selfRev' = if (self ? rev) then self.rev else "FALLBACK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## NixOS
|
||||||
|
|
||||||
|
Things from the NixOS distribution, including the module system.
|
||||||
|
|
||||||
|
## Misc
|
||||||
|
|
||||||
|
Stuff to do with other stuff. Potentially community made flakes.
|
||||||
|
|
||||||
|
### Set the right time in Typix (and LaTeX)
|
||||||
|
|
||||||
|
When using Typix to compile Typst documents, sometimes it's a little _too
|
||||||
|
reproducible_. Attempting to reference the current date and time in the Typst
|
||||||
|
document will always return `January 1st, 1980` when compiled in the Nix build
|
||||||
|
environment.
|
||||||
|
|
||||||
|
You can set an environment variable to get the right time.
|
||||||
|
|
||||||
|
```
|
||||||
|
SOURCE_DATE_EPOCH = builtins.toString self.lastModified;
|
||||||
|
```
|
||||||
|
|
||||||
|
Here `self` is the self provided to the flake outputs that refers to the flake
|
||||||
|
itself. As shown in
|
||||||
|
[[./nixos-cheat-sheet.md#Nix-flake-inputs-have-additional-properties]], you can
|
||||||
|
get the timestamp of the current Git commit.
|
|
@ -1,4 +1,7 @@
|
||||||
---
|
---
|
||||||
|
id: index
|
||||||
|
aliases: []
|
||||||
|
tags: []
|
||||||
title: "Alexandria: a knowledge garden"
|
title: "Alexandria: a knowledge garden"
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -15,6 +18,12 @@ which I took in the fall quarter of 2024. You can find them in
|
||||||
[[./Fall-2024/as-am-5/week-2.md]] and [[./Fall-2024/mes-45/week-1.md]] being
|
[[./Fall-2024/as-am-5/week-2.md]] and [[./Fall-2024/mes-45/week-1.md]] being
|
||||||
the weekly notes.
|
the weekly notes.
|
||||||
|
|
||||||
|
If you're interested in the Nix package manager, I've also started maintaining
|
||||||
|
a sort of "cheat sheet" or "tips and tricks" collection around variou quirks
|
||||||
|
and features of the NixOS / nixpkgs ecosystem in
|
||||||
|
[[assorted-nixos-hacks-and-tricks]]. Maybe you'll find something useful in
|
||||||
|
there!
|
||||||
|
|
||||||
Feel free to take a look around and appreciate the scenery.
|
Feel free to take a look around and appreciate the scenery.
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
Loading…
Reference in a new issue