Skip to content

Commit

Permalink
Add option to disable header in list output of CVEs/users
Browse files Browse the repository at this point in the history
  • Loading branch information
mprpic committed Nov 22, 2022
1 parent af553ea commit 9655514
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 9 deletions.
30 changes: 21 additions & 9 deletions cvelib/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def print_cve_record(cve: dict) -> None:
click.echo(f"└─ Reserved on:\t{human_ts(cve['cveMetadata']['dateReserved'])}")


def print_table(lines: Sequence[Sequence[str]]) -> None:
def print_table(lines: Sequence[Sequence[str]], highlight_header: bool = True) -> None:
"""Print tabulated data based on the widths of the longest values in each column."""
col_widths = []
for item_index in range(len(lines[0])):
Expand All @@ -70,7 +70,7 @@ def print_table(lines: Sequence[Sequence[str]]) -> None:

for idx, line in enumerate(lines):
text = "".join(f"{value:<{width + 3}}" for value, width in zip(line, col_widths)).strip()
if idx == 0:
if idx == 0 and highlight_header:
click.secho(text, bold=True)
else:
click.echo(text)
Expand Down Expand Up @@ -575,6 +575,9 @@ def show_cve(ctx: click.Context, show_record: bool, print_raw: bool, cve_id: str

@cli.command(name="list")
@click.option("--raw", "print_raw", default=False, is_flag=True, help="Print response JSON.")
@click.option(
"-N", "--no-header", default=False, is_flag=True, help="Do not print header in table output."
)
@click.option(
"--sort-by",
type=click.Choice(["cve_id", "state", "user", "reserved_ts"], case_sensitive=False),
Expand All @@ -595,7 +598,9 @@ def show_cve(ctx: click.Context, show_record: bool, print_raw: bool, cve_id: str
)
@click.pass_context
@handle_cve_api_error
def list_cves(ctx: click.Context, print_raw: bool, sort_by: str, **query: dict) -> None:
def list_cves(
ctx: click.Context, print_raw: bool, no_header: bool, sort_by: str, **query: dict
) -> None:
"""Filter and list reserved CVE IDs owned by your CNA."""
cve_api = ctx.obj.cve_api
cves = list(cve_api.list_cves(**query))
Expand All @@ -618,7 +623,10 @@ def list_cves(ctx: click.Context, print_raw: bool, sort_by: str, **query: dict)
elif key == "state":
cves.sort(key=lambda x: x["state"])

lines = [("CVE ID", "STATE", "OWNING CNA", "RESERVED BY", "RESERVED ON")]
if no_header:
lines = []
else:
lines = [("CVE ID", "STATE", "OWNING CNA", "RESERVED BY", "RESERVED ON")]
for cve in cves:
lines.append(
(
Expand All @@ -629,7 +637,7 @@ def list_cves(ctx: click.Context, print_raw: bool, sort_by: str, **query: dict)
human_ts(cve["reserved"]),
)
)
print_table(lines)
print_table(lines, highlight_header=not no_header)


@cli.command()
Expand Down Expand Up @@ -858,9 +866,12 @@ def show_org(ctx: click.Context, print_raw: bool) -> None:

@show_org.command()
@click.option("--raw", "print_raw", default=False, is_flag=True, help="Print response JSON.")
@click.option(
"-N", "--no-header", default=False, is_flag=True, help="Do not print header in table output."
)
@click.pass_context
@handle_cve_api_error
def users(ctx: click.Context, print_raw: bool) -> None:
def users(ctx: click.Context, print_raw: bool, no_header: bool) -> None:
"""List all users in your organization."""
cve_api = ctx.obj.cve_api
org_users = list(cve_api.list_users())
Expand All @@ -881,9 +892,10 @@ def users(ctx: click.Context, print_raw: bool) -> None:
)
)
lines.sort(key=lambda x: x[0]) # Sort by username
# Add header after sorting
lines.insert(0, ("USERNAME", "NAME", "ROLES", "ACTIVE", "CREATED", "MODIFIED"))
print_table(lines)
if not no_header:
# Add header after sorting
lines.insert(0, ("USERNAME", "NAME", "ROLES", "ACTIVE", "CREATED", "MODIFIED"))
print_table(lines, highlight_header=not no_header)


@cli.command()
Expand Down
7 changes: 7 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ def test_cve_list():
"CVE-2021-3002 PUBLISHED acme ann (acme) Thu Jan 14 18:32:57 2021\n"
"CVE-2021-3003 REJECTED acme eve (corp) Thu Jan 14 18:34:50 2021\n"
)
result = runner.invoke(cli, DEFAULT_OPTS + ["list", "--no-header"])
assert result.exit_code == 0, result.output
assert result.output == (
"CVE-2021-3001 RESERVED acme bob (acme) Thu Jan 14 18:32:19 2021\n"
"CVE-2021-3002 PUBLISHED acme ann (acme) Thu Jan 14 18:32:57 2021\n"
"CVE-2021-3003 REJECTED acme eve (corp) Thu Jan 14 18:34:50 2021\n"
)


class TestCvePublish:
Expand Down

0 comments on commit 9655514

Please sign in to comment.