Solved - Trying to package a simple Python script, but it seems to need wrapGAppsNoGuiHook

I have a Python script, workrave-open.py, that I want to package, normally the sort of thing that writePython3Bin is made for. Trouble is, if I do that, I get the error message, “ValueError: Namespace GLib not available.”

Basically, it needs the environment that would normally come from wrapGAppsNoGuiHook.

I tried looking at these previous topics:

That second topic led me to try this non-working derivation:

{
  python3,
  python3Packages,
  wrapGAppsNoGuiHook,
}:

python3.pkgs.buildPythonApplication {
  pname = "workrave-open-py";
  version = "0.1.0";

  src = ./workrave-open.py;

  dontWrapGApps = true;

  makeWrapperArgs = [ "\${gappsWrapperArgs[@]}" ];

  nativeBuildInputs = [ wrapGAppsNoGuiHook ];
  dependencies = [ python3Packages.dasbus ];
    
}

Again, please don’t try this at home. Well, okay, you can try it, but it’s an example of what not to do.

Anyway, this just gets me the error message, “do not know how to unpack source archive /nix/store/p33cghj9mbgblc7axih7xdglzjpnnqp5-workrave-open.py”. :confused:

How do I get this to work?

ETA: Never mind, I forgot about the advice from this: https://discourse.nixos.org/t/struggling-with-nixos-cant-figure-out-how-to-get-some-apps-to-work-without-crude-hacks/66224/15?u=jjramsey

Anyway, the overlay packaging the working script is this:

final: prev:
{
  workrave-open-py = prev.writers.writePython3Bin "workrave-open.py" {
    libraries = with prev.python3Packages; [ dasbus ];
    # If you read the docs I link below, you can see that `makeWrapper`
    # is exposed to all script writers like this.
    #
    # Unfortunately, `wrapGapps` *isn't* exposed, so we need to do
    # this "manually". This may or may not become awkward depending
    # on how involved your script actually is, at which point you should just
    # make a custom derivation - which isn't much more complex tbh, this
    # maybe saves 3 lines.
    makeWrapperArgs = [
      "--set" "GI_TYPELIB_PATH" "${prev.glib.out}/lib/girepository-1.0"
    ];

    flakeIgnore = [ "E265" "E251" ];
    
  } ./workrave-open.py;
}

You’ve really run into an unpleasant edge case here. There should probably be a way to use hooks with writePython*.

One side note: You almost certainly don’t need, and shouldn’t be using, an overlay here. Overlays are really for replacing dependencies of things in nixpkgs. There’s no reason all your packages have to be in pkgs. Just bind a variable to the output of writePython3Bin, and use the variable wherever you would have used pkgs.workrave-open-py.

If you must use an overlay anyway, use final.writers.writePython3Bin, final.python3Packages, and final.glib.out. It shouldn’t matter in most cases, but it’s good practice to always use final in an overlay anytime it wouldn’t infrec. It reduces the impact of the ordering of your overlays. Think of it like this: final == pkgs. By contrast, prev is a strange variant of pkgs that has all the indirect effects of all overlays (including this one) but lacks the direct effects of this overlay and any after it… so the only reason you use prev is when replacing a package with a modified version, since you need the pre-modification variant of that package in order to express the modification itself.

I’ve considered using a different variable naming pattern and starting my overlays with pkgs: prevpkgs: { to emphasize this.

1 Like

I’ve been planning on flakifying my Nix configuration and moving the custom packages that are currently defined in overlays to one or more flakes that output packages, so that should obviate that problem.

1 Like