Define and use derivation in home-manager

I am trying to use the following home.nix:

{ config, lib, pkgs, stdenv, ... }:
let
  sbt-extras = stdenv.mkDerivation rec {
    pname = "sbt-extras";
    rev = "32c96866364964b3e2f7272e0f9ef3e1a76ea7d7";
    version = "2023-01-05";

    src = pkgs.fetchFromGithub {
      owner = "paulp";
      repo = "sbt-extras";
      inherit rev;
      sha256 = "AgwqWmNkUkyQDu6R8LO86/JYJJHI6ZjEhPglt/jWBRY=";
    };

    dontBuild = true;

    installPhase = ''
    mkdir -p $out/bin

    install bin/sbt $out/bin
  '';

    doInstallCheck = true;

    installCheckPhase = ''
    $out/bin/sbt -h >/dev/null
  '';
  };
in

I then use sbt-extras in my home.packages.

But I am getting the following errors when running home-manager switch:

error:
       … while calling the 'derivationStrict' builtin

         at //builtin/derivation.nix:9:12: (source not available)

       … while evaluating derivation 'home-manager-generation'
         whose name attribute is located at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/pkgs/stdenv/generic/make-derivation.nix:352:7

       … while evaluating attribute 'buildCommand' of derivation 'home-manager-generation'

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/pkgs/build-support/trivial-builders/default.nix:98:16:

           97|         enableParallelBuilding = true;
           98|         inherit buildCommand name;
             |                ^
           99|         passAsFile = [ "buildCommand" ]

       … while evaluating derivation 'activation-script'
         whose name attribute is located at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/pkgs/stdenv/generic/make-derivation.nix:352:7

       … while evaluating attribute 'text' of derivation 'activation-script'

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/pkgs/build-support/trivial-builders/default.nix:161:16:

          160|       {
          161|         inherit text executable checkPhase allowSubstitutes preferLocalBuild;
             |                ^
          162|         passAsFile = [ "text" ];

       … while calling 'mkCmd'

         at /home/simao/.nix-defexpr/channels/home-manager/modules/home-environment.nix:654:17:

          653|       let
          654|         mkCmd = res: ''
             |                 ^
          655|             _iNote "Activating %s" "${res.name}"

       … while calling 'g'

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/attrsets.nix:739:19:

          738|           g =
          739|             name: value:
             |                   ^
          740|             if isAttrs value && cond value

       … from call site

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/attrsets.nix:742:20:

          741|               then recurse (path ++ [name]) value
          742|               else f (path ++ [name]) value;
             |                    ^
          743|         in mapAttrs g;

       … while calling anonymous lambda

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/modules.nix:242:72:

          241|           # For definitions that have an associated option
          242|           declaredConfig = mapAttrsRecursiveCond (v: ! isOption v) (_: v: v.value) options;
             |                                                                        ^
          243|

       … while evaluating the option `home.activation.installPackages.data':

       … while calling anonymous lambda

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/modules.nix:824:28:

          823|         # Process mkMerge and mkIf properties.
          824|         defs' = concatMap (m:
             |                            ^
          825|           map (value: { inherit (m) file; inherit value; }) (builtins.addErrorContext "while evaluating definitions from `${m.file}':" (dischargeProperties m.value))

       … while evaluating definitions from `/home/simao/.nix-defexpr/channels/home-manager/modules/home-environment.nix':

       … from call site

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/modules.nix:825:137:

          824|         defs' = concatMap (m:
          825|           map (value: { inherit (m) file; inherit value; }) (builtins.addErrorContext "while evaluating definitions from `${m.file}':" (dischargeProperties m.value))
             |                                                                                                                                         ^
          826|         ) defs;

       … while calling 'dischargeProperties'

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/modules.nix:896:25:

          895|   */
          896|   dischargeProperties = def:
             |                         ^
          897|     if def._type or "" == "merge" then

       … while evaluating derivation 'home-manager-path'
         whose name attribute is located at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/pkgs/stdenv/generic/make-derivation.nix:352:7

       … while evaluating attribute 'passAsFile' of derivation 'home-manager-path'

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/pkgs/build-support/trivial-builders/default.nix:99:9:

           98|         inherit buildCommand name;
           99|         passAsFile = [ "buildCommand" ]
             |         ^
          100|           ++ (derivationArgs.passAsFile or [ ]);

       … while calling 'g'

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/attrsets.nix:739:19:

          738|           g =
          739|             name: value:
             |                   ^
          740|             if isAttrs value && cond value

       … from call site

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/attrsets.nix:742:20:

          741|               then recurse (path ++ [name]) value
          742|               else f (path ++ [name]) value;
             |                    ^
          743|         in mapAttrs g;

       … while calling anonymous lambda

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/modules.nix:242:72:

          241|           # For definitions that have an associated option
          242|           declaredConfig = mapAttrsRecursiveCond (v: ! isOption v) (_: v: v.value) options;
             |                                                                        ^
          243|

       … while evaluating the option `home.packages':

       … from call site

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/modules.nix:846:59:

          845|       if isDefined then
          846|         if all (def: type.check def.value) defsFinal then type.merge loc defsFinal
             |                                                           ^
          847|         else let allInvalid = filter (def: ! type.check def.value) defsFinal;

       … while calling 'merge'

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/types.nix:537:20:

          536|       check = isList;
          537|       merge = loc: defs:
             |                    ^
          538|         map (x: x.value) (filter (x: x ? value) (concatLists (imap1 (n: def:

       … while calling anonymous lambda

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/types.nix:538:35:

          537|       merge = loc: defs:
          538|         map (x: x.value) (filter (x: x ? value) (concatLists (imap1 (n: def:
             |                                   ^
          539|           imap1 (m: def':

       … while calling anonymous lambda

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/lists.nix:165:29:

          164|   */
          165|   imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list);
             |                             ^
          166|

       … from call site

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/lists.nix:165:32:

          164|   */
          165|   imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list);
             |                                ^
          166|

       … while calling anonymous lambda

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/types.nix:539:21:

          538|         map (x: x.value) (filter (x: x ? value) (concatLists (imap1 (n: def:
          539|           imap1 (m: def':
             |                     ^
          540|             (mergeDefinitions

       … while calling anonymous lambda

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/modules.nix:824:28:

          823|         # Process mkMerge and mkIf properties.
          824|         defs' = concatMap (m:
             |                            ^
          825|           map (value: { inherit (m) file; inherit value; }) (builtins.addErrorContext "while evaluating definitions from `${m.file}':" (dischargeProperties m.value))

       … while evaluating definitions from `/home/simao/.config/home-manager/home.nix':

       … from call site

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/modules.nix:825:137:

          824|         defs' = concatMap (m:
          825|           map (value: { inherit (m) file; inherit value; }) (builtins.addErrorContext "while evaluating definitions from `${m.file}':" (dischargeProperties m.value))
             |                                                                                                                                         ^
          826|         ) defs;

       … while calling 'dischargeProperties'

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/modules.nix:896:25:

          895|   */
          896|   dischargeProperties = def:
             |                         ^
          897|     if def._type or "" == "merge" then

       … while calling anonymous lambda

         at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/modules.nix:506:44:

          505|       context = name: ''while evaluating the module argument `${name}' in "${key}":'';
          506|       extraArgs = builtins.mapAttrs (name: _:
             |                                            ^
          507|         builtins.addErrorContext (context name)

       … while evaluating the module argument `stdenv' in "/home/simao/.config/home-manager/home.nix":

       error: attribute 'stdenv' missing

       at /nix/store/xps34lin9jls5c20az0y3qq7ichh8s0i-nixpkgs/nixpkgs/lib/modules.nix:508:28:

          507|         builtins.addErrorContext (context name)
          508|           (args.${name} or config._module.args.${name})
             |                            ^
          509|       ) (lib.functionArgs f);

What am I doing wrong?

You are asking home-manager module system to give you stdenv but it has no such concept. You can get it like pkgs.stdenv.

Alternately, you can use callPackage for dependency injection like Nixpkgs does:

sbt-extras-expr = {stdenv, fetchFromGitHub}: stdenv.mkDerivation rec {/* … */};
sbt-extras = pkgs.callPackage sbt-extras-expr {};

thanks, using pkgs.stdenv worked. I thought I had tried that but apparently not.

I don’t really understand that second way of fixing it. Is there anywhere where I can read about what is happening there? Thanks

I use the callPackage pattern a lot for custom packages which are not (yet) in nixpkgs, because it’s the same pattern nixpkgs uses and it’s quite convenient, especially if you do it via overlays. This allows you to handle all the rest of your config as if your package is just a normal part of nixpkgs.

You’d do something like

  nixpkgs.overlays = [
    (final: prev: {
      stb-extras = prev.callPackage ./pkgs/stb-extras { };
    })
  ];

and put your derivation in ./pkgs/stb-extras/default.nix