如何覆盖导入的谓词?

如何覆盖导入的谓词?

考虑/etc/nixos/root.nix包含以下内容:

{
  nixpkgs.config.allowUnfreePredicate = pkg:
    builtins.elem (lib.getName pkg) [
      "foo"
    ];
}

此配置被导入到 中/etc/nixos/configuration.nix,它提供了自己的allowUnfreePredicate

{
  imports = [
    /etc/nixos/root.nix
  ];

  nixpkgs.config.allowUnfreePredicate = pkg:
    builtins.elem (lib.getName pkg) [
      "bar"
    ];
}

在这种情况下,pkgs.bar只能安装 only,因为最后一个谓词会覆盖第一个谓词。有什么方法可以将它们结合起来吗特别是考虑到/etc/nixos/configuration.nix不应该“知道”它的任何导入是否指定了这个谓词?

更新:上游报告希望它能在那里得到解决。

答案1

这可行,但相当复杂:

{
  config,
  lib,
  modulesPath,
  pkgs,
  specialArgs,
  options,
}: let
  imports = [
    /etc/nixos/cachix.nix
    /etc/nixos/root.nix
  ];
in {
  inherit imports;

  nixpkgs.config.allowUnfreePredicate = pkg:
    (builtins.elem (lib.getName pkg) [
      "bar"
    ])
    || builtins.any (
      path: let
        package = import path {
          inherit config lib modulesPath pkgs specialArgs options;
        };
      in
        if builtins.hasAttr "nixpkgs" package
        then package.nixpkgs.config.allowUnfreePredicate pkg
        else false
    )
    imports;
}

基本上:

  1. 拉出imports以便可以引用它,而无需创建rec草书集。
  2. 对于每个导入,检查它是否具有nixpkgs(我已包含 cachix 配置,因为它没有nixpkgs),如果是,则检查它allowUnfreePredicate对于包是否正确。
  3. 如果任何导入的内容allowUnfreePredicate为 true,则允许安装该包。

希望有一种更简单的方法来做到这一点。

相关内容