668 Commits

Author SHA1 Message Date
adisbladis
59d55cbaa3 lib.sources.sourceByGlobs: init function
Adds a source filtering function inspired by [doublestar](https://github.com/bmatcuk/doublestar).

This has been in used in a few private repositories since the last ~6 months with success.

- Testing

This was originally tested with the nix-unit testsuite:
```
let
  inherit (import ./internal.nix) mkSourceFilter mkMatcher;
in
{
  mkMatcher = {
    empty = {
      testMatch = {
        expr = mkMatcher "" "" "regular";
        expected = true;
      };

      testNoMatch = {
        expr = mkMatcher "" "foo" "regular";
        expected = false;
      };
    };

    simple = {
      testMatch = {
        expr = mkMatcher "foo" "foo" "regular";
        expected = true;
      };

      testNoMatch = {
        expr = mkMatcher "foo" "bar" "regular";
        expected = false;
      };
    };

    singleStar = {
      testMatch = {
        expr = mkMatcher "*.js" "foo.js" "regular";
        expected = true;
      };

      testNoMatch = {
        expr = mkMatcher "*.js" "foo.py" "regular";
        expected = false;
      };
    };

    doubleStar = {
      testMatch = {
        expr = mkMatcher "foo/**/bar" "foo/baz/bar" "regular";
        expected = true;
      };

      testNoMatch = {
        expr = mkMatcher "foo/**/bar" "foo/bar/baz" "regular";
        expected = false;
      };

      testMultiMatch = {
        expr = mkMatcher "foo/**/bar" "foo/baz/xyz/bar" "regular";
        expected = true;
      };

      testMultiMatchDoubleGlob = {
        expr = mkMatcher "foo/**/**/bar" "foo/baz/xyz/bar" "regular";
        expected = true;
      };

      testInfixMatch = {
        expr = mkMatcher "foo/**/qux/**/bar" "foo/baz/qux/baz/bar" "regular";
        expected = true;
      };

      testInfixNoMatch = {
        expr = mkMatcher "foo/**/xyz/**/bar" "foo/baz/qux/baz/bar" "regular";
        expected = false;
      };

      # Technically a partial match
      testInfixDirMatch = {
        expr = mkMatcher "foo/**/xyz/**/bar" "foo/baz/qux/baz/bar" "directory";
        expected = true;
      };
    };
  };

  mkSourceFilter = {
    testSourceFilter = {
      expr = mkSourceFilter ./fixtures [
        "bar/*.js"
      ] "bar/bar.js" "regular";
      expected = true;
    };
  };
}
```
but it was dropped in this nixpkgs contribution as the structure of nixpkgs lib testing is too primitive to incorp this without more extensive refactoring than I'd like at the momment.

- Performance

It's hard to benchmark this against anything else meaningful except [globsset](https://github.com/pdtpartners/globset), which has a very similar API.

`sourceByGlobs` avoids performance pitfalls by:

  - Using `builtins.filterSource`

      This is more performant than the fileset API.
      The downside compared to the fileset API is that any directory which matches the filter will be added to the build, even if it's empty.

  - Match paths component by component

      By splitting each pattern into a token per / separator.
      This is much faster in Nix than the doublestar algorithm.

- Globset source

```json
{
    "cpuTime": 0.8585879802703857,
    "envs": {
        "bytes": 148252864,
        "elements": 11899843,
        "number": 6631765
    },
    "gc": {
        "heapSize": 402915328,
        "totalBytes": 671288560
    },
    "list": {
        "bytes": 3358664,
        "concats": 28658,
        "elements": 419833
    },
    "nrAvoided": 11562713,
    "nrFunctionCalls": 4816963,
    "nrLookups": 4316209,
    "nrOpUpdateValuesCopied": 5686407,
    "nrOpUpdates": 464060,
    "nrPrimOpCalls": 2966970,
    "nrThunks": 7796186,
    "sets": {
        "bytes": 196404672,
        "elements": 10837802,
        "number": 1437490
    },
    "sizes": {
        "Attr": 16,
        "Bindings": 16,
        "Env": 8,
        "Value": 24
    },
    "symbols": {
        "bytes": 340652,
        "number": 32026
    },
    "values": {
        "bytes": 207367440,
        "number": 8640310
    }
}
```

- Glob-filter source

```json
{
    "cpuTime": 0.3904629945755005,
    "envs": {
        "bytes": 13263440,
        "elements": 1005877,
        "number": 652053
    },
    "gc": {
        "heapSize": 402915328,
        "totalBytes": 146914896
    },
    "list": {
        "bytes": 3032168,
        "concats": 5899,
        "elements": 379021
    },
    "nrAvoided": 1666598,
    "nrFunctionCalls": 484399,
    "nrLookups": 112698,
    "nrOpUpdateValuesCopied": 3432135,
    "nrOpUpdates": 13426,
    "nrPrimOpCalls": 1041954,
    "nrThunks": 1205792,
    "sets": {
        "bytes": 64304800,
        "elements": 3978167,
        "number": 40883
    },
    "sizes": {
        "Attr": 16,
        "Bindings": 16,
        "Env": 8,
        "Value": 24
    },
    "symbols": {
        "bytes": 285306,
        "number": 28864
    },
    "values": {
        "bytes": 42963240,
        "number": 1790135
    }
}
```
2026-05-26 21:48:59 +12:00
Johannes Kirschbauer
ae142b5738 types.attrListWith: review fixes
- Improve extractItem error messages: distinguish non-attrset elements
  from multi-key attrsets, and include the faulty definition via showDefs.
- Use isType instead of raw _type access for order detection.
- Disable type merging (typeMerge = t: null) instead of providing a
  functor-based merge. Add test confirming duplicate declarations fail.
2026-05-24 15:32:04 +02:00
Robert Hensing
8aa6e3dbb9 types.attrListWith: add valueMeta.definitions 2026-05-24 15:32:04 +02:00
Robert Hensing
e29bf2412b lib.modules.mapDefinitionValue: init 2026-05-24 15:32:04 +02:00
Robert Hensing
f1b62fdc4e types.attrListWith: add asAttrs
This allows the type's return value to be accessed more easily.

Motivating use case:
- Built-in module provides CLI functionality by declaring
  an `attrListWith { asAttrs = true; }`, extracting the ordered list
  from `valueMeta` for the purpose of creating the `argv`.
- User modules can read the command line's flags directly without
  having to parse the list of attrs.
2026-05-24 15:07:05 +02:00
Robert Hensing
43d998e6c0 types.attrListOf: init
This adds a type for name-value mappings that preserve ordering.

Motivating use case: command line flags for package modules /
wrappers / modular services.
The option value can be transformed into a command line in the
correct order.
Additionally, a convenience readOnly option could be provided
to give easy introspection access to the values in an ad hoc
manner.
2026-05-24 15:07:02 +02:00
Mix
cadca751c4 lib.systems.equals: fix euqality on re-elaborated platform 2026-05-17 02:14:48 +08:00
Emily
036199b38a lib.systems.equals: only filter functions once (#513844) 2026-05-13 00:56:58 +00:00
Michael Daniels
18e82c4591 lib: remove unused let bindings and args@{} uses 2026-04-30 18:43:56 -04:00
Johannes Kirschbauer
5c9f6077a7 lib/concatLines: add test for empty list 2026-04-28 10:08:32 +02:00
Eman Resu
0f0f29fcf1 lib/systems: store version of elaborated system without functions 2026-04-26 23:56:51 -04:00
Ben Siraphob
0fcb031c25 lib/systems: add SH4 (SuperH) cross-compilation target
Add sh4 CPU type (32-bit, little-endian, family "sh"), isSh4 predicate,
"sh4-linux" system double, cross-compilation example (sh4-unknown-linux-gnu),
linuxArch mapping to "sh", and test entry.
2026-04-20 13:02:20 -07:00
Robert Hensing
77b5864637 lib.modules: submodule emptyValue must evaluate sub-option defaults
`emptyValue` for `types.submodule` was `{ value = { }; }`, i.e. none
of the type-declared options or their defaults.

Previously submodules without defs would simply fail for lack of a default,
but since PR #500104 repurposed `emptyValue` as the fallback when no
definitions exist, submodule options without an explicit `default = { }`
(new additions) silently lost their sub-option defaults
(e.g. `requiredFeatures.devnet` in the nixos-test-driver, #511413).

Main change: `emptyValue`: `{ }` -> `{ value = base.config; }`

Additionally, skip `emptyValue`-based default rendering in docs for
types with submodules, because their sub-options are already documented
individually, and forcing evaluation here can break on modules with
invalid or incomplete definitions.
2026-04-19 20:52:33 +01:00
jopejoe1
dbdb37908f lib/tests: add tests for lib.licenses 2026-04-19 12:22:11 +02:00
Alyssa Ross
4cd3a0ec79 lib/systems: add ARC cross-compilation target (#510160) 2026-04-15 15:51:26 +00:00
Ben Siraphob
6152e8cbfa lib/systems: add ARC (Synopsys DesignWare ARC) cross-compilation support
Add arc CPU type (32-bit, little-endian, family "arc"), isArc
predicate, arc-linux double, arc cross example with
arc-unknown-linux-gnu triple, and release-cross job.

ARC has glibc support and uses the "arc" Linux kernel arch, which
matches the CPU name so no explicit linuxArch mapping is needed.
2026-04-14 13:51:11 -07:00
Johannes Kirschbauer
dbe18bc16d lib.types.defaultTypeMerge: Fix for functors with no wrapped attr (#476219) 2026-04-14 07:15:44 +00:00
Robert Hensing
8d4e372952 lib.types: add types.option (#499945) 2026-04-08 13:41:10 +00:00
Robert Hensing
17c056fa24 lib.types.optionDeclaration: test error 2026-04-03 10:53:47 +02:00
cinereal
7334dd9096 lib.types: add types.option
Signed-off-by: cinereal <cinereal@riseup.net>
2026-04-02 12:10:29 +02:00
Robert Hensing
ff011b00be lib/modules: Improve errors involving pushDownProperties (#502117) 2026-04-01 16:00:01 +00:00
Timothy Gallion
f32c37b88c lib.types.defaultTypeMerge: Fix for functors with no wrapped attr
Downstream types that want to use `lib.types.defaultTypeMerge` must include
`wrapped` even though it is deprecated or the internal
`wrappedDeprecationMessage`. This is caused by accessing the
`wrapped` attr in `lib.types.defaultTypeMerge`. The logic should first check
if the attr exists and then if it does check if it is null.
2026-03-29 15:14:00 -04:00
Johannes Kirschbauer
075bb50b1a lib.modules: default to emptyValue (#500104) 2026-03-25 11:00:39 +00:00
cinereal
4c7577dd94 lib.options: reflect emptyValue-based option defaults in documentation
Signed-off-by: cinereal <cinereal@riseup.net>
2026-03-24 14:02:55 +01:00
cinereal
ac0ef82504 lib.modules: default to emptyValue
Signed-off-by: cinereal <cinereal@riseup.net>
2026-03-23 16:04:32 +01:00
dramforever
d48a370de1 lib/modules: Add error message test for pushing down non-attrsets 2026-03-22 14:11:01 +08:00
Philip Taron
4085f24e25 lib.makeScope: add tests for callPackage overriding
Test that:
- makeScope provides a default callPackage
- the scope function can override callPackage
- the override persists through overrideScope
2026-03-19 14:11:11 -07:00
John Ericson
704e1a5c16 lib.systems: add uefi support (#477645) 2026-03-02 05:32:37 +00:00
Silvan Mosberger
b54233e11c lib.maintainers: Enforce unique github[Id], email, matrix 2026-02-09 21:51:01 +01:00
Silvan Mosberger
58b187378d lib/modules: add suggestions to invalid option name errors (#442263) 2026-02-03 19:10:35 +00:00
Theo Paris
9f605ca95e lib.systems: add uefi support
Signed-off-by: Theo Paris <theo@theoparis.com>
Change-Id: I51ce15449fc83f0ff39277d7cde7b34a6a6a6964

lib.systems: remove i686-uefi
2026-01-25 21:59:21 -08:00
Dyego Aurélio
28096cc5e3 treewide: apply nixfmt 1.2.0 2026-01-22 18:37:56 -03:00
Johannes Kirschbauer
04c56b7e59 lib.lists.replaceElemAt: init (#477775) 2026-01-22 15:58:28 +00:00
Johannes Kirschbauer
f4d45cdced lib/types: add tests for types.mkStructuredType 2026-01-20 21:26:05 +01:00
Johannes Kirschbauer
53b47eb93d lib/tests: add strict option to checkConfigOutput 2026-01-20 21:26:05 +01:00
Glen Huang
0445cc8aab lib.lists.replaceElemAt: init
It's very easy to resort to lib.take + lib.drop to accomplish this, but it's not obvious that it actually performs quite badly.

Replacing an item in a list should be a relative common operation.
2026-01-12 11:58:42 +00:00
Shelvacu
5018a33b62 lib/strings.escapeNixIdentifier: quote keywords
Previously `lib.strings.escapeNixIdentifier "assert"` would return `"assert"`; This is wrong, `assert` is not a valid identifier unless quoted.\

This also fixes `lib.generators.toPretty`: `toPretty {} { "assert" = false; }` would previously return an invalid expression.
2026-01-02 13:47:32 -08:00
Robert Hensing
34b2f6702f lib.makeOverridable: preserve constructor override and metadata attributes (#461032) 2025-12-22 13:20:41 +00:00
Tom Hubrecht
ba6b3a4f6c lib/tests: Use --option to enable abort-on-warn 2025-12-08 08:44:53 +01:00
Robert Hensing
649a766e35 lib/tests: move throwTestFailures tests to standalone script
The throwTestFailures tests in misc.nix produce confusing trace output
that looks like test failures even when tests pass.

This commit moves these tests to a new lib/tests/debug.sh script,
following the pattern from modules.sh, sources.sh, and filesystem.sh.

The confusing trace output does not appear in any logs anymore.

Example of the confusing log:

trace: FAIL "testDerivation":
Expected:
<derivation a>

Result:
<derivation b>

evaluation warning: Using `lib.generators.toPlist` without `escape = true` is deprecated
[ ]
2025-11-26 23:51:59 +01:00
Robert Hensing
75c025c613 lib/types: make attrTag's description field list valid choices (#464627) 2025-11-25 18:28:32 +00:00
Johannes Kirschbauer
3ae8192162 lib: deprecate fold (#456532) 2025-11-25 14:15:41 +00:00
cinereal
cf4da9fd69 lib/types: make attrTag's description field list valid choices
Lists the valid choices in `attrTag` type's `description` field.
Given this description is used in error messages, this serves to make
for somewhat more descriptive errors in the event an option involving
this type turns out not to match.

Signed-off-by: cinereal <cinereal@riseup.net>
2025-11-24 18:45:48 +01:00
Yueh-Shun Li
21021adbe9 lib.makeOverrdable: preserve constructor override and metadata attributes 2025-11-13 18:01:44 +08:00
Rebecca Turner
dc4cf16993 lib.debug.throwTestFailures: init
`lib.debug.runTests` provides a unit test evaluator for Nix, but its
results are returned in a raw and difficult-to-read form.

Currently, different callers output the results in various ways:
`builtins.throw (builtins.toJSON failures)` and `builtins.throw ("Tests
failed: " + lib.generators.toPretty { } failures)` are both used.

This change adds a new `lib.debug.throwTestFailures` function which
displays the results nicely before throwing an exception (or returns
`null` if no failures are given), unifying these disparate call-sites.

First, each failing test is pretty-printed in a `trace` message:

```
trace: FAIL testDerivation:
  Expected: <derivation a>
    Result: <derivation b>
```

Then, an exception is thrown containing the number of tests that failed
(and their names), followed by the raw JSON of the results (for parity
with previous usage, and because `lib.generators.toPretty` sometimes
omits information that `builins.toJSON` includes):

```
error:
       … while evaluating the file '...':

       … caused by explicit throw
         at /nix/store/.../lib/debug.nix:528:7:
          527|       in
          528|       throw (
             |       ^
          529|         builtins.seq traceFailures (

       error: 1 tests failed:
       - testDerivation

       [{"expected":"/nix/store/xh7kyqp69mxkwspmi81a94m9xx74r8dr-a","name":"testDerivation","result":"/nix/store/503l84nir4zw57d1shfhai25bxxn16c6-b"}]
```
2025-11-10 10:41:31 -08:00
Felix Buehler
3106949fd7 lib/types: add externalPath 2025-11-04 22:57:16 +01:00
Robert Hensing
49f0cbd7f8 lib.types: introduce a fileset type (#428293) 2025-11-04 13:44:33 +00:00
Robert Hensing
acb6191c6e lib: Add splicing utilities (#426889) 2025-10-30 21:22:54 +00:00
Aliaksandr
f4d36941eb lib: deprecate fold 2025-10-30 16:56:49 +02:00
Robert Hensing
586961172a lib/modules: Report error for unsupported t // { check = ...; } (#454964) 2025-10-28 16:40:39 +00:00