It's a common pattern in Nixpkgs to want to emit a warning in certain
cases, but not actually change behaviours.
This is often expressed as either
if cond then lib.warn "Don't do that thing" x else x
Or
(if cond then lib.warn "Don't do that thing" else lib.id) x
Neither of which really expresses the intent here, because it looks
like 'x' is being chosen conditionally.
To make this clearer, I introduce a "warnIf" function, which makes it
clear that the only thing being affected by the condition is whether
the warning is generated, not the value being returned.
Immensely helpful when you want to see the changes a function makes to
its value as it passes through.
Example:
```
$ nix-instantiate --strict --eval -E '(with import ./lib; traceFnSeqN 2 "id" (x: x) { a.b.c = 3; })'
trace: {
fn = "id";
from = {
a = {
b = {…};
};
};
to = {
a = {
b = {…};
};
};
}
{ a = { b = { c = 3; }; }; }
```
Nix can perform static scope checking, but whenever code is inside
a `with` expression, the analysis breaks down, because it can't
know statically what's in the attribute set whose attributes were
brought into scope. In those cases, Nix has to assume that
everything works out.
Except it doesnt. Removing `with` from lib/ revealed an undefined
variable in an error message.
If that doesn't convince you that we're better off without `with`,
I can tell you that this PR results in a 3% evaluation performance
improvement because Nix can look up local variables by index.
This adds up with applications like the module system.
Furthermore, removing `with` makes the binding site of each
variable obvious, which helps with comprehension.
`toHex` converts the given positive integer to a string of the hexadecimal
representation of that integer. For example:
```
toHex 0 => "0"
toHex 16 => "10"
toHex 250 => "FA"
```
`toBase base i` converts the positive integer `i` to a list of it
digits in the given `base`. For example:
```
toBase 10 123 => [ 1 2 3 ]
toBase 2 6 => [ 1 1 0 ]
toBase 16 250 => [ 15 10 ]
```
The previous hash was too short and caused evaluation-time errors like:
invalid SRI hash 'sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='
Additionally, since the fact that this is broken implies that nobody
could have been using it, "SRI" is a bit of a vague and obscure term,
`fakeSriHash` would be somewhat of a mouthful, and the relevant fetcher
parameters are just called `hash`, rename it to `fakeHash`.
lib/cli is very similar to generators, so it should follow largely the
same interface. Similar to how generators isn’t exported, we should
also namespace cli by default (plus “cli” is only three characters to
type).
Before c9214c394b248e1f26e45dbe1be2bd82363af3a6 and
9d396d2e426b9a765de0b8999aa214f1259633e6 if .git is symlink the version
would gracefully default to no git revision. With those changes an
exception is thrown instead.
This introduces a new function `pathIsGitRepo` that checks if
`commitIdFromGitRepo` fails without error so we don't have to
reimplement this logic again and can fail gracefully.
lib.commitIdFromGitRepo now resolves the refs from the
parent repository in case the supplied path is a file
containing the path to said repository. this adds support
for git-worktree and things alike. see gitrepository-layout(5).
this also:
- adds a new boolean function lib.pathIsRegularFile to
check whether a path is a regular file
- patches lib.revisionWithDefault and
the revision and versionSuffix attributes in
config.system.nixos in order to support git-worktrees
With this change, disabledModules applies recursively, meaning if you
have a module "foo.nix" with
imports = [ ./bar.nix ];
then setting
disabledModules = [ "foo.nix" ];
will disable both "foo.nix" and "bar.nix", whereas previously only
"foo.nix" would be disabled.
This change along with https://github.com/NixOS/nixpkgs/pull/61570 allows
modules to be fully disabled even when they have some `mkRenamedOption`
imports.
This adds a new utility to intelligently convert Nix records to
command line options to reduce boilerplate for simple use cases and to
also reduce the likelihood of malformed command lines
`pipe` is a useful operator for creating pipelines of functions.
It works around the usual problem of e.g. string operations becoming
deeply nested functions.
In principle, there are four different ways this function could be
written:
pipe val [ f1 .. fn ]
pipe val [ fn .. f1 ]
compose [ f1 .. fn ] val
compose [ fn .. f1 ] val
The third and fourth form mirror composition of functions, they would
be the same as e.g. `(f1 << f2 << f3 .. << fn) val`.
However, it is not clear which direction the list should have (as one
can see in the second form, which is the most absurd.
In order not to confuse users, we decide for the most “intuitive”
form, which mirrors the way unix pipes work (thus the name `pipe`).
The flow of data goes from left to right.
Co-Authored-By: Silvan Mosberger <infinisil@icloud.com>
Remove the "version" parameter in order to make it more widely
available.
Starts making some kernel configuration helpers available.
The intent is to be able to better build and check the linux kernel
configuration.
This makes the function available without having to evaluate the
Nixpkgs fix-point, making it available in a more natural way for
code that deals with multiple Nixpkgs invocations.
Its definition is coupled to Nix rather than Nixpkgs, so it will
feel right at home in lib.
The main purpose is to bring attention to `flip map`, which improves
code readablity. It is useful when ad-hoc anonymous function
grows two or more lines in `map` application:
```
map (lcfg:
let port = lcfg.port;
portStr = if port != defaultPort then ":${toString port}" else "";
scheme = if cfg.enableSSL then "https" else "http";
in "${scheme}://cfg.hostName${portStr}"
) (getListen cfg);
```
Compare this to `foreach`-style:
```
foreach (getListen cfg) (lcfg:
let port = lcfg.port;
portStr = if port != defaultPort then ":${toString port}" else "";
scheme = if cfg.enableSSL then "https" else "http";
in "${scheme}://cfg.hostName${portStr}"
);
```
This is similar to Haskell's `for` (http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Traversable.html#v:for)
This commit changes the `mkAliasOptionModule` function to make sure that
the priority for the aliased option is propagated to the non-aliased
option.
This also affects the `mkRenamedOptionModule` function in a similar
fashion.
This also removes the `mkAliasOptionModuleWithPriority` function, since
its functionality is now subsumed by `mkAliasOptionModule`.
This change was recommended by @nbp:
https://github.com/NixOS/nixpkgs/pull/53397#discussion_r245487432
Fake hashes can be used as placeholders for all the places, where
Nix expression requires a hash, but we don't yet have one.
This should be more convenient than following:
- echo|sha256sum, copy into clipboard, go to editor, paste into previously
edited place
- search nixpkgs for a random package, copy it's hash to cliboard, go to
editor, paste into previously edited place
Nix can add support for these fake hashes. In that case printed error should contain
only 1 hash, so no more problem "which of two hashes from error should I use?"
Idea by irc:Synthetica
This commit adds a function `mkAliasOptionModuleWithPriority`. This
function will make an alias to an existing option and copy over the
priority.
This functionality is needed for PRs like #53041. In that case
`nixos-generate-config` added an option to `hardware-configuration.nix`
with `mkDefault`. That option was then changed and an alias created for
the old name.
The end user should be able to set the non-alias option in their
`configuration.nix` and have everything work correctly. Without this
function, the priority for the option won't be copied over correctly
and the end-user will get a message saying they have the same option
set to two different values.