From 34b38e18cf5b0d6abc8c56d4149aab53a1cf7606 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Tue, 12 Aug 2025 14:22:30 +0300 Subject: [PATCH 1/6] tests/functional/lang: Add more tests for TOML timestamps Current test suite doesn't cover the subsecond formatting at all and toml11 is quite finicky with that. We should at the very least test its behavior to avoid silent breakages on updates. (cherry picked from commit 7ed0229d1abd4414144c7af396842462ce6fc1eb) --- .../lang/eval-okay-fromTOML-timestamps.exp | 2 +- .../lang/eval-okay-fromTOML-timestamps.nix | 46 ++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/tests/functional/lang/eval-okay-fromTOML-timestamps.exp b/tests/functional/lang/eval-okay-fromTOML-timestamps.exp index 08b3c69a6..56e610533 100644 --- a/tests/functional/lang/eval-okay-fromTOML-timestamps.exp +++ b/tests/functional/lang/eval-okay-fromTOML-timestamps.exp @@ -1 +1 @@ -{ "1234" = "value"; "127.0.0.1" = "value"; a = { b = { c = { }; }; }; arr1 = [ 1 2 3 ]; arr2 = [ "red" "yellow" "green" ]; arr3 = [ [ 1 2 ] [ 3 4 5 ] ]; arr4 = [ "all" "strings" "are the same" "type" ]; arr5 = [ [ 1 2 ] [ "a" "b" "c" ] ]; arr7 = [ 1 2 3 ]; arr8 = [ 1 2 ]; bare-key = "value"; bare_key = "value"; bin1 = 214; bool1 = true; bool2 = false; "character encoding" = "value"; d = { e = { f = { }; }; }; dog = { "tater.man" = { type = { name = "pug"; }; }; }; flt1 = 1; flt2 = 3.1415; flt3 = -0.01; flt4 = 5e+22; flt5 = 1e+06; flt6 = -0.02; flt7 = 6.626e-34; flt8 = 9.22462e+06; fruit = [ { name = "apple"; physical = { color = "red"; shape = "round"; }; variety = [ { name = "red delicious"; } { name = "granny smith"; } ]; } { name = "banana"; variety = [ { name = "plantain"; } ]; } ]; g = { h = { i = { }; }; }; hex1 = 3735928559; hex2 = 3735928559; hex3 = 3735928559; int1 = 99; int2 = 42; int3 = 0; int4 = -17; int5 = 1000; int6 = 5349221; int7 = 12345; j = { "ʞ" = { l = { }; }; }; key = "value"; key2 = "value"; ld1 = { _type = "timestamp"; value = "1979-05-27"; }; ldt1 = { _type = "timestamp"; value = "1979-05-27T07:32:00"; }; ldt2 = { _type = "timestamp"; value = "1979-05-27T00:32:00.999999"; }; lt1 = { _type = "timestamp"; value = "07:32:00"; }; lt2 = { _type = "timestamp"; value = "00:32:00.999999"; }; name = "Orange"; oct1 = 342391; oct2 = 493; odt1 = { _type = "timestamp"; value = "1979-05-27T07:32:00Z"; }; odt2 = { _type = "timestamp"; value = "1979-05-27T00:32:00-07:00"; }; odt3 = { _type = "timestamp"; value = "1979-05-27T00:32:00.999999-07:00"; }; odt4 = { _type = "timestamp"; value = "1979-05-27T07:32:00Z"; }; physical = { color = "orange"; shape = "round"; }; products = [ { name = "Hammer"; sku = 738594937; } { } { color = "gray"; name = "Nail"; sku = 284758393; } ]; "quoted \"value\"" = "value"; site = { "google.com" = true; }; str = "I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF."; table-1 = { key1 = "some string"; key2 = 123; }; table-2 = { key1 = "another string"; key2 = 456; }; x = { y = { z = { w = { animal = { type = { name = "pug"; }; }; name = { first = "Tom"; last = "Preston-Werner"; }; point = { x = 1; y = 2; }; }; }; }; }; "ʎǝʞ" = "value"; } +{ "1234" = "value"; "127.0.0.1" = "value"; a = { b = { c = { }; }; }; arr1 = [ 1 2 3 ]; arr2 = [ "red" "yellow" "green" ]; arr3 = [ [ 1 2 ] [ 3 4 5 ] ]; arr4 = [ "all" "strings" "are the same" "type" ]; arr5 = [ [ 1 2 ] [ "a" "b" "c" ] ]; arr7 = [ 1 2 3 ]; arr8 = [ 1 2 ]; bare-key = "value"; bare_key = "value"; bin1 = 214; bool1 = true; bool2 = false; "character encoding" = "value"; d = { e = { f = { }; }; }; dog = { "tater.man" = { type = { name = "pug"; }; }; }; flt1 = 1; flt2 = 3.1415; flt3 = -0.01; flt4 = 5e+22; flt5 = 1e+06; flt6 = -0.02; flt7 = 6.626e-34; flt8 = 9.22462e+06; fruit = [ { name = "apple"; physical = { color = "red"; shape = "round"; }; variety = [ { name = "red delicious"; } { name = "granny smith"; } ]; } { name = "banana"; variety = [ { name = "plantain"; } ]; } ]; g = { h = { i = { }; }; }; hex1 = 3735928559; hex2 = 3735928559; hex3 = 3735928559; int1 = 99; int2 = 42; int3 = 0; int4 = -17; int5 = 1000; int6 = 5349221; int7 = 12345; j = { "ʞ" = { l = { }; }; }; key = "value"; key2 = "value"; ld1 = { _type = "timestamp"; value = "1979-05-27"; }; ldt1 = { _type = "timestamp"; value = "1979-05-27T07:32:00"; }; ldt10 = { _type = "timestamp"; value = "1979-05-27T00:32:00.123456789"; }; ldt11 = { _type = "timestamp"; value = "1979-05-27T00:32:00.123456789"; }; ldt2 = { _type = "timestamp"; value = "1979-05-27T07:32:00.100"; }; ldt3 = { _type = "timestamp"; value = "1979-05-27T07:32:00.120"; }; ldt4 = { _type = "timestamp"; value = "1979-05-27T07:32:00.123"; }; ldt5 = { _type = "timestamp"; value = "1979-05-27T00:32:00.123400"; }; ldt6 = { _type = "timestamp"; value = "1979-05-27T00:32:00.123450"; }; ldt7 = { _type = "timestamp"; value = "1979-05-27T00:32:00.123456"; }; ldt8 = { _type = "timestamp"; value = "1979-05-27T00:32:00.123456700"; }; ldt9 = { _type = "timestamp"; value = "1979-05-27T00:32:00.123456780"; }; lt1 = { _type = "timestamp"; value = "07:32:00"; }; lt10 = { _type = "timestamp"; value = "00:32:00.123456789"; }; lt11 = { _type = "timestamp"; value = "00:32:00.123456789"; }; lt2 = { _type = "timestamp"; value = "00:32:00.100"; }; lt3 = { _type = "timestamp"; value = "00:32:00.120"; }; lt4 = { _type = "timestamp"; value = "00:32:00.123"; }; lt5 = { _type = "timestamp"; value = "00:32:00.123400"; }; lt6 = { _type = "timestamp"; value = "00:32:00.123450"; }; lt7 = { _type = "timestamp"; value = "00:32:00.123456"; }; lt8 = { _type = "timestamp"; value = "00:32:00.123456700"; }; lt9 = { _type = "timestamp"; value = "00:32:00.123456780"; }; name = "Orange"; oct1 = 342391; oct2 = 493; odt1 = { _type = "timestamp"; value = "1979-05-27T07:32:00Z"; }; odt10 = { _type = "timestamp"; value = "1979-05-27T07:32:00.123456Z"; }; odt11 = { _type = "timestamp"; value = "1979-05-27T07:32:00.123456700Z"; }; odt12 = { _type = "timestamp"; value = "1979-05-27T07:32:00.123456780Z"; }; odt13 = { _type = "timestamp"; value = "1979-05-27T07:32:00.123456789Z"; }; odt14 = { _type = "timestamp"; value = "1979-05-27T07:32:00.123456789Z"; }; odt2 = { _type = "timestamp"; value = "1979-05-27T00:32:00-07:00"; }; odt3 = { _type = "timestamp"; value = "1979-05-27T00:32:00.999999-07:00"; }; odt4 = { _type = "timestamp"; value = "1979-05-27T07:32:00Z"; }; odt5 = { _type = "timestamp"; value = "1979-05-27T07:32:00.100Z"; }; odt6 = { _type = "timestamp"; value = "1979-05-27T07:32:00.120Z"; }; odt7 = { _type = "timestamp"; value = "1979-05-27T07:32:00.123Z"; }; odt8 = { _type = "timestamp"; value = "1979-05-27T07:32:00.123400Z"; }; odt9 = { _type = "timestamp"; value = "1979-05-27T07:32:00.123450Z"; }; physical = { color = "orange"; shape = "round"; }; products = [ { name = "Hammer"; sku = 738594937; } { } { color = "gray"; name = "Nail"; sku = 284758393; } ]; "quoted \"value\"" = "value"; site = { "google.com" = true; }; str = "I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF."; table-1 = { key1 = "some string"; key2 = 123; }; table-2 = { key1 = "another string"; key2 = 456; }; x = { y = { z = { w = { animal = { type = { name = "pug"; }; }; name = { first = "Tom"; last = "Preston-Werner"; }; point = { x = 1; y = 2; }; }; }; }; }; "ʎǝʞ" = "value"; } diff --git a/tests/functional/lang/eval-okay-fromTOML-timestamps.nix b/tests/functional/lang/eval-okay-fromTOML-timestamps.nix index 74cff9470..d8f3a03e9 100644 --- a/tests/functional/lang/eval-okay-fromTOML-timestamps.nix +++ b/tests/functional/lang/eval-okay-fromTOML-timestamps.nix @@ -55,11 +55,53 @@ builtins.fromTOML '' odt2 = 1979-05-27T00:32:00-07:00 odt3 = 1979-05-27T00:32:00.999999-07:00 odt4 = 1979-05-27 07:32:00Z + # milliseconds + odt5 = 1979-05-27 07:32:00.1Z + odt6 = 1979-05-27 07:32:00.12Z + odt7 = 1979-05-27 07:32:00.123Z + # microseconds + odt8 = 1979-05-27t07:32:00.1234Z + odt9 = 1979-05-27t07:32:00.12345Z + odt10 = 1979-05-27t07:32:00.123456Z + # nanoseconds + odt11 = 1979-05-27 07:32:00.1234567Z + odt12 = 1979-05-27 07:32:00.12345678Z + odt13 = 1979-05-27 07:32:00.123456789Z + # no more precision after nanoseconds + odt14 = 1979-05-27t07:32:00.1234567891Z + ldt1 = 1979-05-27T07:32:00 - ldt2 = 1979-05-27T00:32:00.999999 + # milliseconds + ldt2 = 1979-05-27T07:32:00.1 + ldt3 = 1979-05-27T07:32:00.12 + ldt4 = 1979-05-27T07:32:00.123 + # microseconds + ldt5 = 1979-05-27t00:32:00.1234 + ldt6 = 1979-05-27t00:32:00.12345 + ldt7 = 1979-05-27t00:32:00.123456 + # nanoseconds + ldt8 = 1979-05-27 00:32:00.1234567 + ldt9 = 1979-05-27 00:32:00.12345678 + ldt10 = 1979-05-27 00:32:00.123456789 + # no more precision after nanoseconds + ldt11 = 1979-05-27t00:32:00.1234567891 + ld1 = 1979-05-27 lt1 = 07:32:00 - lt2 = 00:32:00.999999 + # milliseconds + lt2 = 00:32:00.1 + lt3 = 00:32:00.12 + lt4 = 00:32:00.123 + # microseconds + lt5 = 00:32:00.1234 + lt6 = 00:32:00.12345 + lt7 = 00:32:00.123456 + # nanoseconds + lt8 = 00:32:00.1234567 + lt9 = 00:32:00.12345678 + lt10 = 00:32:00.123456789 + # no more precision after nanoseconds + lt11 = 00:32:00.1234567891 arr1 = [ 1, 2, 3 ] arr2 = [ "red", "yellow", "green" ] From 85df250bea791716ce52e85db376b0a0981b75b9 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Tue, 12 Aug 2025 14:31:34 +0300 Subject: [PATCH 2/6] libexpr: Remove extra trailing semicolons (NFC) This looks really weird after the reformat. (cherry picked from commit df4e55ffc13c413e270af134227115a20a2341ba) --- src/libexpr/primops/fromTOML.cc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/libexpr/primops/fromTOML.cc b/src/libexpr/primops/fromTOML.cc index 533739592..18a988d67 100644 --- a/src/libexpr/primops/fromTOML.cc +++ b/src/libexpr/primops/fromTOML.cc @@ -35,7 +35,6 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va v.mkAttrs(attrs); } break; - ; case toml::value_t::array: { auto array = toml::get>(t); @@ -44,25 +43,20 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va visit(*(v = state.allocValue()), array[n]); v.mkList(list); } break; - ; case toml::value_t::boolean: v.mkBool(toml::get(t)); break; - ; case toml::value_t::integer: v.mkInt(toml::get(t)); break; - ; case toml::value_t::floating: v.mkFloat(toml::get(t)); break; - ; case toml::value_t::string: { auto s = toml::get(t); forceNoNullByte(s); v.mkString(s); } break; - ; case toml::value_t::local_datetime: case toml::value_t::offset_datetime: case toml::value_t::local_date: @@ -80,11 +74,9 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va throw std::runtime_error("Dates and times are not supported"); } } break; - ; case toml::value_t::empty: v.mkNull(); break; - ; } }; From 219b85478afbc8e81edf6ecaaf0afac2f4f2668f Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Tue, 12 Aug 2025 14:54:53 +0300 Subject: [PATCH 3/6] libexpr: Use recursive lambda instead of std::function There's no reason to use a std::function for recursive lambdas since there are polymorphic lambdas. (cherry picked from commit a80a5c4dba0d944fab8f5ed57a343869ae96bf16) --- src/libexpr/primops/fromTOML.cc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libexpr/primops/fromTOML.cc b/src/libexpr/primops/fromTOML.cc index 18a988d67..9ade6705e 100644 --- a/src/libexpr/primops/fromTOML.cc +++ b/src/libexpr/primops/fromTOML.cc @@ -13,9 +13,7 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va std::istringstream tomlStream(std::string{toml}); - std::function visit; - - visit = [&](Value & v, toml::value t) { + auto visit = [&](auto & self, Value & v, toml::value t) -> void { switch (t.type()) { case toml::value_t::table: { auto table = toml::get(t); @@ -30,7 +28,7 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va for (auto & elem : table) { forceNoNullByte(elem.first); - visit(attrs.alloc(elem.first), elem.second); + self(self, attrs.alloc(elem.first), elem.second); } v.mkAttrs(attrs); @@ -40,7 +38,7 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va auto list = state.buildList(array.size()); for (const auto & [n, v] : enumerate(list)) - visit(*(v = state.allocValue()), array[n]); + self(self, *(v = state.allocValue()), array[n]); v.mkList(list); } break; case toml::value_t::boolean: @@ -81,7 +79,7 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va }; try { - visit(val, toml::parse(tomlStream, "fromTOML" /* the "filename" */)); + visit(visit, val, toml::parse(tomlStream, "fromTOML" /* the "filename" */)); } catch (std::exception & e) { // TODO: toml::syntax_error state.error("while parsing TOML: %s", e.what()).atPos(pos).debugThrow(); } From 4ba8f167ff1918c07695beffa70fed6b22f68912 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Tue, 12 Aug 2025 14:58:01 +0300 Subject: [PATCH 4/6] libexpr: Use table.size() instead of unnecessary loop (cherry picked from commit d8fc55a46e0c09241131097dbf1d6fa09e0a9808) --- src/libexpr/primops/fromTOML.cc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/libexpr/primops/fromTOML.cc b/src/libexpr/primops/fromTOML.cc index 9ade6705e..c6b50ce8e 100644 --- a/src/libexpr/primops/fromTOML.cc +++ b/src/libexpr/primops/fromTOML.cc @@ -17,14 +17,7 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va switch (t.type()) { case toml::value_t::table: { auto table = toml::get(t); - - size_t size = 0; - for (auto & i : table) { - (void) i; - size++; - } - - auto attrs = state.buildBindings(size); + auto attrs = state.buildBindings(table.size()); for (auto & elem : table) { forceNoNullByte(elem.first); From a2e7c0e0405e2bd2881c068bf6d4ceb99ee4deee Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Tue, 12 Aug 2025 16:11:54 +0300 Subject: [PATCH 5/6] libexpr: Canonicalize TOML timestamps for toml11 > 4.0 This addresses several changes from toml11 4.0 bump in nixpkgs [1]. 1. Added more regression tests for timestamp formats. Special attention needs to be paid to the precision of the subsecond range for local-time. Prior versions select the closest (upwards) multiple of 3 with a hard cap of 9 digits. 2. Normalize local datetime and offset datetime to always use the uppercase separator `T`. This is actually the issue surfaced in [2]. This canonicalization is basically a requirement by (a certain reading) of rfc3339 section 5.6 [3]. 3. If using toml11 >= 4.0 also keep the old behavior wrt to the number of digits used for subsecond part of the local-time. Newer versions cap it at 6 digits unconditionally. [1]: https://www.github.com/NixOS/nixpkgs/pull/331649 [2]: https://www.github.com/NixOS/nix/issues/11441 [3]: https://datatracker.ietf.org/doc/html/rfc3339 (cherry picked from commit dc769d72cb8ad22a0f89768682b5499a9d2b3d8b) --- src/libexpr/meson.build | 6 +++ src/libexpr/primops/fromTOML.cc | 94 ++++++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/src/libexpr/meson.build b/src/libexpr/meson.build index f5adafae0..1038d773f 100644 --- a/src/libexpr/meson.build +++ b/src/libexpr/meson.build @@ -72,6 +72,12 @@ toml11 = dependency( method : 'cmake', include_type: 'system', ) + +configdata_priv.set( + 'HAVE_TOML11_4', + toml11.version().version_compare('>= 4.0.0').to_int(), +) + deps_other += toml11 config_priv_h = configure_file( diff --git a/src/libexpr/primops/fromTOML.cc b/src/libexpr/primops/fromTOML.cc index c6b50ce8e..7d98a5de9 100644 --- a/src/libexpr/primops/fromTOML.cc +++ b/src/libexpr/primops/fromTOML.cc @@ -1,12 +1,91 @@ #include "nix/expr/primops.hh" #include "nix/expr/eval-inline.hh" +#include "expr-config-private.hh" + #include #include namespace nix { +#if HAVE_TOML11_4 + +/** + * This is what toml11 < 4.0 did when choosing the subsecond precision. + * TOML 1.0.0 spec doesn't define how sub-millisecond ranges should be handled and calls it + * implementation defined behavior. For a lack of a better choice we stick with what older versions + * of toml11 did [1]. + * + * [1]: https://github.com/ToruNiina/toml11/blob/dcfe39a783a94e8d52c885e5883a6fbb21529019/toml/datetime.hpp#L282 + */ +static size_t normalizeSubsecondPrecision(toml::local_time lt) +{ + auto millis = lt.millisecond; + auto micros = lt.microsecond; + auto nanos = lt.nanosecond; + if (millis != 0 || micros != 0 || nanos != 0) { + if (micros != 0 || nanos != 0) { + if (nanos != 0) + return 9; + return 6; + } + return 3; + } + return 0; +} + +/** + * Normalize date/time formats to serialize to the same strings as versions prior to toml11 4.0. + * + * Several things to consider: + * + * 1. Sub-millisecond range is represented the same way as in toml11 versions prior to 4.0. Precisioun is rounded + * towards the next multiple of 3 or capped at 9 digits. + * 2. Seconds must be specified. This may become optional in (yet unreleased) TOML 1.1.0, but 1.0.0 defined local time + * in terms of RFC3339 [1]. + * 3. date-time separator (`t`, `T` or space ` `) is canonicalized to an upper T. This is compliant with RFC3339 + * [1] 5.6: + * > Applications that generate this format SHOULD use upper case letters. + * + * [1]: https://datatracker.ietf.org/doc/html/rfc3339#section-5.6 + */ +static void normalizeDatetimeFormat(toml::value & t) +{ + if (t.is_local_datetime()) { + auto & ldt = t.as_local_datetime(); + t.as_local_datetime_fmt() = { + .delimiter = toml::datetime_delimiter_kind::upper_T, + // https://datatracker.ietf.org/doc/html/rfc3339#section-5.6 + .has_seconds = true, // Mandated by TOML 1.0.0 + .subsecond_precision = normalizeSubsecondPrecision(ldt.time), + }; + return; + } + + if (t.is_offset_datetime()) { + auto & odt = t.as_offset_datetime(); + t.as_offset_datetime_fmt() = { + .delimiter = toml::datetime_delimiter_kind::upper_T, + // https://datatracker.ietf.org/doc/html/rfc3339#section-5.6 + .has_seconds = true, // Mandated by TOML 1.0.0 + .subsecond_precision = normalizeSubsecondPrecision(odt.time), + }; + return; + } + + if (t.is_local_time()) { + auto & lt = t.as_local_time(); + t.as_local_time_fmt() = { + .has_seconds = true, // Mandated by TOML 1.0.0 + .subsecond_precision = normalizeSubsecondPrecision(lt), + }; + return; + } +} + +#endif + static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Value & val) { auto toml = state.forceStringNoCtx(*args[0], pos, "while evaluating the argument passed to builtins.fromTOML"); @@ -53,6 +132,9 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va case toml::value_t::local_date: case toml::value_t::local_time: { if (experimentalFeatureSettings.isEnabled(Xp::ParseTomlTimestamps)) { +#if HAVE_TOML11_4 + normalizeDatetimeFormat(t); +#endif auto attrs = state.buildBindings(2); attrs.alloc("_type").mkString("timestamp"); std::ostringstream s; @@ -72,7 +154,17 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va }; try { - visit(visit, val, toml::parse(tomlStream, "fromTOML" /* the "filename" */)); + visit( + visit, + val, + toml::parse( + tomlStream, + "fromTOML" /* the "filename" */ +#if HAVE_TOML11_4 + , + toml::spec::v(1, 0, 0) // Be explicit that we are parsing TOML 1.0.0 without extensions +#endif + )); } catch (std::exception & e) { // TODO: toml::syntax_error state.error("while parsing TOML: %s", e.what()).atPos(pos).debugThrow(); } From 306d8838abe47196b01334fd770a6ddcdbf91c8f Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Tue, 12 Aug 2025 16:23:00 +0300 Subject: [PATCH 6/6] packaging: Build with toml11 4.4.0 (cherry picked from commit 320b2c74ef5c67af1f96c7cbcb8028921aee78c7) --- packaging/dependencies.nix | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packaging/dependencies.nix b/packaging/dependencies.nix index 7ce3bf125..5af84ac57 100644 --- a/packaging/dependencies.nix +++ b/packaging/dependencies.nix @@ -54,6 +54,16 @@ scope: { enableLargeConfig = true; }; + toml11 = pkgs.toml11.overrideAttrs rec { + version = "4.4.0"; + src = pkgs.fetchFromGitHub { + owner = "ToruNiina"; + repo = "toml11"; + tag = "v${version}"; + hash = "sha256-sgWKYxNT22nw376ttGsTdg0AMzOwp8QH3E8mx0BZJTQ="; + }; + }; + # TODO Hack until https://github.com/NixOS/nixpkgs/issues/45462 is fixed. boost = (pkgs.boost.override {