From f7e004a55b120c02ecb6219596820fcd32ca8772 Mon Sep 17 00:00:00 2001 From: Gytis Ivaskevicius Date: Wed, 16 Jun 2021 23:35:21 +0300 Subject: [PATCH] Fix derivation name with invalid characters (#38) * Fix derivation name with invalid characters Fix flake-utils input * Fix failing test --- check-utils.nix | 30 ++++++++++++++++++++++++++++-- examples/checks-utils/flake.nix | 21 +++++++++++---------- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/check-utils.nix b/check-utils.nix index 809d3ed..cd2cb76 100644 --- a/check-utils.nix +++ b/check-utils.nix @@ -1,7 +1,33 @@ systemOrPkgs: let - str = it: if it == null then "null" else (toString it); + inherit (builtins) foldl' unsafeDiscardStringContext elemAt match split concatStringsSep isList substring stringLength length attrNames; system = systemOrPkgs.system or systemOrPkgs; + pipe = val: functions: foldl' (x: f: f x) val functions; + max = x: y: if x > y then x else y; + + # Minimized copy-paste https://github.com/NixOS/nixpkgs/blob/master/lib/strings.nix#L746-L762 + sanitizeDerivationName = string: pipe (toString string) [ + # Get rid of string context. This is safe under the assumption that the + # resulting string is only used as a derivation name + unsafeDiscardStringContext + # Strip all leading "." + (x: elemAt (match "\\.*(.*)" x) 0) + # Split out all invalid characters + # https://github.com/NixOS/nix/blob/2.3.2/src/libstore/store-api.cc#L85-L112 + # https://github.com/NixOS/nix/blob/2242be83c61788b9c0736a92bb0b5c7bbfc40803/nix-rust/src/store/path.rs#L100-L125 + (split "[^[:alnum:]+._?=-]+") + # Replace invalid character ranges with a "-" + (map (s: if isList s then "-" else s)) + (concatStringsSep "") + # Limit to 211 characters (minus 4 chars for ".drv") + (x: substring (max (stringLength x - 207) 0) (-1) x) + # If the result is empty, replace it with "?EMPTY?" + (x: if stringLength x == 0 then "?EMPTY?" else x) + ]; + + # Minimized version of 'sanitizeDerivationName' function + str = it: if it == null then "null" else (sanitizeDerivationName it); + test = name: command: derivation { inherit name system; builder = "/bin/sh"; @@ -18,5 +44,5 @@ in hasKey = attrset: key: if attrset ? ${str key} then test "SUCCESS__${str key}__EXISTS_IN_ATTRSET" "echo success > $out" - else test "FAILURE__${str key}__DOES_NOT_EXISTS_IN_ATTRSET_SIZE_${str(builtins.length (builtins.attrNames attrset))}" "exit 1"; + else test "FAILURE__${str key}__DOES_NOT_EXISTS_IN_ATTRSET_SIZE_${str(length (attrNames attrset))}" "exit 1"; } diff --git a/examples/checks-utils/flake.nix b/examples/checks-utils/flake.nix index 4b16e1c..dbaa4f6 100644 --- a/examples/checks-utils/flake.nix +++ b/examples/checks-utils/flake.nix @@ -7,22 +7,23 @@ flake-utils.lib.eachDefaultSystem (system: let inherit (flake-utils.lib.check-utils system) isEqual hasKey; - - testDataset = { key1 = "value1"; key2 = "value2"; key3 = "value3"; }; + testDataset = { key1 = "value1"; key2 = 123; key3 = "some>value with^invalid&characters"; }; in rec { checks = { - valid_key1 = isEqual testDataset.key1 "value1"; - contains_key2 = hasKey testDataset "key2"; + # Successful cases + success_isEqual = isEqual testDataset.key1 "value1"; + success_hasKey = hasKey testDataset "key2"; - failing_valid_key1 = isEqual testDataset.key1 "failing-data"; - failing_contains_key2 = hasKey testDataset "failing-data"; + # Failing cases + failure_isEqual = isEqual testDataset.key1 "failing-data"; + failure_hasKey = hasKey testDataset "failing-data"; - number_formatting_isEqual = isEqual testDataset.key1 123; - number_formatting_hasKey = hasKey testDataset 123; + # Formatting + formatting_number = isEqual testDataset.key2 123; + formatting_null = isEqual null null; + formatting_invalid_chars = isEqual testDataset.key3 "some>value with^invalid&characters"; - null_formatting_key1 = isEqual testDataset.key1 null; - null_formatting_hasKey = hasKey testDataset null; }; } );