-1

In /etc/nixos/configuration.nix, I have this code

{ lib, pkgs, config, modulesPath, ... }:
with lib;
let
  nixos-wsl = import ./nixos-wsl;
in
{
  imports = [
    "${modulesPath}/profiles/minimal.nix"

    nixos-wsl.nixosModules.wsl
  ];

I would like to know what "${modulesPath} is.

I have tried in shell.

echo ${modulesPath}

nothing

I have tried to print it in a nix interpreter.

nix repl

${modulesPath}

error: syntax error, unexpected DOLLAR_CURLY modulePath

error: undefined variable 'modulesPath' nothing too.

Does somebody what is that and more generally how to get the value of "nix constant"

update

I missed something important:

I have to import it in nix repl like this.

nix repl

{modulesPath}: modulesPath

«lambda @ (string):1:1»

It say that it is a lamdba. I thought it would give a string value.

  • Double quotes indicate a string. Within a string, `${` and `}` delimiter a string escape, which means, everything within those symbols gets evaluated, and then converted to a string (or fail if it's not possible). In this case, this just inserts the content of the variable `modulesPath` in the string. – jthulhu Dec 09 '22 at 22:40
  • BTW, it's important to understand that this isn't a "nix constant" -- nix itself has no idea what `modulesPath` is; it's NixOS that defines it. – Charles Duffy Dec 09 '22 at 22:56
  • 1
    BTW, think about making a habit of using `builtins.trace` when you want to know what something is. `(builtins.trace "Loading ${modulesPath}/profiles/minimal.nix" "${modulesPath}/profiles/minimal.nix")` could go into your `configuration.nix` and would make code evaluating it write a log line telling you what the value is. – Charles Duffy Dec 09 '22 at 22:56
  • No, `{modulesPath}: modulesPath` is not telling you what `modulesPath` is, it's making a new lambda that has nothing whatsoever to do with modulesPath. – Charles Duffy Dec 09 '22 at 23:02
  • Try running `{anything}: anything`, or `{pierreHasNotLearnedNix}: pierreHasNotLearnedNix` -- both will tell you you just created a lambda as well. – Charles Duffy Dec 09 '22 at 23:02
  • 1
    Before you import nixpkgs, `nix repl` doesn't know anything about NixOS, so it _can't_ know anything about modulesPath or anything else that nixpkgs defines. And `modulesPath` isn't even at top level; it gets defined during module evaluation. – Charles Duffy Dec 09 '22 at 23:03
  • 1
    Basically, what you just did is a Nix analog of the Python expression `lambda modulesPath: modulesPath`. `modulesPath` is just the variable name used for an argument in that context; it doesn't tell you anything about what the name means in any other context. – Charles Duffy Dec 09 '22 at 23:08
  • In reading the documentation I linked you, keep in mind that `specialArgs` is used to populate the defaults that fill out arguments to modules during nixos evaluation. _If you're not evaluating a NixOS module, it won't behave the same way._ – Charles Duffy Dec 09 '22 at 23:12
  • @CharlsDuffy Ok but how the configuration.nix knows what is the modulesPath? – Pierre-olivier Gendraud Dec 09 '22 at 23:13
  • That's described in the code comments I quote in the answer. – Charles Duffy Dec 09 '22 at 23:13
  • If you don't understand part of the answer, describe how you understand that and what parts of it are unclear, don't just pretend I never said it; ignoring things you're told is a good way to make people give up on trying to help you. – Charles Duffy Dec 09 '22 at 23:16
  • @CharlesDuffy I will probably ask you questions latter. I think I must learn a little more about nix by myself before I do that. Thanks for your help. – Pierre-olivier Gendraud Dec 10 '22 at 04:47

1 Answers1

1

Quoting from the nixpkgs source:

For NixOS, specialArgs includes modulesPath, which allows you to import extra modules from the nixpkgs package tree without having to somehow make the module aware of the location of the nixpkgs or NixOS directories.

{ modulesPath, ... }: {
   imports = [
     (modulesPath + "/profiles/minimal.nix")
   ];
}

This is performed in nixos/lib/eval-config-minimal.nix, as follows:

lib.evalModules {
  inherit prefix modules;
  specialArgs = {
    modulesPath = builtins.toString ../modules;
  } // specialArgs;
};

Because this is done in <nixpkgs>/nixos/lib, ../modules becomes <nixpkgs>/nixos/modules.

$ nix repl
Welcome to Nix 2.8.1. Type :? for help.

nix-repl> "${toString <nixpkgs>}/nixos/modules/profiles/minimal.nix"
"/nix/store/qdblsqzrzarf9am35r6nqnvlsl7dammk-source/nixos/modules/profiles/minimal.nix"

...run this on your own machine, and you'll get a directory that exists for you.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • I've update my question. Now in nix repl, it say that moduelsPAth is a lambda. – Pierre-olivier Gendraud Dec 09 '22 at 23:05
  • No, `modulesPath` is not a lambda, and `nix repl` is not telling you that it is one. When you run `{modulesPath}: modulesPath`, you just created _a brand new_ lambda that takes an attrset with the variable `modulesPath` as its argument. This tells you nothing at all about what modulesPath means in configuration.nix, where it has a meaning that has nothing to do with your lambda. – Charles Duffy Dec 09 '22 at 23:05
  • @CharlesDuffy you're referencing a file for a documentation-specific evaluation. The main evaluation adds it here https://github.com/NixOS/nixpkgs/blob/68bd364831a89859b40d67bf94618e6163486cae/nixos/lib/eval-config-minimal.nix#L42 – Robert Hensing Dec 10 '22 at 00:24
  • @RobertHensing, updated appropriately, thank you. – Charles Duffy Dec 11 '22 at 19:11