Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

wlib main set documentation

wlib.evalModules

calls nixpkgs.lib.evalModules with the core module imported and wlib added to specialArgs

wlib.evalModules takes the same arguments as nixpkgs.lib.evalModules

wlib.evalModule

evalModule = module: wlib.evalModules { modules = lib.toList module; };

Evaluates the module along with the core options, using lib.evalModules

Takes a module (or list of modules) as its argument. Returns the result from lib.evalModules directly.

To submit a module to this repo, this function must be able to evaluate it.

The wrapper module system integrates with NixOS module evaluation:

  • Uses lib.evalModules for configuration evaluation
  • Supports all standard module features (imports, conditionals, mkIf, etc.)
  • Provides config for accessing evaluated configuration
  • Provides options for introspection and documentation

wlib.evalPackage

evalPackage = module: (wlib.evalModules { modules = lib.toList module; }).config.wrapper;

Evaluates the module along with the core options, using lib.evalModules

Takes a module (or list of modules) as its argument.

Returns the final wrapped package from eval_result.config.wrapper directly.

Requires a pkgs to be set.

home.packages = [
  (wlib.evalPackage [
    { inherit pkgs; }
    ({ pkgs, wlib, lib, ... }: {
      imports = [ wlib.modules.default ];
      package = pkgs.hello;
      flags."--greeting" = "greetings!";
    })
  ])
  (wlib.evalPackage [
    { inherit pkgs; }
    ({ pkgs, wlib, lib, ... }: {
      imports = [ wlib.wrapperModules.tmux ];
      plugins = [ pkgs.tmuxPlugins.onedark-theme ];
    })
  ])
];

wlib.mkInstallModule

Produces a module for another module system, that can be imported to configure and/or install a wrapper module.

Arguments:

{
  name, # string
  value, # module or list of modules
  optloc ? [ "wrappers" ],
  loc ? [
    "environment"
    "systemPackages"
  ],
  as_list ? true,
  # Also accepts any valid top-level module attribute
  # other than `config` or `options`
  ...
}:

Creates a wlib.types.subWrapperModule option with an extra enable option at the path indicated by optloc ++ [ name ], with the default optloc being [ "wrappers" ]

Defines a list value at the path indicated by loc containing the .wrapper value of the submodule, with the default loc being [ "environment" "systemPackages" ]

If as_list is false, it will set the value at the path indicated by loc as it is, without putting it into a list.

This means it will create a module that can be used like so:

# in a nixos module
{ ... }: {
  imports = [
    (mkInstallModule { name = "?"; value = someWrapperModule; })
  ];
  config.wrappers."?" = {
    enable = true;
    env.EXTRAVAR = "TEST VALUE";
  };
}
# in a home-manager module
{ ... }: {
  imports = [
    (mkInstallModule { name = "?"; loc = [ "home" "packages" ]; value = someWrapperModule; })
  ];
  config.wrappers."?" = {
    enable = true;
    env.EXTRAVAR = "TEST VALUE";
  };
}

If needed, you can also grab the package directly with config.wrappers."?".wrapper

Note: This function will try to provide a pkgs to the subWrapperModule automatically.

If the target module evaluation does not provide a pkgs via its module arguments to use, you will need to supply it to the submodule yourself later.

wlib.wrapModule

Imports wlib.modules.default then evaluates the module. It then returns .config so that .wrap is easily accessible!

Use this when you want to quickly create a wrapper but without providing it a pkgs yet.

Equivalent to:

wrapModule = (wlib.evalModule wlib.modules.default).config.apply;

Example usage:

  helloWrapper = wrapModule ({ config, wlib, pkgs, ... }: {
    options.greeting = lib.mkOption {
      type = lib.types.str;
      default = "hello";
    };
    config.package = pkgs.hello;
    config.flags = {
      "--greeting" = config.greeting;
    };
  };

  # This will return a derivation that wraps the hello package with the --greeting flag set to "hi".
  helloWrapper.wrap {
    pkgs = pkgs;
    greeting = "hi";
  };

wlib.wrapPackage

Imports wlib.modules.default then evaluates the module. It then returns the wrapped package.

Use this when you want to quickly create a wrapped package directly, which does not have an existing module already.

Requires a pkgs to be set.

Equivalent to:

wrapPackage = module: wlib.evalPackage ([ wlib.modules.default ] ++ toList module);

mkOutOfStoreSymlink :: pkgs -> path -> { out = …; … }

Lifted straight from home manager, but requires pkgs to be passed to it first.

Creates a symlink to a local absolute path, does not check if it is a store path first.

Returns a store path that can be used for things which require a store path.

wlib.getPackageOutputsSet

getPackageOutputsSet :: Derivation -> AttrSet

Given a package derivation, returns an attribute set mapping each of its output names (e.g. “out”, “dev”, “doc”) to the corresponding output path.

This is useful when a wrapper or module needs to reference multiple outputs of a single derivation. If the derivation does not define multiple outputs, an empty set is returned.

Example: getPackageOutputsSet pkgs.git => { out = /nix/store/…-git; man = /nix/store/…-git-man; }

wlib.escapeShellArgWithEnv

Escape a shell argument while preserving environment variable expansion.

This escapes backslashes and double quotes to prevent injection, then

wraps the result in double quotes.

Unlike lib.escapeShellArg which uses single quotes, this allows

environment variable expansion (e.g., $HOME, ${VAR}).

Caution! This is best used by the nix backend for wlib.modules.makeWrapper to escape things, because the shell and binary implementations pass their args to pkgs.makeWrapper at build time, so allowing variable expansion may not always do what you expect!

Example


escapeShellArgWithEnv "$HOME/config.txt"

=> "\"$HOME/config.txt\""

escapeShellArgWithEnv "/path/with\"quote"

=> "\"/path/with\\\"quote\""

escapeShellArgWithEnv "/path/with\\backslash"

=> "\"/path/with\\\\backslash\""

wlib.makeCustomizable

Wrap a function (or callable attribute set) to make it customizable via a named override entry.

A slightly generalized version of nixpkgs.lib.makeOverridable, with explicit support for:

  • custom override names
  • configurable argument-merging semantics
  • preserving override entry points across common derivation-like patch functions (e.g. override, overrideAttrs, overrideDerivation)

This helper turns f into a functor that:

  • Preserves the original argument signature of f
  • Exposes an override function under the attribute ${name}
  • Recomputes f when arguments are overridden
  • Re-attaches ${name} to selected callable attributes on the result of f, so that chaining through derivation-style patch functions does not lose the custom override entry

Signature:

makeCustomizable =
  name:
  {
    patches ? [
      "override"
      "overrideAttrs"
      "overrideDerivation"
    ],
    mergeArgs ?
      origArgs: newArgs:
        origArgs // (if lib.isFunction newArgs then newArgs origArgs else newArgs),
  }@opts:
  f:

Parameters:

  • name: The attribute name under which the override function is exposed (e.g. customize, withPackages). This attribute is attached both to f itself and to applicable results returned by calling f.

  • opts.patches: A list of attribute names on the result of f that should propagate the named override. Each listed attribute is expected to be callable when present. This is primarily intended for derivation-like results, ensuring that calling methods such as override, overrideAttrs, or overrideDerivation preserves the custom override entry rather than discarding it. It will only patch the value if present.

  • opts.mergeArgs: A function controlling how new arguments are merged with the original arguments when overriding. It receives origArgs and newArgs and must return the argument used to re-invoke f. By default, this performs a shallow merge, evaluating newArgs if it is a function.

  • f: The function (or callable attribute set) to wrap. If f is an attribute set, its additional attributes are preserved, and an existing ${name} entry (if present) is composed rather than replaced.

Semantics:

  • Argument overrides recompute f with merged arguments.
  • Result-level patches recompute f and then delegate to the corresponding callable attribute on the result.
  • Returned attribute sets and functions gain a ${name} attribute that can be chained arbitrarily.

Example:

  luaEnv = wlib.makeCustomizable
    "withPackages"
    { mergeArgs = og: new: lp: og lp ++ new lp; }
    pkgs.luajit.withPackages
    (lp: [ lp.inspect ]);

  # inspect + cjson
  luaEnv2 = luaEnv.withPackages (lp: [ lp.cjson ]);
  # inspect + cjson + luassert
  luaEnv3 = luaEnv2.withPackages (lp: [ lp.luassert ]);