What to do with a builder that wants mutable sources?

I’m trying to package my static blog with Nix. I’m using Hugo (gohugo.com) to generate the static HTML. Hugo places a lock file in the source directory while building.

This is a problem as Nix really wants to keep sources read-only. I’d prefer if there was an option in Hugo to ignore the lock issue, but there isn’t.

Is there a recommended pattern to deal with this kind of problems?

Thanks

Doesn’t Hugo have a --noBuildLock flag?

1 Like

Oh, thanks! I was running hugo from nixpkgs-22.05 which doesn’t have it (it’s only from version 0.100+).

Turns out Hugo also really wants to create $src/resources/_gen and some stuff underneath that, which is annoying.

I ended up with a derivation that basically does:

{ stdenv, hugo }:
stdenv.mkDerivation {
  name = "home-korfuri-fr-website";
  src = ./blog;
  nativeBuildInputs = [ hugo ];
  phases = [ "buildPhase" ];
  buildPhase = ''
tmpdir=$(mktemp -d -t hugoXXXXXXXX)
cp -r --no-preserve=mode,ownership $src $tmpdir/src
hugo -s "$tmpdir/src" -d "$out"
rm -rf $tmpdir
'';
}

The trick is just to copy $src elsewhere while discarding ownership and mode, so the builder now has a rw copy of src it can modify.

The unpackPhase would normally do exactly that, I believe.

1 Like

Correct, after unpackPhase, src ends up in the build directory, which is writable.

I recommend just doing cp -r $src ., no need to make a new directory – builds are dropped into a writable directory by default (see my previous comment).

It seems that you should be able to just not set phases and use

buildPhase = ''
  hugo -s "src" -d "$out"
'';

stdenv will handle the copying for you and skip install correctly

1 Like

An overdue reply but indeed @dramforever is right, the solution was to not specify phases at all. Easy as that :slight_smile: