packages feed

nix-freeze-tree-0.1.0.0: README.md

# `nix-freeze-tree`

[![builds.sr.ht status](https://builds.sr.ht/~jack/nix-freeze-tree.svg)](https://builds.sr.ht/~jack/nix-freeze-tree?)
[![AGPLv3](https://git.sr.ht/~jack/nix-freeze-tree/blob/master/AGPLv3.png)](https://www.gnu.org/licenses/agpl-3.0.html)

`nix-freeze-tree` is a utility that walks a directory tree, and writes
out [Nix](https://nixos.org/nix/) expressions which rebuild that
tree. The generated expressions have two important properties:

1. Each file in the tree is built by a separate fixed-output
   derivation, and

2. Directories are built by derivations that symlink their contents
   recursively.

If you are using `nix copy` to ship a derivation between nix stores,
copying the derivation built by evaluating the output of
`nix-freeze-tree` can reuse existing files in the destination store,
as fixed-output derivations can be checked against a hash before
copying.

I use this to speed up deploys to my personal website. Running
`nix-freeze-tree` on the output from [my site
generator](https://git.sr.ht/~jack/jackkelly-name) and importing the
result means that `nix copy` only uploads new files, instead of
copying a single giant derivation containing every image on the site.


## Installation

### Nix

If you use Nix, you can install the command into your local
environment by running `nix-env -f
https://git.sr.ht/~jack/nix-freeze-tree/archive/master.tar.gz -iA
command`.

### Cabal

If you have GHC installed, you can also build and install the binary
by running `cabal v2-install nix-freeze-tree`. You can also run the
binary from the build directory with `cabal v2-run nix-freeze-tree --
ARGS`.


## Usage

```
Usage: nix-freeze-tree [--version] [-f|--force] [-v|--verbose]
                       [-o|--out-root OUT_ROOT] [IN_DIR]
  Write a tree of nix expressions to OUT_ROOT that build a derivation,
  symlinking every file in IN_DIR as a separate fixed-output derivation.

Available options:
  --version                Display version information and exit.
  -h,--help                Show this help text
  -f,--force               If any default.nix exist in the output directory,
                           remove them and generate anyway
  -v,--verbose             Display messages while working.
  -o,--out-root OUT_ROOT   Where to write the nix files (default: IN_DIR)
  IN_DIR                   Directory to freeze (default: .)
```


## Calling from Nix

This repository's `default.nix` gives access to a function `freeze`,
which can be used to freeze the output of an existing derivation.

You can use it with Nix code that looks a bit like:

```nix
let
  # Some nixpkgs from somewhere
  nixpkgs = ...;

  # Whether you get it from a channel, a local checkout,
  # builtins.fetchTarball or builtins.fetchgit is up to you
  nix-freeze-tree-repo = builtins.fetchTarball { ... };

  # Derivation to freeze
  drv = mkDerivation { ... };

  # Evaluate default.nix from nix-freeze-tree-repo and hold onto the
  # freeze function
  freeze = (import nix-freeze-tree-repo { inherit nixpkgs; }).freeze;
in
  freeze drv
```


## FAQ

Q: Why didn't you use
[`symlinkJoin`](https://nixos.org/nixpkgs/manual/#chap-trivial-builders)
to tie all the subtrees together?

A: I had the program mostly working before I remembered that
`symlinkJoin` existed. I thought about making each file's derivation
contain the directories leading up to it and then `symlinkJoin`ing
them all together, but decided against it for three reasons:

1. You can easily build subtrees using the Nix expressions generated
   by `nix-freeze-tree`;
2. Building the output of `nix-freeze-tree` will correctly create
   empty directories present in the input; and
3. Files are hashed based on their content alone, not their position
   in the tree-to-be-frozen (reducing duplication).


## Other Resources

* Questions should go to the
  [nix-freeze-tree-discuss](https://lists.sr.ht/~jack/nix-freeze-tree-discuss)
  mailing list.

* Bug reports should go to the [bug
  tracker](https://todo.sr.ht/~jack/nix-freeze-tree).