Specifying sources

A number of derivations in Typix accept source trees as parameters, such as src, fontPaths, and virtualPaths. Specifying these is usually as simple as cleanTypstSource in the case of src and string interpolation (via ${...}) in the case of fontPaths and virtualPaths, but there are situations where more is required or desirable:

  • cleanTypstSource omits local files which are required by your Typst project
  • An input you're sourcing contains a large number of files which would be expensive to copy to the Nix store, resulting in longer build times and higher disk usage

Expanding a source tree

TL;DR: you can use lib.sources.cleanSource, but the problem with this approach is that every change to a file tracked by git will invalidate the cache and trigger a rebuild.

To include more local files1 in a source tree, you can use a combination of different functions in lib.fileset such as lib.fileset.unions, lib.fileset.fromSource, and lib.fileset.toSource, like so:

{
  outputs = { nixpkgs, typix }: let
    system = "x86_64-linux";
    pkgs = nixpkgs.legacyPackages.${system};
    inherit (pkgs) lib;
    typixLib = typix.lib.${system};
    myTypstSource = typixLib.cleanTypstSource ./.;
  in {
    packages.${system}.default = typixLib.mkTypstDerivation {
      src = lib.fileset.toSource {
        root = ./.;
        fileset = lib.fileset.unions [
          (lib.fileset.fromSource myTypstSource)
          ./path.svg
          ./other/path.svg
          ./another
        ];
      };
    };
  };
}

This will create a source tree that looks something like:

/nix/store/...
├── another
│  ├── path1.svg
│  ├── path2.svg
│  └── path3.svg
├── path.svg
├── other
│  └── path.svg
└── ...
1

lib.fileset functions can only be used with local files, not e.g. flake inputs, which is what virtualPaths is for.

Source filtering

You can do source filtering primarily using builtins.filterSource and functions in lib.sources such as lib.sources.cleanSourceWith.

A more detailed explanation can be found in the Nix discussion: "Filtering Source Trees with Nix and Nixpkgs".

Here's an example which picks specific files by name:

{
  outputs = { nixpkgs, typix, font-awesome }: let
    system = "x86_64-linux";
    pkgs = nixpkgs.legacyPackages.${system};

    fontAwesomeSubset = let
      icons = [
        "gem.svg"
        "heart.svg"
        "lightbulb.svg"
      ];
    in lib.sources.cleanSourceWith {
      src = "${font-awesome}/svgs/regular";
      filter = path: type:
        builtins.any (icon: builtins.baseNameOf path == icon) icons;
    };
  in {
    packages.${system}.default = typix.lib.${system}.mkTypstDerivation {
      virtualPaths = [
        fontAwesomeSubset
      ];
    };
  };
}