Interactively inspect *Phase source in `nix develop`

When in a shell created by nix develop ... I can manually execute the various phases such as unpackPhase, and TAB-completion works on the names of the various phases. But how can I inspect, interactively, what code is executed by unpackPhase etc. inside nix develop ...?

1 Like

printenv $phaseName

1 Like

With the $?

I’m getting weird behaviour:

  • (printenv $unpackPhase (with $) prints the whole environment, just like printenv on its own. This doesn’t surprise me in the slightest.)
  • printenv unpackPhase (without $) produces no output, but
  • unpackPhase fetches an unpacks the source.


  • printenv buildPhase (no $) shows echo XXXXXXXXXX (which is what I wrote in mkDerivation.buildPhase` for debugging purposes), but
  • buildPhase gives ‘no Makefile, doing nothing’.

In short, there seems to be a disconnect between what printenv somePhase shows and what somePhase actually does! Specifically, it seems that printenv somePhase prints whatever I wrote in mkDerivation { somePhase = ... }; but somePhase seems to perform the default action for that phase.

type buildPhase

The default buildPhase is a bash function, not an environment variable, which is why it doesn’t show up in printenv.

… and bash doesn’t show shell functions in response to which as I’ve grown to expect from zsh (at least the way mine is configured). OK, that makes sense. It’s annoying, but at least it makes some sort of sense.

But now I’m left with the problem that

  1. printenv buildPhase gives
    echo XXXXXXXX
  2. type buildPhase gives
    buildPhase is a function
    buildPhase () 
        runHook preBuild;
        : ${makeFlags=};
        if [[ -z "$makeFlags" && -z "${makefile:-}" && ! ( -e Makefile || -e makefile || -e GNUmakefile ) ]]; then
            echo "no Makefile, doing nothing";
            local flagsArray=(${enableParallelBuilding:+-j${NIX_BUILD_CORES} -l${NIX_BUILD_CORES}} SHELL=$SHELL $makeFlags "${makeFlagsArray[@]}" $buildFlags "${buildFlagsArray[@]}");
            echoCmd 'build flags' "${flagsArray[@]}";
            make ${makefile:+-f $makefile} "${flagsArray[@]}";
            unset flagsArray;
        runHook postBuild
  3. buildPhase executes the latter.

So it seems that if I want to perform these steps manually in nix develop I
have to inspect whether a phase’s default action was overridden in
mkDerivation and invoke the phase differently depending on the answer.

This is very annoying and flaky. Surely there must be a better way! Is this a bug or a feature?

1 Like