Skip to content

Commit cc08c11

Browse files
committed
Add tool to find unused module utils.
1 parent 5bd65cc commit cc08c11

File tree

1 file changed

+82
-1
lines changed

1 file changed

+82
-1
lines changed

src/antsibull_nox/cli.py

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919

2020
from . import __version__
2121
from .cd import get_base_branch, get_changes, init_cd, supports_cd
22-
from .config import CONFIG_FILENAME, load_config_from_toml
22+
from .config import CONFIG_FILENAME, Config, load_config_from_toml
2323
from .init import create_initial_config as _create_initial_config
2424
from .lint_config import lint_config as _lint_config
25+
from .python.python_dependencies import get_python_dependency_info
2526
from .sessions.utils.paths import PythonDependencies, add_python_deps
2627

2728
try:
@@ -107,12 +108,78 @@ def show_changes(args: argparse.Namespace) -> int:
107108
return 0
108109

109110

111+
def dependency_tree(args: argparse.Namespace) -> int:
112+
"""
113+
Subcommand 'dependency-tree'.
114+
"""
115+
subcommand: str = args.subcommand
116+
117+
config_path = Path(CONFIG_FILENAME)
118+
try:
119+
config = load_config_from_toml(config_path)
120+
except Exception as exc: # pylint: disable=broad-exception-caught
121+
print(f"Error: {exc}", file=sys.stderr)
122+
return 3
123+
124+
return DEPENDENCY_TREE_ARGS_MAP[subcommand](config, args)
125+
126+
127+
def find_unused_python(
128+
config: Config, args: argparse.Namespace # pylint: disable=unused-argument
129+
) -> int:
130+
"""
131+
Subcommand 'dependency-tree find-unused-python'.
132+
"""
133+
dep_info = get_python_dependency_info()
134+
found: set[Path] = set()
135+
for file, module_path in dep_info.file_to_module_path.items():
136+
if (
137+
len(module_path) > 4
138+
and module_path[3] == "plugins"
139+
and module_path[4] not in ("module_utils", "plugin_utils")
140+
):
141+
found.add(file)
142+
to_do: list[Path] = list(found)
143+
while to_do:
144+
file = to_do.pop()
145+
next_info = dep_info.file_to_imported_modules.get(file)
146+
if next_info:
147+
_next_module_paths, next_files = next_info
148+
for next_file in next_files:
149+
if next_file not in found:
150+
found.add(next_file)
151+
to_do.append(next_file)
152+
left_over = {
153+
file
154+
for file, module_path in dep_info.file_to_module_path.items()
155+
if len(module_path) > 3
156+
and module_path[3] == "plugins"
157+
and file.name != "__init__.py"
158+
and file not in found
159+
}
160+
if left_over:
161+
print(f"Found {len(left_over)} apparently unused Python modules in plugins/:")
162+
cwd = Path.cwd()
163+
for file in sorted(left_over):
164+
print(f" {file.relative_to(cwd)}")
165+
else:
166+
print("All code in plugins/ seems to be in use.")
167+
return 0
168+
169+
110170
# Mapping from command line subcommand names to functions which implement those.
111171
# The functions need to take a single argument, the processed list of args.
112172
ARGS_MAP: dict[str, Callable[[argparse.Namespace], int]] = {
113173
"lint-config": lint_config,
114174
"init": create_initial_config,
115175
"show-changes": show_changes,
176+
"dependency-tree": dependency_tree,
177+
}
178+
179+
# Mapping from command line subcommand names to functions which implement those.
180+
# The functions need to take a single argument, the processed list of args.
181+
DEPENDENCY_TREE_ARGS_MAP: dict[str, Callable[[Config, argparse.Namespace], int]] = {
182+
"find-unused-python": find_unused_python,
116183
}
117184

118185

@@ -165,6 +232,20 @@ def parse_args(program_name: str, args: list[str]) -> argparse.Namespace:
165232
" Python files (transitively) imported by changed files will be added ('foward').",
166233
)
167234

235+
show_changes_parser = subparsers.add_parser(
236+
"dependency-tree", description="Operations on the dependency trees"
237+
)
238+
show_changes_parser_sub = show_changes_parser.add_subparsers(
239+
title="Subcommands",
240+
dest="subcommand",
241+
help="for help use: `SUBCOMMANDS -h`",
242+
required=True,
243+
)
244+
245+
show_changes_parser_sub.add_parser(
246+
"find-unused-python", description="Find unused Python module and plugin utils"
247+
)
248+
168249
# This must come after all parser setup
169250
if HAS_ARGCOMPLETE:
170251
argcomplete.autocomplete(toplevel_parser)

0 commit comments

Comments
 (0)