Repository: borgbackup/borg

Issue:
borg list --format: improve docs, extend placeholders
<!--
Thank you for reporting an issue.

*IMPORTANT* -  *before* creating a new issue please look around:
 - Borgbackup documentation: http://borgbackup.readthedocs.io/en/stable/index.html
 - FAQ: https://borgbackup.readthedocs.io/en/stable/faq.html
 and
 - open issues in Github tracker: https://github.com/borgbackup/borg/issues
  
If you cannot find a similar problem, then create a new issue.

Please fill in as much of the template as possible.
-->

## Have you checked borgbackup docs, FAQ, and open Github issues?

Yes

## Is this a BUG / ISSUE report or a QUESTION?

ISSUE

## System information. For client/server mode post info for both machines.

borg version 1.1.17

## Describe the problem you're observing.

The format for `borg-list --format` is barely documented:
There are keys, and from the example I can see that adding `:N` will right-pad the key to length `N`. But what about trimming or left-padding or...? Currently I can't even know what is supported.

Furthermore, the default given applies only to file listings. The default for repo listing should be given as well, which might prevent confusion such as in #3399.

Finally, I would like some extra keys for repo listing:
- size of the archive files (compress/uncompressed) - ignore deduplication for this
- number of files in the archive

<!--

If this complaint relates to borg performance, please include CRUD benchmark
results and any steps you took to troubleshoot.
How to run benchmark: http://borgbackup.readthedocs.io/en/stable/usage/benchmark.html

*IMPORTANT* - Please mark logs and text output from terminal commands 
or else Github will not display them correctly. 
An example is provided below.

Example:
```
this is an example how log text should be marked (wrap it with ```)
```
-->



Discussion:
Docs: https://borgbackup.readthedocs.io/en/stable/usage/list.html

Default: as there is only one borg list command that covers repos as well as archives, the help string in the argparser needs to mention both defaults.

Default formats (1.1-maint and master):
```
archive: "{mode} {user:6} {group:6} {size:8} {mtime} {path}{extra}{NL}"
repo: "{archive:<36} {time} [{id}]{NL}"
```

Formatting options / syntax: guess this is standard python f-string formatting.

Additional keys for repo listing:
- 1.1-maint: not available, neither from manifest nor from archive metadata
- master has size, csize, nfiles, size_parts, csize_parts, nfiles_parts potentially available in archive metadata
Working on this needs 2 PRs:
- one for the help string and docs fix, needed for master and later as backport for 1.1-maint
- one for adding placeholders for master only
Hey,
can i take up this issue?
@kaushik853 sure! in general, all open issue can be taken.
This is my cli workaround for displaying archives with their size in the meantime, but it is abysmally slow :/
```sh
sizesum() {
    borg list ::$1 "--format={${2}size}{NL}" |
		paste -s -d'+' | bc | numfmt --to=iec
}
sizes() {
    p=$1
    echo $p: all $(sizesum $p) compressed $(sizesum $p "c") deduplicated $(sizesum $p "dc")
}
borg list --format="{name}{NL}" |
	while read p
	do sizes $p
	done
```

Resolving patch:
diff --git a/src/borg/archiver.py b/src/borg/archiver.py
--- a/src/borg/archiver.py
+++ b/src/borg/archiver.py
@@ -4223,16 +4223,45 @@ def define_borg_mount(parser):
 
         .. man NOTES
 
-        The following keys are available for ``--format``:
+        The FORMAT specifier syntax
+        +++++++++++++++++++++++++++
+
+        The ``--format`` option uses python's `format string syntax
+        <https://docs.python.org/3.8/library/string.html#formatstrings>`_.
+
+        Examples:
+        ::
+
+            $ borg list --format '{archive}{NL}' /path/to/repo
+            ArchiveFoo
+            ArchiveBar
+            ...
+
+            # {VAR:NUMBER} - pad to NUMBER columns.
+            # Strings are left-aligned, numbers are right-aligned.
+            # Note: time columns except ``isomtime``, ``isoctime`` and ``isoatime`` cannot be padded.
+            $ borg list --format '{archive:36} {time} [{id}]{NL}' /path/to/repo
+            ArchiveFoo                           Thu, 2021-12-09 10:22:28 [0b8e9a312bef3f2f6e2d0fc110c196827786c15eba0188738e81697a7fa3b274]
+            $ borg list --format '{mode} {user:6} {group:6} {size:8} {mtime} {path}{extra}{NL}' /path/to/repo::ArchiveFoo
+            -rw-rw-r-- user   user       1024 Thu, 2021-12-09 10:22:17 file-foo
+            ...
+
+            # {VAR:<NUMBER} - pad to NUMBER columns left-aligned.
+            # {VAR:>NUMBER} - pad to NUMBER columns right-aligned.
+            $ borg list --format '{mode} {user:>6} {group:>6} {size:<8} {mtime} {path}{extra}{NL}' /path/to/repo::ArchiveFoo
+            -rw-rw-r--   user   user 1024     Thu, 2021-12-09 10:22:17 file-foo
+            ...
+
+        The following keys are always available:
 
 
         """) + BaseFormatter.keys_help() + textwrap.dedent("""
 
-        Keys for listing repository archives:
+        Keys available only when listing archives in a repository:
 
         """) + ArchiveFormatter.keys_help() + textwrap.dedent("""
 
-        Keys for listing archive files:
+        Keys available only when listing files in an archive:
 
         """) + ItemFormatter.keys_help()
         subparser = subparsers.add_parser('list', parents=[common_parser], add_help=False,
@@ -4246,8 +4275,9 @@ def define_borg_mount(parser):
         subparser.add_argument('--short', dest='short', action='store_true',
                                help='only print file/directory names, nothing else')
         subparser.add_argument('--format', metavar='FORMAT', dest='format',
-                               help='specify format for file listing '
-                                    '(default: "{mode} {user:6} {group:6} {size:8d} {mtime} {path}{extra}{NL}")')
+                               help='specify format for file or archive listing '
+                                    '(default for files: "{mode} {user:6} {group:6} {size:8} {mtime} {path}{extra}{NL}"; '
+                                    'for archives: "{archive:<36} {time} [{id}]{NL}")')
         subparser.add_argument('--json', action='store_true',
                                help='Only valid for listing repository contents. Format output as JSON. '
                                     'The form of ``--format`` is ignored, '
diff --git a/src/borg/helpers/parseformat.py b/src/borg/helpers/parseformat.py
--- a/src/borg/helpers/parseformat.py
+++ b/src/borg/helpers/parseformat.py
@@ -549,7 +549,7 @@ def format_item(self, item):
     def keys_help():
         return "- NEWLINE: OS dependent line separator\n" \
                "- NL: alias of NEWLINE\n" \
-               "- NUL: NUL character for creating print0 / xargs -0 like output, see barchive/bpath\n" \
+               "- NUL: NUL character for creating print0 / xargs -0 like output, see barchive and bpath keys below\n" \
                "- SPACE\n" \
                "- TAB\n" \
                "- CR\n" \


Test patch: