How to allowUnfree in dependant flake?

I reviewed multiple discussions and other sources about allowUnfree, but they were mostly focused on Home Manager or NixOS, and the proper way to propagate the the option through your configs.

However, I found no solution for the case in which I’d like to use an external flake, that declares a package license as not free, but it doesn’t expose a facility similar to HM useGlobalPkgs.

To make it concrete, consider this two flakes:

# flake.nix
{
  inputs = {
    dep.url = "path:./dep";
  };

  outputs = {
    self,
    dep,
  }: {
    packages.x86_64-linux.default = dep.packages.x86_64-linux.default;
  };
}

and

# dep/flake.nix
{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
  };

  outputs = {
    self,
    nixpkgs,
  }: let
    # pkgs = import nixpkgs {
    #   system = "x86_64-linux";
    #   config.allowUnfree = true;
    # };
    pkgs = nixpkgs.legacyPackages.x86_64-linux;
  in {
    packages.x86_64-linux = {
      default = pkgs.hello.overrideAttrs (final: prev: {meta.license.free = false;});
    };
  };
}

and then run nix build . in the folder of flake.nix.

Obviously, swapping the definition of pkgs with the commented one in the dependency flake solves the issue. But the second flake should be the one written by someone else, so it’s not really possible to modify it (nor it would make sense, since the allowUnfree should be a choice of the end user).

Not sure if there is a clean solution here for the reasons outlined in 1000 instances of nixpkgs.

I have used two tricks in the original flake, neither of which are ideal of course:

  • Overriding the license at call site:

    {
      packages.x86_64-linux.default = dep.packages.x86_64-linux.default.overrideAttrs (
        final: prev: { meta.license.free = true; }
      );
    };
    
  • Or just vendoring the package definition from dep flake into the original flake I control

1 Like

Yes, that’s exactly what I ended up doing. Moreover, since you don’t need them, you could avoid the args to .overrideAttrs:

{
  packages.x86_64-linux.default = dep.packages.x86_64-linux.default.overrideAttrs (
    { meta.license.free = true; }
  );
};

Sometimes there is even a further option: often projects still maintain a default.nix file, despite not being necessary with flake.nix. In that case, you could even just import the flake (that will bypass flake.nix, and all its content), and just vendor the content of flake.nix.
Actually, default.nix makes it more convenient, since in these cases flake.nix are usually trivial, but it is possible in general, making the same imports of the flake (what you’re mostly loosing are the locked inputs, but you will relock on your side).

In any case, I personally opted for the override, since it looks more similar to the “proper” one. Despite lying on license…