Skip to content

Commit b712d55

Browse files
Merge pull request #9096 from ThomasWaldmann/fix-9095-1.4
json: include archive keys in JSON lines when requested via --format, fixes #9095
2 parents 0f85500 + 0c27bd3 commit b712d55

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

src/borg/helpers/parseformat.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -798,13 +798,18 @@ def __init__(self, archive, format, *, json_lines=False):
798798
'archiveid': archive.fpr,
799799
}
800800
static_keys.update(self.FIXED_KEYS)
801+
self.format = partial_format(format, static_keys)
802+
self.format_keys = {f[1] for f in Formatter().parse(format)}
801803
if self.json_lines:
802804
self.item_data = {}
805+
# Include selected static archive-level keys when requested in format for JSON lines
806+
# This aligns JSON output with text output where these placeholders are available.
807+
for k in ('archivename', 'archiveid'):
808+
if k in self.format_keys:
809+
self.item_data[k] = static_keys[k]
803810
self.format_item = self.format_item_json
804811
else:
805812
self.item_data = static_keys
806-
self.format = partial_format(format, static_keys)
807-
self.format_keys = {f[1] for f in Formatter().parse(format)}
808813
self.call_keys = {
809814
'size': self.calculate_size,
810815
'csize': self.calculate_csize,

src/borg/testsuite/archiver.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2614,6 +2614,26 @@ def test_list_json(self):
26142614
assert file1['path'] == 'input/file1'
26152615
assert file1['sha256'] == 'b2915eb69f260d8d3c25249195f2c8f4f716ea82ec760ae929732c0262442b2b'
26162616

2617+
def test_list_json_lines_includes_archive_keys_in_format(self):
2618+
# Issue #9095: archivename/archiveid should be available in JSON lines when requested via --format
2619+
self.create_regular_file('file1', size=1024)
2620+
self.cmd('init', '--encryption=repokey', self.repository_location)
2621+
archive = self.repository_location + '::test'
2622+
self.cmd('create', archive, 'input')
2623+
info_archive = json.loads(self.cmd('info', '--json', archive))
2624+
assert len(info_archive['archives']) == 1
2625+
archive_info = info_archive['archives'][0]
2626+
expected_name = archive_info['name']
2627+
expected_id = archive_info['id']
2628+
# request both keys explicitly in format
2629+
out = self.cmd('list', '--json-lines', '--format={archivename} {archiveid}', archive)
2630+
rows = [json.loads(s) for s in out.splitlines() if s]
2631+
# ensure we have at least the directory and the file1 item, pick the last as a file
2632+
assert len(rows) >= 2
2633+
row = rows[-1]
2634+
assert row['archivename'] == expected_name
2635+
assert row['archiveid'] == expected_id
2636+
26172637
def test_list_json_args(self):
26182638
self.cmd('init', '--encryption=repokey', self.repository_location)
26192639
if self.FORK_DEFAULT:

0 commit comments

Comments
 (0)