diff --git a/pkgs/pkgs-lib/formats/hocon/default.nix b/pkgs/pkgs-lib/formats/hocon/default.nix index d5b6308dea60..318ee0143320 100644 --- a/pkgs/pkgs-lib/formats/hocon/default.nix +++ b/pkgs/pkgs-lib/formats/hocon/default.nix @@ -35,26 +35,8 @@ in # In the case that you need this functionality, # you will have to disable pyhocon validation. , doCheck ? true - }: { - type = let - type' = with lib.types; let - atomType = nullOr (oneOf [ - bool - float - int - path - str - ]); - in (oneOf [ - atomType - (listOf atomType) - (attrsOf type') - ]) // { - description = "HOCON value"; - }; - in type'; - - lib = { + }: let + hoconLib = { mkInclude = value: let includeStatement = if lib.isAttrs value && !(lib.isDerivation value) then { required = false; @@ -101,7 +83,65 @@ in }; }; + in { + type = let + type' = with lib.types; let + atomType = nullOr (oneOf [ + bool + float + int + path + str + ]); + in (oneOf [ + atomType + (listOf atomType) + (attrsOf type') + ]) // { + description = "HOCON value"; + }; + in type'; + + lib = hoconLib; + generate = name: value: + let + # TODO: remove in 24.11 + # Backwards compatability for generators in the following locations: + # - nixos/modules/services/networking/jibri/default.nix (__hocon_envvar) + # - nixos/modules/services/networking/jicofo.nix (__hocon_envvar, __hocon_unquoted_string) + # - nixos/modules/services/networking/jitsi-videobridge.nix (__hocon_envvar) + replaceOldIndicators = value: + if lib.isAttrs value then + (if value ? "__hocon_envvar" + then + lib.warn '' + Use of `__hocon_envvar` has been deprecated, and will + be removed in the future. + + Please use `(pkgs.formats.hocon {}).lib.mkSubstitution` instead. + '' + (hoconLib.mkSubstitution value.__hocon_envvar) + else if value ? "__hocon_unquoted_string" + then + lib.warn '' + Use of `__hocon_unquoted_string` has been deprecated, and will + be removed in the future. + + Please make use of the freeform options of + `(pkgs.formats.hocon {}).format` instead. + '' + { + value = value.__hocon_unquoted_string; + _type = "unquoted_string"; + } + else lib.mapAttrs (_: replaceOldIndicators) value) + else if lib.isList value + then map replaceOldIndicators value + else value; + + finalValue = replaceOldIndicators value; + in callPackage ({ stdenvNoCC @@ -114,7 +154,7 @@ in dontUnpack = true; - json = builtins.toJSON value; + json = builtins.toJSON finalValue; passAsFile = [ "json" ]; strictDeps = true; diff --git a/pkgs/pkgs-lib/formats/hocon/src/src/main.rs b/pkgs/pkgs-lib/formats/hocon/src/src/main.rs index a564fc7dccdb..2e53f3fd5659 100644 --- a/pkgs/pkgs-lib/formats/hocon/src/src/main.rs +++ b/pkgs/pkgs-lib/formats/hocon/src/src/main.rs @@ -10,6 +10,7 @@ enum HOCONValue { List(Vec), Substitution(String, bool), Object(Vec, Vec<(String, HOCONValue)>), + Literal(String), } #[derive(Debug)] @@ -92,6 +93,15 @@ fn parse_special_types(o: &Map) -> Option { HOCONValue::Append(Box::new(json_to_hocon(value))) } + "unquoted_string" => { + let value = o + .get("value") + .expect("Missing value for unquoted_string") + .as_str() + .unwrap_or_else(|| panic!("Unquoted string value is not a string: {:?}", o)); + + HOCONValue::Literal(value.to_string()) + } _ => panic!( "\ Attribute set contained special element '_type',\ @@ -210,6 +220,7 @@ impl ToString for HOCONValue { format!("{{\n{}\n}}", content) } HOCONValue::Append(_) => panic!("Append should not be present at this point"), + Self::Literal(s) => s.to_string(), } } } diff --git a/pkgs/pkgs-lib/formats/hocon/test/backwards-compatibility/default.nix b/pkgs/pkgs-lib/formats/hocon/test/backwards-compatibility/default.nix new file mode 100644 index 000000000000..5f0b3d12a2d0 --- /dev/null +++ b/pkgs/pkgs-lib/formats/hocon/test/backwards-compatibility/default.nix @@ -0,0 +1,65 @@ +{ lib, formats, stdenvNoCC, writeText, ... }: +let + hocon = formats.hocon { }; + + expression = { + substitution = { __hocon_envvar = "PATH"; }; + literal = { + __hocon_unquoted_string = '' + [ + 1, + "a", + ]''; + }; + + nested = { + substitution = { __hocon_envvar = "PATH"; }; + literal = { + __hocon_unquoted_string = '' + [ + 1, + "a", + ]''; + }; + }; + + nested_in_array = [ + { __hocon_envvar = "PATH"; } + { + __hocon_unquoted_string = '' + [ + 1, + "a", + ]''; + } + ]; + }; + + hocon-test-conf = hocon.generate "hocon-test.conf" expression; +in + stdenvNoCC.mkDerivation { + name = "pkgs.formats.hocon-test-backwards-compatibility"; + + dontUnpack = true; + dontBuild = true; + + doCheck = true; + checkPhase = '' + runHook preCheck + + diff -U3 ${./expected.txt} ${hocon-test-conf} + + runHook postCheck + ''; + + installPhase = '' + runHook preInstall + + mkdir $out + cp ${./expected.txt} $out/expected.txt + cp ${hocon-test-conf} $out/hocon-test.conf + cp ${hocon-test-conf.passthru.json} $out/hocon-test.json + + runHook postInstall + ''; + } diff --git a/pkgs/pkgs-lib/formats/hocon/test/backwards-compatibility/expected.txt b/pkgs/pkgs-lib/formats/hocon/test/backwards-compatibility/expected.txt new file mode 100644 index 000000000000..2835a3c6ca39 --- /dev/null +++ b/pkgs/pkgs-lib/formats/hocon/test/backwards-compatibility/expected.txt @@ -0,0 +1,22 @@ +{ + "literal" = [ + 1, + "a", + ] + "nested" = { + "literal" = [ + 1, + "a", + ] + "substitution" = ${?PATH} + } + "nested_in_array" = [ + ${?PATH}, + [ + 1, + "a", + ] + ] + "substitution" = ${?PATH} +} + diff --git a/pkgs/pkgs-lib/formats/hocon/test/default.nix b/pkgs/pkgs-lib/formats/hocon/test/default.nix index 6cd03fe4854f..19928703b95e 100644 --- a/pkgs/pkgs-lib/formats/hocon/test/default.nix +++ b/pkgs/pkgs-lib/formats/hocon/test/default.nix @@ -1,4 +1,15 @@ { pkgs, ... }: { comprehensive = pkgs.callPackage ./comprehensive { }; + backwards-compatibility = + let + pkgsNoWarn = pkgs.extend (final: prev: { + lib = prev.lib.extend (libFinal: libPrev: { + warn = msg: v: v; + trivial = libPrev.trivial // { + warn = msg: v: v; + }; + }); + }); + in pkgsNoWarn.callPackage ./backwards-compatibility { }; }