Need help packaging my first package

Hi, I’ve taken a look at the packaging guide and took some existing nixpkgs for apps written in Go as an example.

I’m trying to pack autobrr and I successfully managed to create a build and run the result, but when visiting the app in the browser I get an internal server error. I’m not sure why, but I’m thinking it’s to do with building the frontend. autobrr uses pnpm, but I couldn’t find easy to understand (for a newb) resources on how to create nixpkgs that involve pnpm.

I’ve gotten this so far:

{ lib, buildGoModule, fetchFromGitHub }:
#with import <nixpkgs> {};

buildGoModule rec {
  pname = "autobrr";
  version = "1.43.0";

  src = fetchFromGitHub {
    owner = "autobrr";
    repo = "autobrr";
    rev = "v${version}";
    hash = "sha256-hlQ+rSU9M3P1NytcV9OsdX0VO/O4k6ARSHaz5tgsvv4=";
  };

  vendorHash = "sha256-KJeMuB6C/uijuHIKl8LDMa5PMZhU8TJKyj3NZVfrPJE=";

  subPackage = [ "cmd/autobrr" "cmd/autobrrctl" ];

  CGO_ENABLED = 0;

  meta = with lib; {
    description = "Modern, easy to use download automation for torrents and usenet.";
    homepage = "https://github.com/autobrr/autobrr";
    license = lib.licenses.gpl2Only;
    maintainers = with lib.maintainers; [ muradbu ];
  };
}

Where do I go from here?

Here’s a skeleton of a pnpm package, you could use one derivation to build the frontend, then copy it into the main package, if you find it easier:

{
  stdenv,
  nodejs,
  pnpm_9,
  buildGoModule,
}:
let 
  frontend = stdenv.mkDerivation (finalAttrs: {
    pname = "package";
    version = "1.2.3";
  
    # ...
  
    pnpmDeps = pnpm_9.fetchDeps {
      inherit (finalAttrs) pname version src;
      hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
    };
  
    nativeBuildInputs = [
      pnpm_9.configHook
    ];
  
    # ...
  });
in
buildGoModule rec {
  pname = "autobrr";
  version = "1.43.0";

  preBuild = ''
    ln -sf ${frontend}/whatever ./whatever
  '';

  passthru = { inherit frontend; };
  # ...
}

When you add pnpm_9.configHook to nativeBuildInputs it runs this setupHook, which uses the value from pnpmDeps.

1 Like

Thanks.

I’m trying to follow along using your skeleton and instructions found in nixpkgs/doc/languages-frameworks/javascript.section.md at 532db1f9d1b8ccff0add4be7f793ec7fb09f43b6 · NixOS/nixpkgs · GitHub, while I get the general idea of what’s happening I get the following error when I try to build:

nix-build -E 'with import <nixpkgs> {}; callPackage ./test.nix {}'
error:
       … while calling the 'abort' builtin

         at /nix/store/4djy3i4nbcd9rrrx6rvbhl6zdpnd9md9-nixos-24.05/nixos/lib/customisation.nix:269:13:

          268|        # which is especially relevant with allowAliases = false
          269|        else abort "lib.customisation.callPackageWith: ${error}";
             |             ^
          270|

       error: evaluation aborted with the following error message: 'lib.customisation.callPackageWith: Function called without required argument "pnpm" at /home/murad/nixpkgs/pkgs/servers/autobrr/test.nix:6, did you mean "clpm", "epm" or "fnm"?'

I made a temporary test.nix without the Go related things to isolate the problem.

{
  lib,
  stdenv,
  nodejs,
  # This is pinned as { pnpm = pnpm_9; }
  pnpm,
  fetchFromGitHub
}:

stdenv.mkDerivation (finalAttrs: {
  pname = "autobrr";
  version = "0.2.0";

  src = fetchFromGitHub {
    owner = "autobrr";
    repo = "autobrr";
    rev = "1.43.0";
    hash = lib.fakeHash;
  };

  nativeBuildInputs = [
    nodejs
    pnpm.configHook
  ];

  pnpmDeps = pnpm.fetchDeps {
    inherit (finalAttrs) pname version src;
    hash = lib.fakeHash;
    sourceRoot = "${finalAttrs.src.name}/web";
  };

  pnpmRoot = "web";
})

I tried to Google the error and looked at the source code of customisation.nix, but I can’t really make much of it at the moment…

That error means you have a package that callPackage cannot provide, this means your instance of nixpkgs does not provide pnpm. I assume your nixpkgs channel is release-24.05, pnpm was only recently packaged, so it’s only available in nixpkgs-unstable.

callPackageWith is a function used to construct the callPackage function:

callPackage = callPackageWith pkgs;

As a suggestion, you could clone nixpkgs and develop with your package already placed in its correct place (pkgs/by-name/au/autobrr/package.nix). Then build with nix-build -A autobrr.

I hope you meant nixos-24.05 not release-24.05 (release-* channels are not meant for end users.)