Skip to content

Commit 894ca27

Browse files
committed
Fix YAML EOL whitespace & make list indent optional
1 parent b954cdf commit 894ca27

8 files changed

+320
-83
lines changed

stdlib/std.jsonnet

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -921,8 +921,8 @@ limitations under the License.
921921
std.join('', lines);
922922
aux(value, [], ''),
923923

924-
manifestYamlDoc(value)::
925-
local aux(v, in_array, in_object, path, cindent) =
924+
manifestYamlDoc(value, indent_array_in_object=false)::
925+
local aux(v, path, cindent) =
926926
if v == true then
927927
'true'
928928
else if v == false then
@@ -937,7 +937,7 @@ limitations under the License.
937937
'""'
938938
else if v[len - 1] == '\n' then
939939
local split = std.split(v, '\n');
940-
std.join('\n' + cindent, ['|'] + split[0:std.length(split) - 1])
940+
std.join('\n' + cindent + ' ', ['|'] + split[0:std.length(split) - 1])
941941
else
942942
std.escapeStringJson(v)
943943
else if std.type(v) == 'function' then
@@ -946,44 +946,71 @@ limitations under the License.
946946
if std.length(v) == 0 then
947947
'[]'
948948
else
949+
local params(value) =
950+
if std.isArray(value) && std.length(value) > 0 then {
951+
// While we could avoid the new line, it yields YAML that is
952+
// hard to read, e.g.:
953+
// - - - 1
954+
// - 2
955+
// - - 3
956+
// - 4
957+
new_indent: cindent + ' ',
958+
space: '\n' + self.new_indent,
959+
} else if std.isObject(value) && std.length(value) > 0 then {
960+
new_indent: cindent + ' ',
961+
// In this case we can start on the same line as the - because the indentation
962+
// matches up then. The converse is not true, because fields are not always
963+
// 1 character long.
964+
space: ' ',
965+
} else {
966+
// In this case, new_indent is only used in the case of multi-line strings.
967+
new_indent: cindent,
968+
space: ' ',
969+
};
949970
local range = std.range(0, std.length(v) - 1);
950-
// If we're in object than drop the indent we would usually have. This allows e.g.
951-
// ports:
952-
// - 80
953-
// instead of
954-
// ports:
955-
// - 80
956-
local actual_indent = if in_object then cindent[2:] else cindent;
957-
local new_indent = actual_indent + ' ';
958-
local parts = [aux(v[i], true, false, path + [i], new_indent) for i in range];
959-
// While we could avoid the new line in the case of in_array, it yields YAML that is
960-
// hard to read, e.g.:
961-
// - - - 1
962-
// - 2
963-
// - - 3
964-
// - 4
965-
(if in_array || in_object then '\n' + actual_indent else '')
966-
+ '- ' + std.join('\n' + actual_indent + '- ', parts)
971+
local parts = [
972+
'-' + param.space + aux(v[i], path + [i], param.new_indent)
973+
for i in range
974+
for param in [params(v[i])]
975+
];
976+
std.join('\n' + cindent, parts)
967977
else if std.type(v) == 'object' then
968978
if std.length(v) == 0 then
969979
'{}'
970980
else
971-
local new_indent = cindent + ' ';
981+
local params(value) =
982+
if std.isArray(value) && std.length(value) > 0 then {
983+
// Not indenting allows e.g.
984+
// ports:
985+
// - 80
986+
// instead of
987+
// ports:
988+
// - 80
989+
new_indent: if indent_array_in_object then cindent + ' ' else cindent,
990+
space: '\n' + self.new_indent,
991+
} else if std.isObject(value) && std.length(value) > 0 then {
992+
new_indent: cindent + ' ',
993+
space: '\n' + self.new_indent,
994+
} else {
995+
// In this case, new_indent is only used in the case of multi-line strings.
996+
new_indent: cindent,
997+
space: ' ',
998+
};
972999
local lines = [
973-
std.escapeStringJson(k) + ': ' + aux(v[k], false, true, path + [k], new_indent)
1000+
std.escapeStringJson(k) + ':' + param.space + aux(v[k], path + [k], param.new_indent)
9741001
for k in std.objectFields(v)
1002+
for param in [params(v[k])]
9751003
];
976-
// If we're in an array, we can start on the same line as the - because the indentation
977-
// matches up then. The converse is not true, because fields are not always
978-
// 1 character long.
979-
(if in_object then '\n' + cindent else '') + std.join('\n' + cindent, lines);
980-
aux(value, false, false, [], ''),
1004+
std.join('\n' + cindent, lines);
1005+
aux(value, [], ''),
9811006

982-
manifestYamlStream(value)::
1007+
manifestYamlStream(value, indent_array_in_object=false)::
9831008
if std.type(value) != 'array' then
9841009
error 'manifestYamlStream only takes arrays, got ' + std.type(value)
9851010
else
986-
'---\n' + std.join('\n---\n', [std.manifestYamlDoc(e) for e in value]) + '\n...\n',
1011+
'---\n' + std.join(
1012+
'\n---\n', [std.manifestYamlDoc(e, indent_array_in_object) for e in value]
1013+
) + '\n...\n',
9871014

9881015

9891016
manifestPython(o)::
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
RUNTIME ERROR: cannot test equality of functions
2-
std.jsonnet:1239:9-34 function <anonymous>
2+
std.jsonnet:1266:9-34 function <anonymous>
33
error.equality_function.jsonnet:17:1-33
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
RUNTIME ERROR: foobar
22
error.inside_equals_array.jsonnet:18:18-32 thunk <array_element>
3-
std.jsonnet:1219:29-33 thunk <b>
4-
std.jsonnet:1219:21-33 function <anonymous>
5-
std.jsonnet:1219:21-33 function <aux>
6-
std.jsonnet:1222:15-31 function <anonymous>
7-
std.jsonnet:1223:11-23
3+
std.jsonnet:1246:29-33 thunk <b>
4+
std.jsonnet:1246:21-33 function <anonymous>
5+
std.jsonnet:1246:21-33 function <aux>
6+
std.jsonnet:1249:15-31 function <anonymous>
7+
std.jsonnet:1250:11-23
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
RUNTIME ERROR: foobar
22
error.inside_equals_object.jsonnet:18:22-36 object <b>
3-
std.jsonnet:1233:50-54 thunk <b>
4-
std.jsonnet:1233:42-54 function <anonymous>
5-
std.jsonnet:1233:42-54 function <aux>
6-
std.jsonnet:1236:15-31 function <anonymous>
7-
std.jsonnet:1237:11-23
3+
std.jsonnet:1260:50-54 thunk <b>
4+
std.jsonnet:1260:42-54 function <anonymous>
5+
std.jsonnet:1260:42-54 function <aux>
6+
std.jsonnet:1263:15-31 function <anonymous>
7+
std.jsonnet:1264:11-23
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
RUNTIME ERROR: Object assertion failed.
22
error.invariant.equality.jsonnet:17:10-15 thunk <object_assert>
3-
std.jsonnet:1233:42-46 thunk <a>
4-
std.jsonnet:1233:42-54 function <anonymous>
5-
std.jsonnet:1233:42-54 function <anonymous>
6-
std.jsonnet:1237:11-23
3+
std.jsonnet:1260:42-46 thunk <a>
4+
std.jsonnet:1260:42-54 function <anonymous>
5+
std.jsonnet:1260:42-54 function <anonymous>
6+
std.jsonnet:1264:11-23
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
RUNTIME ERROR: Object assertion failed.
22
error.obj_assert.fail1.jsonnet:20:23-29 thunk <object_assert>
3-
std.jsonnet:1233:42-46 thunk <a>
4-
std.jsonnet:1233:42-54 function <anonymous>
5-
std.jsonnet:1233:42-54 function <anonymous>
6-
std.jsonnet:1237:11-23
3+
std.jsonnet:1260:42-46 thunk <a>
4+
std.jsonnet:1260:42-54 function <anonymous>
5+
std.jsonnet:1260:42-54 function <anonymous>
6+
std.jsonnet:1264:11-23
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
RUNTIME ERROR: foo was not equal to bar
22
error.obj_assert.fail2.jsonnet:20:32-65 thunk <object_assert>
3-
std.jsonnet:1233:42-46 thunk <a>
4-
std.jsonnet:1233:42-54 function <anonymous>
5-
std.jsonnet:1233:42-54 function <anonymous>
6-
std.jsonnet:1237:11-23
3+
std.jsonnet:1260:42-46 thunk <a>
4+
std.jsonnet:1260:42-54 function <anonymous>
5+
std.jsonnet:1260:42-54 function <anonymous>
6+
std.jsonnet:1264:11-23

0 commit comments

Comments
 (0)