181 Matching Annotations
  1. Feb 2024
  2. Jan 2024
  3. Apr 2023
    1. The Answer to the Original Issue

      This is the pinning solution.

    2. If channels were to be removed, it would be more clearer to everybody including new users, what the real use and power of nix is, and all documentation would go straight to pinning. Then only after understanding this, can people write higher level abstract tools to provide an auto-updating "channel" like interface to the underlying pinning concept.

      great channels vs pinning summary

    3. One effect of this is that you get reproducibility. Note that this is not binary reproducibility, since it's still possible for the compilation of code to give different resulting binaries. But it is reproducibility within the context of Nix universe.
    4. No pinning isn't about which channels you get. Pinning pins to a content addressed commit hash of nixpkgs or any nixpkgs even your own fork. Channels is orthogonal and probably a mistake and should be removed.

      Wonder what the consensus on channels nowadays?

    5. What's "pinning"? Is this ever explained to a new user? Where? (Yes, I understand what it is now, but new users probably will not, meaning it doesn't exist to them.) Your packages never get bug-fix updates Your packages never get security updates Broken package expressions never get fixed. If you need to update one package, you must update them all. This can be seen as either consistency, or limitation. It depends on the use case.

      Again, the entire comment is great.

    6. The main thing I want to accomplish is to distinguish between the versions of packages, and the versions of derivations.
    7. What I want is to let a channel have several derivations for a package, each with its own version. This is current behavior. I then want my derivation to depend on a specific package name and version. Since versions are currently put into some package names, this is current behavior, though it would be cleaner to just use separate names. I then want my derivation to pattern match a range of versions. This is not current behavior. The current channel will provide a package with the greatest version number matched by the range provided that it has defined.

      Another good one.

    8. To summarize what I have read here (correct me if I am wrong) @mayhewluke described some real drawbacks of how derivations are currently implemented: Derivations cannot use a specific version of a package. Derivations are limited to a very small subset of real versions for dependencies.

      This entire comment is gold

    9. You always have the option of adding missing versions of certain packages to your local database by means of an override as described in http://nixos.org/nixpkgs/manual/#how-to-create-nix-builds-for-your-own-private-haskell-packages. You can register aeson-0.8.1.1 in your copy of Nixpkgs without needing to change the Nixpkgs git repository at all.

      what

    10. So what happens if I have to fix a bug in an old project that was using 0.8.1.1? In that particular case, Nix won't help you and you are better off using a cabal-install sandbox or a stack build.

      Is this still the case?

    11. To be certain, you can just copy those by nix-copy-closure. Note that version numbers of direct dependencies don't contain all the information at all.
    12. We keep multiple versions in nixpkgs only when there's a good reason to. Nix is able to handle any number of versions/configurations, but on the other hand it's much more convenient when all (or most) use just a single one. It leads to better sharing of the effort in many respects: simplified maintenance, testing, sharing of the binaries, etc. It's what most distros do. (Only gentoo diverges from the big ones I know, and they pay a price for it.) When we do create more variants, we just name them (attribute paths), e.g. gcc48 and gcc49 or ffmpeg and ffmpeg-full.

      mull this over

  4. Feb 2023
  5. Jan 2023
    1. Python — Json documents double as valid Python literals with minimal adaptation, and Python supports trailing commas and comments. It has variables and functions, powerful string interpolation, and json.dump built in. A self-contained Python file that prints json to stdout goes a long way!

      If you would like to template yaml, then rather do it in Nix or Python

  6. Dec 2022
  7. Oct 2022
  8. Aug 2022
  9. Jul 2022
  10. Jun 2022
  11. May 2022
  12. Apr 2022
  13. Mar 2022
  14. Feb 2022
  15. Jan 2022
  16. Sep 2021
  17. May 2021
    1. The command nix-shell will build the dependencies of the specified derivation, but not the derivation itself. It will then start an interactive shell in which all environment variables defined by the derivation path have been set to their corresponding values, and the script $stdenv/setup has been sourced. This is useful for reproducing the environment of a derivation for development.

      QUESTION: What exactly does nix-shell execute from the Nix expression (i.e., shell.nix, default.nix, etc.)?

      ANSWER: Based on my current understanding, the answer is everything. It calls $stdenv/setup (see annotation below) to set up the most basic environment variables (TODO: expand on this), and "injects" the most common tools (e.g., gcc, sed) into it.

      It also defines the phases (TODO: verify this) and builder functions, such as genericBuilder. For example, the default builder is just two lines:

      source $stdenv/setup
      genericBuild
      

      TODO: pkgs/stdenv/generic/builder.sh is a mystery though.

      QUESTION: Once dropping into nix-shell, how do I know what phases to execute by looking at a default.nix? (E.g., [..]freeswitch/default.nix)

      ANSWER: As far as I can tell, one can override the phases in their Nix build expression (to build the derivation, see at the bottom), but they won't get executed as only the $stdenv/setup (see above) will get sourced, and no builders are called that, in return, invoke the phases (again, see above).

      So if one is using nix-shell

      • to create/hack on a package, the person has to manually invoke the builder or phases (TODO: still fuzzy on this subject)

      • to set up an environment, then one doesn't even have to worry about builders/phases because we just use nix-shell to clear the environment and to inject tools that we need for a given task

      QUESTION: When dropping into nix-shell, is this Nix expression (i.e., freeswitch/default.nix) executed? Or just parts of it?

      ANSWER: As stated above, all of the input Nix expression is evaluated, but no builders and build phases are called; although, nothing prevents one to override the phases, in case they are creating/hacking on a package.

      QUESTION:

      The command nix-shell will build the dependencies of the specified derivation, but not the derivation itself.

      What is the "derivation" here exactly? I know that it is a build expression, but does that mean the default.nix (or other Nix expression) nix-shell is invoked with?

      <sup>This statement also seems like a contradiction with how `nix-shell` works (i.e., if one issues `nix-shell -p curl`, then `curl` will be available in that sub-shell), but `-p` acts like a shortcut to as if `curl` had been listed in `buildInputs` so this is not the case.</sup>

      ANSWER: I have the feeling my confusion comes from the fact that the term "derivation" is used ambiguously in the manuals, sometimes to mean multiple things (see list below).

      TODO: Substantiate this claim, and make sure that it not coming from my misunderstanding certain topics.

      • Nix build expression (such as default.nix) whose output is going to become the store derivation itself (see last item at the bottom about the Nix manual's glossary definition)

      • store derivation.

      Had multiple cracks at unambiguously define what a derivation is, and here's a list of these:

      QUESTION: What is the difference between nix-shell -p and nix-shell invoked with a Nix expression of mkShell (or other that achieves the similar effect)?

      QUESTION: nix-shell does not create a sub-shell, so what does it do? (clarification: so nix-shell indeed does it; I confused it with nix shell)

  18. Mar 2021
  19. Feb 2021
    1. A Nix expression describes everything that goes into a package build action (a “derivation”)

      Come up with an ultimate definition for what a "derivation" is.

      So round up all the places where it is mentioned across Nix* manuals, and check out these:


      From Nix Pills section 6.1. The derivation function (see annotation):

      A derivation from a Nix language view point is simply a set, with some attributes. Therefore you can pass the derivation around with variables like anything else.

      So there is clearly an ambiguity between what derivations are perceived to be and what is stated in the Eelco Dolstra's PhD thesis. Or maybe I'm having issues with reading comprehension again...

    2. For each output declared in outputs, the corresponding environment variable is set to point to the intended path in the Nix store for that output. Each output path is a concatenation of the cryptographic hash of all build inputs, the name attribute and the output name. (The output name is omitted if it’s out.)

      QUESTION: So when I see $out in a builder script, it refers to the default output path because the output attribute in the Nix expression has never been explicitly set, right?

    3. A derivation causes that derivation to be built prior to the present derivation; its default output path is put in the environment variable.

      That is, if an input attribute is a reference to a derivation in the Nix store, then

      1. that derivation is built first (after a binary substitute is not found, I presume), and
      2. the path to the built package (for a better word) is handed to the shell build script.
    4. derivationA description of a build action. The result of a derivation is a store object. Derivations are typically specified in Nix expressions using the derivation primitive. These are translated into low-level store derivations (implicitly by nix-env and nix-build, or explicitly by nix-instantiate).

      Organically related to the annotation regarding my nix-shell confusion.

      The dissection of this definition to show why I find it lacking:

      A description of a build action.

      The first (couple) time(s) I read the manuals, this description popped up in many places, and I identified it with Nix expression every time, thinking that a derivation is a synonym for Nix expression.

      Maybe it is, because it clearly tries to disambiguate between store derivations and derivation in the last sentence.

      The result of a derivation is a store object.

      Is this store object the same as a store derivation?

      Derivations are typically specified in Nix expressions using the `derivation primitive. These are translated into low-level store derivations (implicitly by nix-env and nix-build, or explicitly by nix-instantiate).

      QUESTION: So, the part of the Nix build expression (such as default.nix) where the derivation primitive is called (explicitly or implicitly, as in mkDerivation) is the derivation, that will be ultimately be translated into store derivations?

      ANSWER: Start at section 15.4 Derivation.


      QUESTION: Also, why is typically used here? Can one define derivations outside of Nix expressions?

      ANSWER(?): One could I guess, because store derivations are ATerms (see annotation at the top), and the Nix expression language is just a tool to translate parameterized build actions into concrete terms to build a software package. The store derivations could be achieved using different means; e.g., the way Guix uses Guile scheme to get the same result))


      I believe, that originally, derivation was simply a synonym to store derivation. Maybe it still is, and I'm just having difficulties with reading comprehension but I think the following would be less misleading (to me and apart from re-writing the very first sentence):

      Derivations are typically the result of Nix expressions calling the derivation primitive explicitly, or implicitly usingmkDerivation`. These are translated into low-level store derivations (implicitly by nix-env and nix-build, or explicitly by nix-instantiate).

    5. $stdenv/setup

      QUESTION: Does this refer to pkgs/stdenv/generic/setup.sh? According to 6.5 Phases in the Nixpkgs manual?

      ANSWER: I'm pretty sure it does. It sets up the environment (not sure how yet; I see the env vars, but not the basic commands - sed, awk, etc. - that are listed below) and defines a bunch of functions (such as genericBuilder) but it doesn't call these functions!

    6. The function mkDerivation in the Nixpkgs standard environment is a wrapper around derivation that adds a default value for system and always uses Bash as the builder, to which the supplied builder is passed as a command-line argument. See the Nixpkgs manual for details.

      "Documented" in the Nixpkgs manual under 6.1 Using stdenv.

      Used the double-quotes above because I don't consider it well documted. Will give it a try too; worst case scenario is that I'll fail as well.

    7. C.12. Release 1.6 (2013-09-10)In addition to the usual bug fixes, this release has several new features:The command nix-build --run-env has been renamed to nix-shell.
    8. See annotations with the build-phases tag.


      Why are the build phases not enumerated in the Nix manual? If the instructions on how to create a derivation (and thus, a package) then why not go all in instead of spreading out information in different manuals, making the subject harder to grasp?...

      (By the way, it is documented in the Nixpkgs manual under 6.5 Phases; not sure why it is not called build phases when every page refers to them like that.)

    9. Chapter 14. A Simple Nix Expression

      This such a stupid move to go through a derivation example before introducing the language.

    10. Add the package to the file pkgs/top-level/all-packages.nix. The Nix expression written in the first step is a function; it requires other packages in order to build it. In this step you put it all together, i.e., you call the function with the right arguments to build the actual package.

      In addition to this rant, step 3. should be more generic, instead of tying it to Nixpkgs; at least, either show how to build your own Nix expression repo, or don't add this step, but it is not at all necessary to write a derivation. There is a Nixpkgs manual for a reason.

    11. $ nix-env -i firefox --substituters ssh://alice@avalon This works similar to the binary cache substituter that Nix usually uses, only using SSH instead of HTTP

      So a substitute is a built binary for a given derivation, and a substituter is a server (or binary cache) that serves pre-built binaries, right?

      Update: in the next line it says that "it will fall back to using the binary cache substituter", so I guess that answers it.

    12. substitute

      this is another key topic. Also:

      • substitute vs. substituter => this (I think)

      See annotations with the substitute tag

    13. When you ask Nix to install a package, it will first try to get it in pre-compiled form from a binary cache. By default, Nix will use the binary cache https://cache.nixos.org; it contains binaries for most packages in Nixpkgs. Only if no binary is available in the binary cache, Nix will build the package from source. So if nix-env -i subversion results in Nix building stuff from source, then either the package is not built for your platform by the Nixpkgs build servers, or your version of Nixpkgs is too old or too new.

      binary caches tie in with substitutes somehow; get to the bottom of it. See annotations with the substitute tag.

      Maybe this?

    14. closure

      Another gem: who knows what a "closure" is.

      [This highlight] (a couple lines below) implicitly explains it though:

      The command nix-copy-closure copies a Nix store path along with all its dependencies to or from another machine via the SSH protocol. It doesn’t copy store paths that are already present on the target machine.

      or this, also just a couple lines below:

      the closure of a store path (that is, the path and all its dependencies)

    15. the closure of a store path (that is, the path and all its dependencies)
    16. The command nix-copy-closure copies a Nix store path along with all its dependencies to or from another machine via the SSH protocol. It doesn’t copy store paths that are already present on the target machine. For example, the following command copies Firefox with all its dependencies:
    17. subscribes you to a channel that always contains that latest version of the Nix Packages collection.

      That is a misleading statement. The latest version is where the master branch points, isn't it?

      So a channel points to a Nixpkgs commit (on a branch named after the channel) where all packages inside are deemed stable, and all packages are built to have available binary substitutes by a (hydra) build farm.

    18. A Nix channel is just a URL that points to a place that contains a set of Nix expressions and a manifest.
    19. garbage collector roots

      Definitely avoid this, when a term is used but only introduced formally way later. (There is also a reference to "garbage collector roots" almost at the beginning as well.)

    20. $ nix-env --switch-profile /nix/var/nix/profiles/my-profile $ nix-env --switch-profile /nix/var/nix/profiles/default These commands switch to the my-profile and default profile, respectively. If the profile doesn’t exist, it will be created automatically.

      learn more about profiles; creating new profiles was new info

    21. Chapter 10. ProfilesProfiles and user environments are Nix’s mechanism for implementing the ability to allow different users to have different configurations, and to do atomic upgrades and rollbacks.
    22. user environment
    23. In Nix, different users can have different “views” on the set of installed applications. That is, there might be lots of applications present on the system (possibly in many different versions), but users can have a specific selection of those active — where “active” just means that it appears in a directory in the user’s PATH. Such a view on the set of installed applications is called a user environment, which is just a directory tree consisting of symlinks to the files of the active applications.
    24. nix-env -qas

      ... and it takes AGES to complete

    25. 4.3.1. Change the Nix store path prefix

      There is a lot of place in this manual (and probably in the others as well) where the prefix is referred to (usually with italics, such as "prefix/store"), so in the book

      • this should be linked to this section (or the one in the book), and

      • establish a clear and well-communicated notation to convey this

    26. At the same time, it is not possible for one user to inject a Trojan horse into a package that might be used by another user.
    27. Chapter 6. SecurityNix has two basic security models. First, it can be used in “single-user mode”, which is similar to what most other package management tools do: there is a single user (typically root) who performs all package management operations. All other users can then use the installed packages, but they cannot perform package management operations themselves.Alternatively, you can configure Nix in “multi-user mode”. In this model, all users can perform package management operations — for instance, every user can install software without requiring root privileges. Nix ensures that this is secure. For instance, it’s not possible for one user to overwrite a package used by another user with a Trojan horse.

      Would have been nice to link these to the install chapter where single- and multi-user modes were mentioned.

      How would this look in a topic-based documentation? I would think that his chapter would be listed in the pre-requisites, and it could be used to buld different reading paths (or assemblies in DocBook, I believe) such as practical, depth-first (if there are people like me who want to understand everything first), etc.

    28. reentrancy
    29. You can uninstall Nix simply by running: $ rm -rf /nix
    30. $ mkdir /nix $ chown alice /nix

      Traditionally, when a command should be invoked with sudo, it is either included in the example, or the shell indicator is # instead of $.

    31. To explicitly select a single-user installation on your system:

      It should be noted in this section also that since nix 2.1.0, single user install is the default.

    32. nix-shell '<nixpkgs>' -A pan

      What is happening here exactly?

      nix-shell's syntax synopsis always bugged because it looks like this

      SYNOPSIS
      nix-shell [--arg name value] [--argstr name value] [{--attr | -A} attrPath] [--command cmd] [--run cmd] [--exclude regexp] [--pure] [--keep name] {{--packages | -p} packages...  | [path]}
      

      and the canonical example is nix-shell '<nixpkgs>' -A pan; what tripped me up is that path is usually the first in examples, and I thought that the position of arguments are strict. As it turns out, nix-shell -A pan '<nixpkgs> is just as valid.

      Side note<br> Apparently there is no standard for man pages. See 1, 2.

      '<nixpkgs>' path is the one specified in the NIX_PATH environment variable, and -A pan looks up the pan attribute in pkgs/top-level/all-packages.nix in the Nixpkgs repo.

    33. since packages aren’t overwritten, the old versions are still there after an upgrade. This means that you can roll back to the old version:

      Wouldn't hurt to tell folks that this is a convenience layer, and one could also just use the old package from the /nix/store, even though that path would be long and obscure; one could use symlinks of course.

      Or, onc could just use nix-shell -p that specifies a specific version (that's already in the store), but, of course, it's not that simple...

      https://github.com/NixOS/nixpkgs/issues/9682

    1. A derivation from a Nix language view point is simply a set, with some attributes. Therefore you can pass the derivation around with variables like anything else.
    2. the single repository technique. The natural implementation in Nix is to create a top-level Nix expression, and one expression for each package. The top-level expression imports and combines all expressions in a giant attribute set with name -> package pairs. But isn't that heavy? It isn't, because Nix is a lazy language, it evaluates only what's needed! And that's why nixpkgs is able to maintain such a big software repository in a giant attribute set.

      This is the gist of how Nixpkgs works (and how it is organized).

    3. 17.3. Fixed point

      QUESTION: What is a fixed-point of a function?

      ANSWER: See this video) at least, and the Fixed-point (mathematics)) wikipedia article:

      In mathematics, a fixed point (sometimes shortened to fixpoint, also known as an invariant point) of a function is an element of the function's domain that is mapped to itself by the function. That is to say, c is a fixed point of the function f if f(c) = c. This means

      f(f(...f(c)...)) = f n(c) = c
      

      an important terminating consideration when recursively computing f. A set of fixed points is sometimes called a fixed set.

      For example, if f is defined on the real numbers by f(x)=x^{2}-3x+4,}, then 2 is a fixed point of f, because f(2) = 2.

      There is also the wiki article fixed-point combinator that actually plays a role here, but read through the articles in this order.

      Then dissect the Stackoverflow thread What is a Y combinator?, and pay attention to the comments! For example:

      According to Mike Vanier's description, your definition for Y is actually not a combinator because it's recursive. Under "Eliminating (most) explicit recursion (lazy version)" he has the lazy scheme equivalent of your C# code but explains in point 2: "It is not a combinator, because the Y in the body of the definition is a free variable which is only bound once the definition is complete..." I think the cool thing about Y-combinators is that they produce recursion by evaluating the fixed-point of a function. In this way, they don't need explicit recursion. – GrantJ Jul 18 '11 at 0:02

      (wut?)

      Other resources in no particular order:


      QUESTION: How the hell did they come up with the idea of using this with Nix and package management? (..and who? I remember a video saved somewhere, but maybe that was about overlays)


      QUESTION: ... and how does it work in this context?

      ANSWER: Well, not an answer yet, but this may be something in the right direction:

      http://blog.tpleyer.de/posts/2020-01-29-Nix-overlay-evaluation-example.html

    4. there's no ldconfig cache either. So where does bash find libc?

      QUESTION: What is ldconfig cache?

      QUESTION: What is libc and why does Bash need it?

    5. Derivations/packages are stored in the Nix store as follows: /nix/store/hash-name, where the hash uniquely identifies the derivation (this isn't quite true, it's a little more complex), and the name is the name of the derivation.

      QUESTION: So the Nix store houses derivations and not the built packages?

      QUESTION: Are the hashes in the Nix store not unique?

    6. In Nix there is the notion of a derivation rather than a package. The difference can be subtle at the beginning, so I will often use the words interchangeably.

      Doesn't really say anything but thought it important to highlight this first mention of derivations in the Nix Pills.

    7. From an administrator's point of view: you can use containers. The typical solution nowadays is to create a container per service, especially when different versions are needed. That somewhat solves the problem, but at a different level and with other drawbacks. For example, needing orchestration tools, setting up a shared cache of packages, and new machines to monitor rather than simple services.

      This is a very good pointer; I guess it refers to systemd services when it mentions "simple services".

    1. nix-channel --list #<output> nixpkgs https://nixos.org/channels/nixpkgs-unstable The command returns a name for each channel (e.g., nixpkgs) and an URL. Note When running nix-env with the parameter -A, one can select the channel to get the package from. Such a command looks like nix-env -iA channelname.packagename.

      Instead of #<output> it should have said channel-name instead at the top nix-channel example to keep it consistent.

    2. However, using channels is not fully reproducible, as a channel may evolve to incorporate updates.

      TODO: Find other sources about this topic. I remember this mentioned already (and it makes) sense, but need to learn more.

      TODO: What is a better alternative? An own repo? Flakes? Can cachix help?

      It says right below that pinning can help but keep looking.

      When package reproducibility become a major concern, as it is the case in this tutorial, it is preferable to refer to a pinned version of the nixpkgs repository instead — i.e, a specific commit of the repository or an immutable archived tarball. The ability to pin the version of nixpkgs is powerful, it will ensure that a package is always constructed from the same Nix source. As we go deeper in the tutorial we avoid using channels in favor of pinned environments.

    3. However, it makes the “Making the package available to the user” more complex. Nix heavily relies on environment variables to make this possible

      And symlinks

    1. example: get an environment which is used to build irssi (also see nix-shell) $ nix-build $NIXPKGS --run-env -A irssi example: get a persistent environment which is used to build irssi $ nix-build $NIXPKGS --run-env -A irssi --add-root

      nix-build <path> --run-env has been superseded by nix-shell. From Nix manual section C.12. Release 1.6 (2013-09-10):

      The command nix-build --run-env has been renamed to nix-shell.

    1. NIX_PATHA colon-separated list of directories used to look up Nix expressions enclosed in angle brackets (i.e., <path>). For instance, the value

      It would be helpful to

      1. formally describe the formats for NIXPATH, and
      2. note the allowed angle bracket syntax accordingly

      <path> will work with the prefixless format, but not with the prefixed one, and it may be helpful to spell this out explicitly.

      0 [14:16:19] nix repl
      Welcome to Nix version 2.3.10. Type :? for help.
      
      nix-repl> :l <nixpkgs/doc>  
      Added 40 variables.
      
      nix-repl> :l <doc>
      error: file 'doc' was not found in the Nix search path (add it using $NIX_PATH or -I)
      

      I always saw a NIXPATH used with the prefix syntax so far:

      $ echo $NIX_PATH
      nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root
      

      but NIX_PATH documentation shows that the prefixless format is also valid.

      $ export NIX_PATH=/home/toraritte:/nix/var/nix/profiles/per-user/root/channels/nixos
      
      $ printenv NIX_PATH
      /home/toraritte:/nix/var/nix/profiles/per-user/root/channels/nixos
      
      $ nix repl
      Welcome to Nix version 2.3.10. Type :? for help.
      
      nix-repl> :l <nixpkgs>
      Added 12439 variables.
      
  20. Sep 2020
  21. Aug 2020
    1. builtins.attrValues set

      TODO: Is this the same as lib.attrsets.attrValues in nixpkgs?

    2. baseNameOf sReturn the base name of the string s, that is, everything following the final slash in the string. This is similar to the GNU basename command.

      works both on strings and paths

    3. String Concatenation string1 + string2 leftString concatenation.
    1. 5.1.2.6. lib.attrsets.attrValuesattrValues :: AttrSet -> [Any]

      TODO Is this an alias to builtins.attrValues?

    2. type Option type, providing type-checking and value merging.

      This is vague to the point of being useless, given the Nix expression language is untyped.

      A snippet from freeswitch.nix:

            configTemplate = mkOption {
              type = types.path;
              # omitted
            };
            configDir = mkOption {
              type = with types; attrsOf path;
              # omitted
            };
      
      • Where does types come from?

        See NixOS manual at "Option types".

      • What is the difference between the path types? (I guess, the second one is attribute set consisting only of paths.)

    3. TODO: document lib.mkIf

      Found a description in the NixOS manual:

      The special function mkIf causes the evaluation of the conditional to be “pushed down” into the individual definitions, as if you had written:

      config = {
        environment.systemPackages = if
      config.services.httpd.enable then [ ... ] else [];
        ...
      };
      
    4. TODO: document lib.mkDefault

      Not mentioned in any of the manuals (i.e., nix, nixpkgs, NixOS), only the NixOS options page has 1 mention:

      Some promising search result (in the order of relevance):


      From source:

        mkOverride = priority: content:
          { _type = "override";
            inherit priority content;
          };
      
        mkDefault = mkOverride 1000; # used in config sections of non-user modules to set a default
      

      It seems that all the mkOverride calls set up a priority for certain actions.

    5. 5.1.7. NixOS / nixpkgs option handling

      What is an option?

      From the link below to the source, it's just an attribute set with all the function parameters (see below) plus a _type attribute name to allow for type level operations (because Nix is untyped).

        mkOption =
          {
          # Default value used when no definition is given in the configuration.
          default ? null,
          # Textual representation of the default, for the manual.
          defaultText ? null,
          # Example value used in the manual.
          example ? null,
          # String describing the option.
          description ? null,
          # Related packages used in the manual (see `genRelatedPackages` in ../nixos/lib/make-options-doc/default.nix).
          relatedPackages ? null,
          # Option type, providing type-checking and value merging.
          type ? null,
          # Function that converts the option value to something else.
          apply ? null,
          # Whether the option is for NixOS developers only.
          internal ? null,
          # Whether the option shows up in the manual.
          visible ? null,
          # Whether the option can be set only once
          readOnly ? null,
          # Deprecated, used by types.optionSet.
          options ? null
          } @ attrs:
          attrs // { _type = "option"; };
      

      How does it fit in a big scheme of things?

      ?

    6. 5.1.2.25. lib.attrsets.recursiveUpdateUntil

      If there is recursiveUpdateUntil (i.e., mergeUntil) then mergeWith would also be welcome.

    7. 5.1.2.26. lib.attrsets.recursiveUpdaterecursiveUpdate :: AttrSet -> AttrSet -> AttrSet

      Would be nice to have an alias called merge.

    8. String -> Any -> { name = String; value = Any }

      Fix: add semicolon after last Any. (same above in the main type signature)

    9. mapAttrsToList :: (String -> Any -> Any) -> AttrSet -> Any Located at lib/attrsets.nix:233 in <nixpkgs>. Call fn for each attribute in the given set and return the result in a list.

      So the type signature

      (String -> Any -> Any) -> AttrSet -> Any
                                           ^^^
      

      should be

      
      (String -> Any -> Any) -> AttrSet -> List
                                           ^^^^
      

      instead, right?

    10. 5.1.2.11. lib.attrsets.collectcollect :: (Any -> Bool) -> AttrSet -> [Any]
    11. 5.1.2.7. lib.attrsets.catAttrscatAttrs :: String -> [AttrSet] -> [Any] Located at lib/attrsets.nix:113 in <nixpkgs>. Collect each attribute named `attr' from the list of attribute sets, sets.

      Then why not call it collectVals?... (Following the distinctive naming convention between lib.attrsets.attrVals and lib.attrsets.attrValues.)

      Especially because there is lib.attrsets.collect:

      catAttrs :: String -> [AttrSet] -> [Any]
      collect :: (Any -> Bool) -> AttrSet -> [Any]
      

      (Call it filterVals? There are filterAttrs* functions but those return an attribute set, so no collision.)

    12. Attribute-Set

      This should read "Attribute Set Functions". Nowhere else is attribute sets spelled as "attribute-set".

      edit: Alright, "attribute-set" is used in total of 4 times, whereas "attribute set" is used 112 times.

    1. > (square: (x: y: square x + square y) 3 7) (x: x*x)58

      This can be written up in many other forms, plus the possibility of currying deserves to be pointed out:

      $ nix repl
      nix-repl> (sq: (x: y: sq y + sq x) 2 7) (x: x*x)
      53
      
      nix-repl> (sq: (x: y: sq y + sq x)) (x: x*x)     
      «lambda @ (string):1:11»
      
      nix-repl> (sq: (x: y: sq y + sq x)) (x: x*x) 2
      «lambda @ (string):1:14»
      
      nix-repl> (sq: (x: y: sq y + sq x)) (x: x*x) 2 7
      53
      
      nix-repl> (sq: x: y: sq y + sq x) (x: x*x) 2 7   
      53
      
  22. Jul 2020
    1. The most commonly supported tool for this is kerl. Kerl is a wrapper around downloading, compiling, and loading various Erlang/OTP versions on a single system, and will abstract away most annoying operations.
  23. Jun 2020
    1. Why is Nix written in C++ rather than a functional language like Haskell?[ ] Mainly because Nix is intended to be lightweight, easy to learn and portable (zero dependencies). Since 24. April 2017 thanks to Shea Levy and the crowdfunding of 54 community members, nix does not have Perl as dependency anymore.

      There is hnix that is still actively developed (as of 2020/06/21).

    1. Basic Install environment.systemPackages = with pkgs; [ vim ]; or environment.systemPackages = with pkgs; [ vim_configurable ];

      What is the difference between the vim and vim_configurable packages?

      I believe the source for the latter is here.

    1. boot.initrd.luks.devices = [ { name = "root"; device = "/dev/nvme0n1p2"; preLVM = true; } ];

      This will still work on 20.03 but will show a warning as name = "root"; is deprecated, and luksroot should be used instead (see boot.initrd.luks.devices NixOS option) .

      boot.initd.luks.devices = {
        luksroot = {
          device = "/nev/sda2";
          preLVM = true;
        };
      };
      
  24. Apr 2020
    1. nix path-info shows information about store paths, replacing nix-store -q. A useful feature is the option --closure-size (-S). For example, the following command show the closure sizes of every path in the current NixOS system closure, sorted by size: nix path-info -rS /run/current-system | sort -nk2

      The Nixpkgs pull request template has a checkbox "Determined the impact on package closure size (by running nix path-info -S before and after)" but there is only 4 instances of path-info in the Nix manual (and none in the Nixpkgs manual).

      nix --help says

      path-info        query information about store paths
      

      so the command works at the bottom but what switches are available for example? From the examples, -r and -S is valid but where are they documented?

      nix path-info -rS $(readlink -f $(which vim))

  25. Mar 2020
  26. Feb 2020
    1. Nix is a purely functional package manager. This means that it treats packages like values in purely functional programming languages such as Haskell — they are built by functions that don’t have side-effects, and they never change after they have been built.
    2. Nix helps you make sure that package dependency specifications are complete. In general, when you’re making a package for a package management system like RPM, you have to specify for each package what its dependencies are, but there are no guarantees that this specification is complete. If you forget a dependency, then the component will build and work correctly on your machine if you have the dependency installed, but not on the end user's machine if it's not there.
    1. Never compile the same project twice Nix allows to easily share build results across machines. If the CI has built the project, developers or servers can download the build results instead of re-building the same thing.
  27. Nov 2019
    1. { packageOverrides = pkgs: rec { foo = pkgs.foo.override { ... }; }; }

      Why is rec needed here, and not in the example under 2.6.1?

      Based on what I saw with other examples, rec is usually included when a_package.override is used inside packageOverrides. But why?

    1. 3. Deployment as Memory Management

      The entire chapter 3 is worth reading. Great resource on what a package (or more broadly, a component) is in regards to Nix.

      Specifically "3.1 What is a component?"

    1. packages

      There is no officially prescribed reading order of the Nix manuals, but it's safe to say that one should start this, the Nix manual. Then it would be prudent to briefly describe what a package is in the context of Nix and/or (at east) link to the definition.

      I like how Dolstra's thesis has an entire section on the topic (that is, on the more general concept of components).

    2. You can have multiple versions or variants of a package installed at the same time.

      It is clear now that there can be multiple versions of the same package in the store, but how does one call them (e.g., if is an executable application)? Simply by using the full Nix store path (and create and manage one's own symlinks, with stow or manually)??

    1. haskell-overridez is a tool and library of nix functions that simplify the use of overrides while developing haskell projects with nixpkgs.

  28. Oct 2019
    1. fixed-point

      "fixed-point", "fix point" seems to be most important concept in Nix, because overrides, overridePackages, overlays are built using it.

    2. Overlays
    3. buildEnv
    4. stdenv.lib.licenses

      Find out where stdenv.lib functions are documented.

    5. builtins.elem

      builtins.elem x xs

      Return true if a value equal to x occurs in the list xs, and false otherwise.

    6. builtins.parseDrvName

      builtins.parseDrvName s

      Split the string s into a package name and version. The package name is everything up to but not including the first dash followed by a digit, and the version is everything following that dash. The result is returned in a set { name, version }. Thus, builtins.parseDrvName "nix-0.12pre12876" returns { name = "nix"; version = "0.12pre12876"; }.

    7. This option is a function which accepts a package as a parameter, and returns a boolean. The following example configuration accepts a package and always returns false: { allowUnfreePredicate = (pkg: false); }

      What is a package in this context? That is, the callback's pkg parameter. Is it a derivation?

      If I understood it correctly, whenever referencing other packages as inputs, those are actually derivations, that are just attribute sets.

  29. Jul 2019
  30. Jun 2019
  31. Dec 2018
  32. Nov 2018
  33. Oct 2018
  34. Sep 2018
  35. Jul 2018
  36. Jun 2018
  37. Dec 2017