Using callPackage with GitHub

I am developing a package on GitHub and would like to make it available to my own NixOS system. As such I am writing

# configuration.nix
...
environment.systemPackages = [
  ...
  (callPackage (pkgs.fetchFromGitHub {
    owner = "wgunderwood";
    repo = "tex-fmt";
    rev = "...";
    sha256 = "...";
  }) {})
  ...
  ];

This works fine, and the binary tex-fmt becomes available in my path. However I would like the callPackage code to be in another file to reduce clutter, and so tried

# configuration.nix
...
environment.systemPackages = [
  ...
  (callPackage ./tex-fmt.nix {})
  ...
  ];

with a new file

# tex-fmt.nix
{pkgs ? import <nixpkgs> {}}:
pkgs.fetchFromGitHub {
  owner = "wgunderwood";
  repo = "tex-fmt";
  rev = "...";
  sha256 = "...";
}

This builds without error, but the binary tex-fmt is not present in my path. Further, nix-tree is unable to locate the tex-fmt anywhere. The file tex-fmt.nix is definitely being read as it requires a correct sha256. The repository at https://github.com/WGUNDERWOOD/tex-fmt contains a default.nix which uses buildRustPackage. Any ideas why these approaches differ, and how I can fix it?

pkgs.callPackage file { }

is very much like

import file pkgs

So if you do

callPackage (pkgs.fetchFromGitHub { ... }) { }

It will import the file that was fetched

Whereas for

callPackage ./tex-fmt.nix { }

it will just import the ./tex-fmt.nix file, not the fetched one.

So to make that work, you’ll need to nest another callPackage in tex-fmt.nix:

{pkgs ? import <nixpkgs> {}}:
pkgs.callPackage (pkgs.fetchFromGitHub {
  owner = "wgunderwood";
  repo = "tex-fmt";
  rev = "...";
  sha256 = "...";
}) { }

Rule of thumb: One callPackage for every file :slight_smile:

1 Like

Thanks so much for the speedy and accurate reply! This makes a lot of sense, and I guess I tried every combination except this.

1 Like