formats.hocon: add backwards compatibility

This commit is contained in:
h7x4 2024-01-24 05:12:30 +01:00
parent 9ebcb6f5db
commit 0e65eca7c6
No known key found for this signature in database
GPG key ID: 9F2F7D8250F35146
5 changed files with 170 additions and 21 deletions

View file

@ -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;

View file

@ -10,6 +10,7 @@ enum HOCONValue {
List(Vec<HOCONValue>),
Substitution(String, bool),
Object(Vec<HOCONInclude>, Vec<(String, HOCONValue)>),
Literal(String),
}
#[derive(Debug)]
@ -92,6 +93,15 @@ fn parse_special_types(o: &Map<String, Value>) -> Option<HOCONValue> {
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(),
}
}
}

View file

@ -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
'';
}

View file

@ -0,0 +1,22 @@
{
"literal" = [
1,
"a",
]
"nested" = {
"literal" = [
1,
"a",
]
"substitution" = ${?PATH}
}
"nested_in_array" = [
${?PATH},
[
1,
"a",
]
]
"substitution" = ${?PATH}
}

View file

@ -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 { };
}