How to reference a boolean variable within "entryAfter" script?

I use a variables file file to define various settings for my nixos config, like so:

{
  role.htpc = true;
  role.htpc-discrete-power = true;
  hostName = "screendog";
}

It works great, but I’m having trouble using those boolean values within some shell script as shown below (I stripped out all but the relevant parts for this issues). I get a “cannot coerce a Boolean to a string” when trying to build the config.

{ config, lib, pkgs, modulesPath, ... }:
            
let       
  variables = import ./variables.nix;
in          
{           
  config = if variables.role.htpc then {            
    # Configure media home
    home-manager.users.media = { pkgs, lib, ... }: {
      home = {
        stateVersion = "23.11";

          # Pre-create kodi configuration
          prepKodi = lib.hm.dag.entryAfter ["writeBoundary"] ''
            # Remotes without discrete power buttons get different map file
            if [ ${variables.role.htpc-discrete-power} ]; then
              ln -sf ../../data/Lircmap-discrete-power.xml .kodi/userdata/Lircmap.xml
            else
              ln -sf ../../data/Lircmap-default-power.xml .kodi/userdata/Lircmap.xml
            fi
          '';
        };
      };
    };
  } else {};
}

I’ve tried things like [ "${variables.role.htpc-discrete-power}" == "true" ], but every variant I try results in the same error. If I switch to something like [ "${variables.hostName}" == "xxx" ], where hostName is already a string, it works fine, but I’d prefer to use an option to toggle that behavior vs. hostnames.

Anyone know how I can reference a boolean variable within shell script like this? (Note: I know for this specific example I could use source/target with mkIf, but this snippet is part of a much larger configuration script that I can’t cover with native nix functions. I’d prefer to keep all my kodi config together.)

Here’s the full error message:

error:
       … while calling the 'head' builtin

         at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/attrsets.nix:1575:11:

         1574|         || pred here (elemAt values 1) (head values) then
         1575|           head values
             |           ^
         1576|         else

       … while evaluating the attribute 'value'

         at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:809:9:

          808|     in warnDeprecation opt //
          809|       { value = builtins.addErrorContext "while evaluating the option `${showOption loc}':" value;
             |         ^
          810|         inherit (res.defsFinal') highestPrio;

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: cannot coerce a Boolean to a string

There’s a toString function you can apply to primitive values like booleans.

1 Like

Thanks, that’s exactly what I needed. Didn’t know to look for that. :slight_smile:

Here’s the working code, for anyone else stumbling across this in the future:

            if [ ${toString variables.role.htpc-discrete-power} ]; then

toString spits out ‘1’ for true and an empty string for false, which threw me off initially, but easy enough to work with.

Thanks again for the help! Very much appreciated.