Skip to content

Commit

Permalink
formats.hocon: add backwards compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
h7x4 committed Feb 9, 2024
1 parent 9ebcb6f commit 0e65eca
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 21 deletions.
82 changes: 61 additions & 21 deletions pkgs/pkgs-lib/formats/hocon/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -114,7 +154,7 @@ in

dontUnpack = true;

json = builtins.toJSON value;
json = builtins.toJSON finalValue;
passAsFile = [ "json" ];

strictDeps = true;
Expand Down
11 changes: 11 additions & 0 deletions pkgs/pkgs-lib/formats/hocon/src/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ enum HOCONValue {
List(Vec<HOCONValue>),
Substitution(String, bool),
Object(Vec<HOCONInclude>, Vec<(String, HOCONValue)>),
Literal(String),
}

#[derive(Debug)]
Expand Down Expand Up @@ -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',\
Expand Down Expand Up @@ -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(),
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
'';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"literal" = [
1,
"a",
]
"nested" = {
"literal" = [
1,
"a",
]
"substitution" = ${?PATH}
}
"nested_in_array" = [
${?PATH},
[
1,
"a",
]
]
"substitution" = ${?PATH}
}

11 changes: 11 additions & 0 deletions pkgs/pkgs-lib/formats/hocon/test/default.nix
Original file line number Diff line number Diff line change
@@ -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 { };
}

0 comments on commit 0e65eca

Please sign in to comment.