Repository: certbot/certbot

Issue:
`certbot certificates --cert-name` outputs many empty lines from non-selected certificates
## My operating system is (include version):
Gentoo

## I installed Certbot with (certbot-auto, OS package manager, pip, etc):
OS package manager of course, because Gentoo.

## I ran this command and it produced this output:
```
server ~ # certbot certificates --cert-name le-test-02.example.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following matching certs:














  Certificate Name:   le-test-02.example.com
    Serial Number:    6d058346fc54620a
    Key Type:         RSA
    Domains:          le-test-02.example.com
    Expiry Date:      2026-03-21 10:17:39+00:00 (VALID: 1825 days)
    Certificate Path: /etc/letsencrypt/live/le-test-02.example.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/le-test-02.example.com/privkey.pem


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
server ~ # 
```

Please appreciate the total amount of empty lines between the `----` lines in combination with:

```
server ~ # certbot certificates | grep Certificate\ Name | wc -l
Saving debug log to /var/log/letsencrypt/letsencrypt.log
17
server ~ # 
```

## Certbot's behavior differed from what I expected because:
I'd expect the following:

```
server ~ # certbot certificates --cert-name le-test-02.example.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following matching certs:
  Certificate Name:   le-test-02.example.com
    Serial Number:    6d058346fc54620a
    Key Type:         RSA
    Domains:          le-test-02.example.com
    Expiry Date:      2026-03-21 10:17:39+00:00 (VALID: 1825 days)
    Certificate Path: /etc/letsencrypt/live/le-test-02.example.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/le-test-02.example.com/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
server ~ # 
```

Clean output without all the extra empty lines.


Discussion:
If a certificate shouldn't be outputted, `human_readable_cert_info()` returns an empty string:

https://github.com/certbot/certbot/blob/40ae5d939ee0449ce54b8bf12e75e9311e361d91/certbot/certbot/_internal/cert_manager.py#L268-L271

Issue comes from the fact every output from `human_readable_cert_info()` is appended, *even* if it's empty:

https://github.com/certbot/certbot/blob/40ae5d939ee0449ce54b8bf12e75e9311e361d91/certbot/certbot/_internal/cert_manager.py#L357-L362

Resulting in a bunch of empty lines.

Resolving patch:
diff --git a/certbot/certbot/_internal/cert_manager.py b/certbot/certbot/_internal/cert_manager.py
--- a/certbot/certbot/_internal/cert_manager.py
+++ b/certbot/certbot/_internal/cert_manager.py
@@ -266,9 +266,9 @@ def human_readable_cert_info(config, cert, skip_filter_checks=False):
     checker = ocsp.RevocationChecker()
 
     if config.certname and cert.lineagename != config.certname and not skip_filter_checks:
-        return ""
+        return None
     if config.domains and not set(config.domains).issubset(cert.names()):
-        return ""
+        return None
     now = pytz.UTC.fromutc(datetime.datetime.utcnow())
 
     reasons = []
@@ -358,7 +358,9 @@ def _report_human_readable(config, parsed_certs):
     """Format a results report for a parsed cert"""
     certinfo = []
     for cert in parsed_certs:
-        certinfo.append(human_readable_cert_info(config, cert))
+        cert_info = human_readable_cert_info(config, cert)
+        if cert_info is not None:
+            certinfo.append(cert_info)
     return "\n".join(certinfo)
 
 


Test patch: