Browse Source

Merge pull request #9107 from ThomasWaldmann/port-9096-to-master

json: include archive keys in JSON lines when requested via --format, fixes #9095
TW 1 week ago
parent
commit
50b50e4ba4
2 changed files with 32 additions and 0 deletions
  1. 9 0
      src/borg/helpers/parseformat.py
  2. 23 0
      src/borg/testsuite/archiver/list_cmd_test.py

+ 9 - 0
src/borg/helpers/parseformat.py

@@ -898,6 +898,7 @@ class ItemFormatter(BaseFormatter):
         super().__init__(format, static_data)
         super().__init__(format, static_data)
         self.xxh64 = StreamingXXH64
         self.xxh64 = StreamingXXH64
         self.archive = archive
         self.archive = archive
+        # track which keys were requested in the format string
         self.format_keys = {f[1] for f in Formatter().parse(format)}
         self.format_keys = {f[1] for f in Formatter().parse(format)}
         self.call_keys = {
         self.call_keys = {
             "size": self.calculate_size,
             "size": self.calculate_size,
@@ -942,6 +943,14 @@ class ItemFormatter(BaseFormatter):
         item_data["inode"] = item.get("inode")
         item_data["inode"] = item.get("inode")
         for key in self.used_call_keys:
         for key in self.used_call_keys:
             item_data[key] = self.call_keys[key](item)
             item_data[key] = self.call_keys[key](item)
+        # When producing JSON lines, include selected static archive-level keys if they were
+        # requested via --format. This mirrors text output behavior and fixes #9095.
+        if jsonline:
+            # Include selected static archive-level keys when requested via --format.
+            # Keep implementation style aligned with 1.4-maint.
+            for k in ("archivename", "archiveid"):
+                if k in self.format_keys:
+                    item_data[k] = self.static_data[k]
         return item_data
         return item_data
 
 
     def calculate_num_chunks(self, item):
     def calculate_num_chunks(self, item):

+ 23 - 0
src/borg/testsuite/archiver/list_cmd_test.py

@@ -79,6 +79,29 @@ def test_list_json(archivers, request):
     assert file1["sha256"] == "b2915eb69f260d8d3c25249195f2c8f4f716ea82ec760ae929732c0262442b2b"
     assert file1["sha256"] == "b2915eb69f260d8d3c25249195f2c8f4f716ea82ec760ae929732c0262442b2b"
 
 
 
 
+def test_list_json_lines_includes_archive_keys_in_format(archivers, request):
+    # Issue #9095 / PR #9096: archivename/archiveid should be available in JSON lines when
+    # requested via --format.
+    archiver = request.getfixturevalue(archivers)
+    create_regular_file(archiver.input_path, "file1", size=1024)
+    cmd(archiver, "repo-create", RK_ENCRYPTION)
+    cmd(archiver, "create", "test", "input")
+
+    # Query archive info to obtain expected name and id
+    info_archive = json.loads(cmd(archiver, "info", "--json", "-a", "test"))
+    assert len(info_archive["archives"]) == 1
+    archive_info = info_archive["archives"][0]
+    expected_name = archive_info["name"]
+    expected_id = archive_info["id"]
+
+    out = cmd(archiver, "list", "test", "--json-lines", "--format={archivename} {archiveid}")
+    rows = [json.loads(s) for s in out.splitlines() if s]
+    assert len(rows) >= 2  # directory + file
+    row = rows[-1]
+    assert row["archivename"] == expected_name
+    assert row["archiveid"] == expected_id
+
+
 def test_list_depth(archivers, request):
 def test_list_depth(archivers, request):
     """Test the --depth option for the list command."""
     """Test the --depth option for the list command."""
     archiver = request.getfixturevalue(archivers)
     archiver = request.getfixturevalue(archivers)