From c7b2970949346a55dde4cff492c456137276d590 Mon Sep 17 00:00:00 2001 From: Max P Date: Sun, 27 Apr 2025 14:16:54 +0000 Subject: [PATCH] Modularizes CLI commands for maintainability Refactors CLI command handlers into separate classes under a new `commands` module for improved organization and scalability. Introduces a `register_commands` function to centralize command registration. Adds version retrieval for better tool identification in CLI descriptions. --- src/hdlbuild/cli.py | 88 ++++--------------------------- src/hdlbuild/commands/__init__.py | 1 + src/hdlbuild/commands/build.py | 30 +++++++++++ src/hdlbuild/commands/clean.py | 27 ++++++++++ src/hdlbuild/commands/commands.py | 17 ++++++ src/hdlbuild/commands/dep.py | 17 ++++++ src/hdlbuild/commands/test.py | 23 ++++++++ 7 files changed, 126 insertions(+), 77 deletions(-) create mode 100644 src/hdlbuild/commands/__init__.py create mode 100644 src/hdlbuild/commands/build.py create mode 100644 src/hdlbuild/commands/clean.py create mode 100644 src/hdlbuild/commands/commands.py create mode 100644 src/hdlbuild/commands/dep.py create mode 100644 src/hdlbuild/commands/test.py diff --git a/src/hdlbuild/cli.py b/src/hdlbuild/cli.py index 6598e17..394a5cc 100644 --- a/src/hdlbuild/cli.py +++ b/src/hdlbuild/cli.py @@ -1,55 +1,17 @@ import argparse -import sys - -from hdlbuild.dependencies.resolver import DependencyResolver -from hdlbuild.models.config import DIRECTORIES -from hdlbuild.tools.xilinx_ise.isim import build_testbench, generate_simulation_project_file, run_testbench -from hdlbuild.tools.xilinx_ise.main import xilinx_ise_all, xilinx_ise_synth -from hdlbuild.utils.console_utils import ConsoleUtils -from hdlbuild.utils.directory_manager import clear_build_directories, clear_directories, ensure_directories_exist -from hdlbuild.utils.project_loader import load_project_config - -project = load_project_config() -console_utils = ConsoleUtils("hdlbuild") - -def clear(args): - """Clears the build artifacts.""" - if args.target == "all": - console_utils.print("Starting clear all process...") - clear_directories() - console_utils.print("All cleared.") - else: - console_utils.print("Clearing build artifacts...") - clear_build_directories() - console_utils.print("Build artifacts cleared.") - -def build(args): - """Starts the build process.""" - console_utils.print("Starting build process...") - ensure_directories_exist(True) - xilinx_ise_all(project) - -def synth(args): - """Starts the build process.""" - console_utils.print("Starting build process...") - ensure_directories_exist() - xilinx_ise_synth(project) - -def dep(args): - """Starts the dependencies process.""" - console_utils.print("Starting dependencies process...") - DependencyResolver(project).resolve_all() - -def test(args): - """Starts the test process.""" - console_utils.print("Starting test process...") - build_testbench(project, args.target) - run_testbench(project, args.target) +from importlib.metadata import version, PackageNotFoundError +from hdlbuild.commands import register_commands +def get_version(): + try: + return version("hdlbuild") # Paketname aus pyproject.toml + except PackageNotFoundError: + return "unknown" def main(): + version_str = get_version() parser = argparse.ArgumentParser( - description="hdlbuild - Build management tool for FPGA projects", + description=f"hdlbuild v{version_str} - Build management tool for FPGA projects", formatter_class=argparse.RawTextHelpFormatter ) @@ -60,36 +22,8 @@ def main(): required=True ) - # Clear command - parser_clear = subparsers.add_parser("clear", help="Clear build artifacts") - parser_clear.add_argument( - "target", - nargs="?", - choices=["all"], - help="Specify 'all' to clear everything (optional)" - ) - parser_clear.set_defaults(func=clear) - - # Build command - parser_build = subparsers.add_parser("build", help="Start the build process") - parser_build.set_defaults(func=build) - - # Synth command - parser_synth = subparsers.add_parser("synth", help="Start the synth process") - parser_synth.set_defaults(func=synth) - - # Dependencies command - parser_dep = subparsers.add_parser("dep", help="Start the dependencies process") - parser_dep.set_defaults(func=dep) - - # Tests command - parser_test = subparsers.add_parser("test", help="Start the Tests process") - parser_test.set_defaults(func=test) - parser_test.add_argument( - "target", - nargs="?", - help="Select the target to test" - ) + # Register all commands + register_commands(subparsers) args = parser.parse_args() args.func(args) diff --git a/src/hdlbuild/commands/__init__.py b/src/hdlbuild/commands/__init__.py new file mode 100644 index 0000000..e754fc7 --- /dev/null +++ b/src/hdlbuild/commands/__init__.py @@ -0,0 +1 @@ +from .commands import register_commands \ No newline at end of file diff --git a/src/hdlbuild/commands/build.py b/src/hdlbuild/commands/build.py new file mode 100644 index 0000000..a626e81 --- /dev/null +++ b/src/hdlbuild/commands/build.py @@ -0,0 +1,30 @@ +from hdlbuild.tools.xilinx_ise.main import xilinx_ise_all, xilinx_ise_synth +from hdlbuild.utils.console_utils import ConsoleUtils +from hdlbuild.utils.directory_manager import ensure_directories_exist +from hdlbuild.utils.project_loader import load_project_config + +class BuildCommand: + def __init__(self): + self.console_utils = ConsoleUtils("hdlbuild") + self.project = load_project_config() + + def register(self, subparsers): + parser = subparsers.add_parser("build", help="Start the build process") + parser.add_argument( + "target", + nargs="?", + choices=["synth"], + help="Specify 'synth' to only synthesize the design (optional)" + ) + parser.set_defaults(func=self.execute) + + def execute(self, args): + """Starts the build process.""" + if args.target == "synth": + self.console_utils.print("Starting synth process...") + ensure_directories_exist(True) + xilinx_ise_synth(self.project) + else: + self.console_utils.print("Starting build process...") + ensure_directories_exist(True) + xilinx_ise_all(self.project) \ No newline at end of file diff --git a/src/hdlbuild/commands/clean.py b/src/hdlbuild/commands/clean.py new file mode 100644 index 0000000..3e8e43a --- /dev/null +++ b/src/hdlbuild/commands/clean.py @@ -0,0 +1,27 @@ +from hdlbuild.utils.console_utils import ConsoleUtils +from hdlbuild.utils.directory_manager import clear_build_directories, clear_directories + +class CleanCommand: + def __init__(self): + self.console_utils = ConsoleUtils("hdlbuild") + + def register(self, subparsers): + parser = subparsers.add_parser("clean", help="Clean build artifacts") + parser.add_argument( + "target", + nargs="?", + choices=["all"], + help="Specify 'all' to clean everything (optional)" + ) + parser.set_defaults(func=self.execute) + + def execute(self, args): + """Cleans the build artifacts.""" + if args.target == "all": + self.console_utils.print("Starting clean all process...") + clear_directories() + self.console_utils.print("All cleaned.") + else: + self.console_utils.print("Clearing build artifacts...") + clear_build_directories() + self.console_utils.print("Build artifacts cleaned.") \ No newline at end of file diff --git a/src/hdlbuild/commands/commands.py b/src/hdlbuild/commands/commands.py new file mode 100644 index 0000000..565562d --- /dev/null +++ b/src/hdlbuild/commands/commands.py @@ -0,0 +1,17 @@ +from hdlbuild.commands.build import BuildCommand +from hdlbuild.commands.clean import CleanCommand +from hdlbuild.commands.dep import DepCommand +from hdlbuild.commands.test import TestCommand + + +def register_commands(subparsers): + """Registers all available commands.""" + commands = [ + CleanCommand(), + BuildCommand(), + DepCommand(), + TestCommand() + ] + + for command in commands: + command.register(subparsers) \ No newline at end of file diff --git a/src/hdlbuild/commands/dep.py b/src/hdlbuild/commands/dep.py new file mode 100644 index 0000000..ea2d9c4 --- /dev/null +++ b/src/hdlbuild/commands/dep.py @@ -0,0 +1,17 @@ +from hdlbuild.dependencies.resolver import DependencyResolver +from hdlbuild.utils.console_utils import ConsoleUtils +from hdlbuild.utils.project_loader import load_project_config + +class DepCommand: + def __init__(self): + self.console_utils = ConsoleUtils("hdlbuild") + self.project = load_project_config() + + def register(self, subparsers): + parser = subparsers.add_parser("dep", help="Start the dependencies process") + parser.set_defaults(func=self.execute) + + def execute(self, args): + """Starts the dependencies process.""" + self.console_utils.print("Starting dependencies process...") + DependencyResolver(self.project).resolve_all() \ No newline at end of file diff --git a/src/hdlbuild/commands/test.py b/src/hdlbuild/commands/test.py new file mode 100644 index 0000000..367dfd3 --- /dev/null +++ b/src/hdlbuild/commands/test.py @@ -0,0 +1,23 @@ +from hdlbuild.tools.xilinx_ise.isim import build_testbench, run_testbench +from hdlbuild.utils.console_utils import ConsoleUtils +from hdlbuild.utils.project_loader import load_project_config + +class TestCommand: + def __init__(self): + self.console_utils = ConsoleUtils("hdlbuild") + self.project = load_project_config() + + def register(self, subparsers): + parser = subparsers.add_parser("test", help="Start the Tests process") + parser.add_argument( + "target", + nargs="?", + help="Select the target to test" + ) + parser.set_defaults(func=self.execute) + + def execute(self, args): + """Starts the test process.""" + self.console_utils.print("Starting test process...") + build_testbench(self.project, args.target) + run_testbench(self.project, args.target) \ No newline at end of file