Use custom writeTOML on older nixpkgs

This commit is contained in:
Patryk Wychowaniec 2023-07-30 14:48:47 +02:00
parent eb2bdf3b0f
commit 0e758b9648
6 changed files with 227 additions and 16 deletions

View file

@ -10,7 +10,7 @@ jobs:
linux:
strategy:
matrix:
nixpkgs: [ nixpkgs, nixpkgs-21.05, nixpkgs-21.11 ]
nixpkgs: [ nixpkgs, nixpkgs-21.05, nixpkgs-22.05, nixpkgs-23.05 ]
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2

View file

@ -8,7 +8,47 @@
rec
{
writeTOML = (formats.toml { }).generate;
# Serializes given attrset into a TOML file.
#
# Usage:
# writeTOML path attrset
#
# On newer nixpkgs, this function invokes `lib.formats.toml` that nowadays
# handles all TOML documents properly.
#
# On older nixpkgs, where that serializer doesn't work correctly¹, we rely on
# a custom implementation (with its own tiny shortcomings²).
#
# TODO remove our custom serializer after nixpkgs v23 becomes more widely
# adopted
#
# ¹ e.g. cases like `[targets."cfg(\"something\")"]` are translated badly
# ² https://github.com/nix-community/naersk/issues/263
writeTOML =
let
our-impl =
let
to-toml = import ./to-toml.nix {
inherit lib;
};
in
name: value:
runCommandLocal name {
value = to-toml value;
passAsFile = [ "value" ];
} ''
cp "$valuePath" "$out"
cat "$out"
'';
nixpkgs-impl = (formats.toml { }).generate;
in
if builtins.compareVersions lib.version "22.11" <= 0 then
our-impl
else
nixpkgs-impl;
readTOML = usePure: f:
if usePure then

139
builtins/to-toml.nix Normal file
View file

@ -0,0 +1,139 @@
{ lib }:
let
inherit (lib)
length
elemAt
concatMap
all
concatLists
concatStringsSep
concatMapStringsSep
mapAttrsToList
;
inherit (builtins)
abort
match
toJSON
typeOf
;
quoteKey = k:
if match "[a-zA-Z]+" k == []
then k
else quoteString k;
quoteString = builtins.toJSON;
outputValInner = v:
let
ty = tomlTy v;
in
if ty == "set" then
let
vals = mapAttrsToList
(k': v': "${quoteKey k'} = ${outputValInner v'}") v;
valsStr = concatStringsSep ", " vals;
in
"{ ${valsStr} }" else
outputVal v;
outputVal = v:
let
ty = tomlTy v;
in
if (ty == "bool" || ty == "int") then
builtins.toJSON v
else
if ty == "string" then
quoteString v
else
if ty == "list" || ty == "list_of_attrs" then
let
vals = map quoteString v;
valsStr = concatStringsSep ", " vals;
in
"[ ${valsStr} ]"
else
if ty == "set" then
abort "unsupported set for not-inner value"
else abort "Not implemented: type ${ty}";
outputKeyValInner = k: v:
let
ty = tomlTy v;
in
if ty == "set" then
let
vals = mapAttrsToList
(k': v': "${quoteKey k'} = ${outputValInner v'}") v;
valsStr = concatStringsSep ", " vals;
in
[ "${quoteKey k} = { ${valsStr} }" ] else
outputKeyVal k v;
# Returns a list of strings; one string per line
outputKeyVal = k: v:
let
ty = tomlTy v;
in
if ty == "bool" || ty == "int" then
[ "${quoteKey k} = ${outputValInner v}" ]
else
if ty == "string" then
[ "${quoteKey k} = ${quoteString v}" ]
else
if ty == "list_of_attrs" then
concatMap (
inner:
[ "[[${k}]]" ] ++ (concatLists (mapAttrsToList outputKeyValInner inner))
) v
else
if ty == "list" then
let
vals = map quoteString v;
valsStr = concatStringsSep ", " vals;
in
[ "${quoteKey k} = [ ${valsStr} ]" ] else
if ty == "set" then
[ "[${k}]" ] ++ (concatLists (mapAttrsToList outputKeyValInner v))
else abort "Not implemented: type ${ty} for key ${k}";
tomlTy = x:
if typeOf x == "string" then "string" else
if typeOf x == "bool" then "bool" else
if typeOf x == "int" then "int" else
if typeOf x == "float" then "float" else
if typeOf x == "set" then
if lib.isDerivation x then "string" else "set" else
if typeOf x == "list" then
if length x == 0 then "list"
else
let
ty = typeOf (elemAt x 0);
in
#assert (all (v: typeOf v == ty) x);
if ty == "set" then "list_of_attrs" else "list"
else abort "Not implemented: toml type for ${typeOf x}";
toTOML = attrs:
assert (typeOf attrs == "set");
let
byTy = lib.foldl
(
acc: x:
let
ty = tomlTy x.v;
in
acc // { "${ty}" = (acc.${ty} or []) ++ [ x ]; }
)
{} (mapAttrsToList (k: v: { inherit k v; }) attrs);
in
concatMapStringsSep "\n"
(kv: concatStringsSep "\n" (outputKeyVal kv.k kv.v))
(
(byTy.string or []) ++ (byTy.int or []) ++ (byTy.float or []) ++ (byTy.list or []) ++ (byTy.list_of_attrs or []) ++ (byTy.set or [])
)
;
in
toTOML

View file

@ -60,15 +60,15 @@
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixpkgs": {
"branch": "master",
"branch": "nixpkgs-unstable",
"description": "Nixpkgs/NixOS branches that track the Nixpkgs/NixOS channels",
"homepage": null,
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1df733d83081fe79c109b066c90badece6b8d8b1",
"sha256": "1m3s4xv35jilrmbv8hj9gzpbcqgb8vb0iqhzcm1261x8b1hiylvj",
"rev": "d2b52322f35597c62abf56de91b0236746b2a03d",
"sha256": "1zrqry4m22rbscazxbcqf5ym7ckm6v7pvxpsml23whc1gjf2hkk3",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/1df733d83081fe79c109b066c90badece6b8d8b1.tar.gz",
"url": "https://github.com/NixOS/nixpkgs/archive/d2b52322f35597c62abf56de91b0236746b2a03d.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixpkgs-21.05": {
@ -83,16 +83,28 @@
"url": "https://github.com/NixOS/nixpkgs/archive/6d684ea3adef590a2174f2723134e1ea377272d2.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixpkgs-21.11": {
"branch": "release-21.11",
"nixpkgs-22.05": {
"branch": "release-22.05",
"description": "Nix Packages collection",
"homepage": "",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "432864f33c84af53192d4b23ee5871697e57f094",
"sha256": "0sqmasma9qin7nhfzv50d1la1mi1yazn7gx2lrxi9j61i9j8l3zm",
"rev": "380be19fbd2d9079f677978361792cb25e8a3635",
"sha256": "154x9swf494mqwi4z8nbq2f0sp8pwp4fvx51lqzindjfbb9yxxv5",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/432864f33c84af53192d4b23ee5871697e57f094.tar.gz",
"url": "https://github.com/NixOS/nixpkgs/archive/380be19fbd2d9079f677978361792cb25e8a3635.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixpkgs-23.05": {
"branch": "release-23.05",
"description": "Nix Packages collection",
"homepage": "",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b81af66deb21f73a70c67e5ea189568af53b1e8c",
"sha256": "172i5kzn8qja3k0rz9wfj86fgbw2ivc68yw3ra8g86byqc1rcw1m",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/b81af66deb21f73a70c67e5ea189568af53b1e8c.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixpkgs-mozilla": {

View file

@ -1,5 +1,18 @@
{ sources, naersk, pkgs, ... }:
{ sources, pkgs, ... }:
let
fenix = import sources.fenix { };
toolchain = fenix.fromToolchainFile {
file = "${sources.agent-rs}/rust-toolchain.toml";
sha256 = "sha256-DzNEaW724O8/B8844tt5AVHmSjSQ3cmzlU4BP90oRlY=";
};
naersk = pkgs.callPackage ../../../default.nix {
cargo = toolchain;
rustc = toolchain;
};
in
naersk.buildPackage {
src = sources.agent-rs;

View file

@ -27,7 +27,14 @@ let
};
in
pkgs.runCommand "probe-rs-test"
{
buildInputs = [ app ];
} "rtthost --help && touch $out"
if builtins.compareVersions pkgs.lib.version "22.11" <= 0 then
# Executing this test requires nixpkgs > 22.11 due to changes to the TOML
# serialization function.
#
# See `writeTOML` in this repository for more details.
true
else
pkgs.runCommand "probe-rs-test"
{
buildInputs = [ app ];
} "rtthost --help && touch $out"