I wrote small, but very handy nix-build-phases.bash script which allows to run nix package build phases interactively. It is very useful when developing or debugging packages. It also allows to run single build phase multiple times which can save a tons of time.
Example:
mkdir dev; cd dev
nix develop nixpkgs#geos
. ../nix-build-phases.bash
>>> Phase: **unpackPhase** patchPhase configurePhase buildPhase checkPhase installPhase fixupPhase installCheckPhase distPhase
>>> Command: phases=unpackPhase genericBuild
>>> Press ENTER to run, CTRL-C to exit
unpacking sources
unpacking source archive /nix/store/bps3riq6avqb05z55jvwg6i8234fr63v-geos-3.11.2.tar.bz2
source root is geos-3.11.2
setting SOURCE_DATE_EPOCH to timestamp 1679011021 of file geos-3.11.2/Version.txt
>>> Phase: unpackPhase **patchPhase** configurePhase buildPhase checkPhase installPhase fixupPhase installCheckPhase distPhase
>>> Command: phases=patchPhase genericBuild
>>> Press ENTER to run, CTRL-C to exit
patching sources
>>> Phase: unpackPhase patchPhase **configurePhase** buildPhase checkPhase installPhase fixupPhase installCheckPhase distPhase
>>> Command: phases=configurePhase genericBuild
>>> Press ENTER to run, CTRL-C to exit
configuring
fixing cmake files...
cmake flags: -DCMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY=OFF ....
Before running each phase, it prints information how to run the phase manually if needed (for example to run buildPhase: phases=buildPhase genericBuild).
That’s quite practical. I have a small question: if you quit your script (like restart computer), how would you restart it from where you left? Notably, do you need first to manually go to the source that were extracted and skip the unpack phases?
I would also encourage you to try to sprint this into mainline (nixpkgs), while the context is still fresh. We may ask the Nixpkgs Architecture Team to consider it somewhat timely for review to keep your churn low.
@blaggacao , @nixinator thank you very much for feedback. I am already thinking about integration to nixpkgs stdenv , but I am not sure about correct design.
Some packages need configurePhase while other eval "$configurePhase" depending on whether the phase defined explicitly or use default, so general approach should analyze .drv file to invoke the phase correctly.
Nix phases are not written with idempotency in mind. You cannot run patchPhase for the second time without error. Often you cannot run buildPhase for the second time too (because it might have e.g. sed; or second patchelf might corrupt executables), so as the prerequisite one have to fix idempotency of the phase which supposes to be repeated.
For 1 isn’t phases="configurePhase" genericBuild supposed to deal with both cases? Otherwise can’t we check the type of configure phase?
For 2 I was thinking to save the source/environment variables/bash functions in a file, and directly load that file to skip non-idempotent phases. Or for non-idempotent phases, to restart from the previous saved step.