Unverified Commit 6b79fe8c authored by Robert Hensing's avatar Robert Hensing Committed by GitHub
Browse files

Merge pull request #211855 from hercules-ci/lib-modules-disabledModules-module-with-key

lib/modules: Allow an "anonymous" module with key in disabledModules
parents 324ef866 118bdf25
Loading
Loading
Loading
Loading
+29 −5
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ let
    isBool
    isFunction
    isList
    isPath
    isString
    length
    mapAttrs
@@ -45,6 +46,9 @@ let
    showOption
    unknownModule
    ;
  inherit (lib.strings)
    isConvertibleWithToString
    ;

  showDeclPrefix = loc: decl: prefix:
    " - option(s) with prefix `${showOption (loc ++ [prefix])}' in module `${decl._file}'";
@@ -403,7 +407,7 @@ rec {
            key = module.key;
            module = module;
            modules = collectedImports.modules;
            disabled = module.disabledModules ++ collectedImports.disabled;
            disabled = (if module.disabledModules != [] then [{ file = module._file; disabled = module.disabledModules; }] else []) ++ collectedImports.disabled;
          }) initialModules);

      # filterModules :: String -> { disabled, modules } -> [ Module ]
@@ -412,10 +416,30 @@ rec {
      # modules recursively. It returns the final list of unique-by-key modules
      filterModules = modulesPath: { disabled, modules }:
        let
          moduleKey = m: if isString m && (builtins.substring 0 1 m != "/")
            then toString modulesPath + "/" + m
            else toString m;
          disabledKeys = map moduleKey disabled;
          moduleKey = file: m:
            if isString m
            then
              if builtins.substring 0 1 m == "/"
              then m
              else toString modulesPath + "/" + m

            else if isConvertibleWithToString m
            then
              if m?key && m.key != toString m
              then
                throw "Module `${file}` contains a disabledModules item that is an attribute set that can be converted to a string (${toString m}) but also has a `.key` attribute (${m.key}) with a different value. This makes it ambiguous which module should be disabled."
              else
                toString m

            else if m?key
            then
              m.key

            else if isAttrs m
            then throw "Module `${file}` contains a disabledModules item that is an attribute set, presumably a module, that does not have a `key` attribute. This means that the module system doesn't have any means to identify the module that should be disabled. Make sure that you've put the correct value in disabledModules: a string path relative to modulesPath, a path value, or an attribute set with a `key` attribute."
            else throw "Each disabledModules item must be a path, string, or a attribute set with a key attribute, or a value supported by toString. However, one of the disabledModules items in `${toString file}` is none of that, but is of type ${builtins.typeOf m}.";

          disabledKeys = concatMap ({ file, disabled }: map (moduleKey file) disabled) disabled;
          keyFilter = filter (attrs: ! elem attrs.key disabledKeys);
        in map (attrs: attrs.module) (builtins.genericClosure {
          startSet = keyFilter modules;
+12 −0
Original line number Diff line number Diff line
@@ -141,6 +141,14 @@ checkConfigError "The option .*enable.* does not exist. Definition values:\n\s*-
checkConfigError "attribute .*enable.* in selection path .*config.enable.* not found" "$@" ./disable-define-enable.nix ./disable-declare-enable.nix
checkConfigError "attribute .*enable.* in selection path .*config.enable.* not found" "$@" ./disable-enable-modules.nix

checkConfigOutput '^true$' 'config.positive.enable' ./disable-module-with-key.nix
checkConfigOutput '^false$' 'config.negative.enable' ./disable-module-with-key.nix
checkConfigError 'Module ..*disable-module-bad-key.nix. contains a disabledModules item that is an attribute set, presumably a module, that does not have a .key. attribute. .*' 'config.enable' ./disable-module-bad-key.nix

# Not sure if we want to keep supporting module keys that aren't strings, paths or v?key, but we shouldn't remove support accidentally.
checkConfigOutput '^true$' 'config.positive.enable' ./disable-module-with-toString-key.nix
checkConfigOutput '^false$' 'config.negative.enable' ./disable-module-with-toString-key.nix

# Check _module.args.
set -- config.enable ./declare-enable.nix ./define-enable-with-custom-arg.nix
checkConfigError 'while evaluating the module argument .*custom.* in .*define-enable-with-custom-arg.nix.*:' "$@"
@@ -358,6 +366,10 @@ checkConfigOutput '^"The option `a\.b. defined in `.*/doRename-warnings\.nix. ha
  config.result \
  ./doRename-warnings.nix

# Anonymous modules get deduplicated by key
checkConfigOutput '^"pear"$' config.once.raw ./merge-module-with-key.nix
checkConfigOutput '^"pear\\npear"$' config.twice.raw ./merge-module-with-key.nix

cat <<EOF
====== module tests ======
$pass Pass
+16 −0
Original line number Diff line number Diff line
{ lib, ... }:
let
  inherit (lib) mkOption types;

  moduleWithKey = { config, ... }: {
    config = {
      enable = true;
    };
  };
in
{
  imports = [
    ./declare-enable.nix
  ];
  disabledModules = [ { } ];
}
+34 −0
Original line number Diff line number Diff line
{ lib, ... }:
let
  inherit (lib) mkOption types;

  moduleWithKey = {
    key = "disable-module-with-key.nix#moduleWithKey";
    config = {
      enable = true;
    };
  };
in
{
  options = {
    positive = mkOption {
      type = types.submodule {
        imports = [
          ./declare-enable.nix
          moduleWithKey
        ];
      };
      default = {};
    };
    negative = mkOption {
      type = types.submodule {
        imports = [
          ./declare-enable.nix
          moduleWithKey
        ];
        disabledModules = [ moduleWithKey ];
      };
      default = {};
    };
  };
}
+34 −0
Original line number Diff line number Diff line
{ lib, ... }:
let
  inherit (lib) mkOption types;

  moduleWithKey = {
    key = 123;
    config = {
      enable = true;
    };
  };
in
{
  options = {
    positive = mkOption {
      type = types.submodule {
        imports = [
          ./declare-enable.nix
          moduleWithKey
        ];
      };
      default = {};
    };
    negative = mkOption {
      type = types.submodule {
        imports = [
          ./declare-enable.nix
          moduleWithKey
        ];
        disabledModules = [ 123 ];
      };
      default = {};
    };
  };
}
Loading