Skip to content

Commit 98bf60c

Browse files
committed
feat(cli): Implement dda info go tags command
1 parent a8046c8 commit 98bf60c

File tree

1 file changed

+53
-7
lines changed

1 file changed

+53
-7
lines changed

src/dda/cli/info/go/tags/__init__.py

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,67 @@
77

88
import click
99

10-
from dda.cli.base import dynamic_command
10+
from dda.cli.base import dynamic_command, pass_app
11+
from dda.utils.fs import Path
1112

1213
if TYPE_CHECKING:
13-
from dda.utils.fs import Path
14+
from dda.cli.application import Application
1415

1516

1617
@dynamic_command(
1718
short_help="Query the list of Go build tags existing in the repository.",
1819
)
1920
@click.option(
20-
"repo",
21+
"--repo",
2122
"-r",
22-
type=click.Path(exists=True, file_okay=False, dir_okay=True, resolve_path=True),
23-
help="The repository to use.",
23+
type=click.Path(exists=True, file_okay=False, dir_okay=True, resolve_path=True, path_type=Path),
24+
default=Path.cwd(),
25+
# NOTE: Should we default to the root of the currently-open git repository?
26+
help="The repository path to use. Defaults to the current working directory.",
2427
)
2528
@click.option("--json", "-j", is_flag=True, help="Format the output as JSON.")
26-
def cmd(repo: Path, *, json: bool) -> None:
27-
pass
29+
@click.option("--map", "-m", is_flag=True, help="Map the tags to the paths where they are used.")
30+
@click.option(
31+
"--exclude",
32+
"-e",
33+
multiple=True,
34+
help="Exclude files or directories from the search using a regular expression. Can be specified multiple times.",
35+
)
36+
@pass_app
37+
def cmd(app: Application, *, repo: Path, json: bool, map: bool, exclude: list[str]) -> None: # noqa: A002
38+
import re
39+
40+
from dda.build.go.tags.search import search_build_tags
41+
42+
result_raw = search_build_tags(repo, exclude_patterns=[re.compile(pattern) for pattern in exclude])
43+
44+
# Need to convert the set[Path] to a list[str] to be able to serialize to JSON
45+
# Sort the inner list elements alphabetically for consistent output
46+
result_map = {tag: sorted(str(path) for path in paths) for tag, paths in result_raw.items()}
47+
result_list = sorted(result_map.keys(), key=lambda x: len(result_map[x]), reverse=True)
48+
49+
if json:
50+
from json import dumps
51+
52+
result = result_map if map else result_list
53+
app.output(dumps(result))
54+
return
55+
56+
# If outputting for humans, display the tags in a table
57+
# This table is sorted by the most frequently used tags first
58+
if len(result_list) == 0:
59+
app.display("No build tags found.")
60+
return
61+
62+
if not map:
63+
app.display("\n".join(result_list))
64+
return
65+
66+
from collections import OrderedDict
67+
68+
# Order the tags by most-used first (by "count"), descending
69+
result_human = OrderedDict([
70+
(tag, {"count": len(result_map[tag]), "paths": ", ".join(result_map[tag])}) for tag in result_list
71+
])
72+
app.display_table(result_human)
73+
return

0 commit comments

Comments
 (0)