1{
2 lib,
3 pkgs,
4}:
5let
6 inherit (pkgs) buildPackages callPackage;
7
8 hocon-generator = buildPackages.rustPlatform.buildRustPackage {
9 name = "hocon-generator";
10 version = "0.1.0";
11 src = ./src;
12
13 passthru.updateScript = ./update.sh;
14
15 cargoLock.lockFile = ./src/Cargo.lock;
16 };
17
18 hocon-validator =
19 pkgs.writers.writePython3Bin "hocon-validator"
20 {
21 libraries = [ pkgs.python3Packages.pyhocon ];
22 }
23 ''
24 from sys import argv
25 from pyhocon import ConfigFactory
26
27 if not len(argv) == 2:
28 print("USAGE: hocon-validator <file>")
29
30 ConfigFactory.parse_file(argv[1])
31 '';
32in
33{
34 format =
35 {
36 generator ? hocon-generator,
37 validator ? hocon-validator,
38 doCheck ? true,
39 }:
40 let
41 hoconLib = {
42 mkInclude =
43 value:
44 let
45 includeStatement =
46 if lib.isAttrs value && !(lib.isDerivation value) then
47 {
48 required = false;
49 type = null;
50 _type = "include";
51 }
52 // value
53 else
54 {
55 value = toString value;
56 required = false;
57 type = null;
58 _type = "include";
59 };
60 in
61 assert lib.assertMsg
62 (lib.elem includeStatement.type [
63 "file"
64 "url"
65 "classpath"
66 null
67 ])
68 ''
69 Type of HOCON mkInclude is not of type 'file', 'url' or 'classpath':
70 ${(lib.generators.toPretty { }) includeStatement}
71 '';
72 includeStatement;
73
74 mkAppend = value: {
75 inherit value;
76 _type = "append";
77 };
78
79 mkSubstitution =
80 value:
81 if lib.isString value then
82 {
83 inherit value;
84 optional = false;
85 _type = "substitution";
86 }
87 else
88 assert lib.assertMsg (lib.isAttrs value) ''
89 Value of invalid type provided to `hocon.lib.mkSubstitution`: ${lib.typeOf value}
90 '';
91 assert lib.assertMsg (value ? "value") ''
92 Argument to `hocon.lib.mkSubstitution` is missing a `value`:
93 ${builtins.toJSON value}
94 '';
95 {
96 value = value.value;
97 optional = value.optional or false;
98 _type = "substitution";
99 };
100 };
101
102 in
103 {
104 type =
105 let
106 type' =
107 with lib.types;
108 let
109 atomType = nullOr (oneOf [
110 bool
111 float
112 int
113 path
114 str
115 ]);
116
117 includeType = addCheck attrs (x: (x._type or null) == "include");
118 in
119 (oneOf [
120 atomType
121 (addCheck (listOf atomType) (lib.all atomType.check))
122 (addCheck (listOf includeType) (lib.all includeType.check))
123 (attrsOf type')
124 ])
125 // {
126 description = "HOCON value";
127 };
128 in
129 type';
130
131 lib = hoconLib;
132
133 generate =
134 name: value:
135 callPackage
136 (
137 {
138 stdenvNoCC,
139 hocon-generator,
140 hocon-validator,
141 writeText,
142 }:
143 stdenvNoCC.mkDerivation rec {
144 inherit name;
145
146 dontUnpack = true;
147 preferLocalBuild = true;
148
149 json = builtins.toJSON value;
150 passAsFile = [ "json" ];
151
152 strictDeps = true;
153 nativeBuildInputs = [ hocon-generator ];
154 buildPhase = ''
155 runHook preBuild
156 hocon-generator < $jsonPath > output.conf
157 runHook postBuild
158 '';
159
160 inherit doCheck;
161 nativeCheckInputs = [ hocon-validator ];
162 checkPhase = ''
163 runHook preCheck
164 hocon-validator output.conf
165 runHook postCheck
166 '';
167
168 installPhase = ''
169 runHook preInstall
170 mv output.conf $out
171 runHook postInstall
172 '';
173
174 passthru.json = writeText "${name}.json" json;
175 }
176 )
177 {
178 hocon-generator = generator;
179 hocon-validator = validator;
180 };
181 };
182}