# ProjectInitializerTool/project_initializer/__main__.py import sys import argparse from pathlib import Path # Per lanciare il tool, la directory ProjectInitializerTool deve essere nel PYTHONPATH # o si deve essere in ProjectInitializerTool/ e lanciare python -m project_initializer # Questo permette gli import relativi corretti. from projectinitializer.gui import app_window # type: ignore from projectinitializer.cli import interface # type: ignore from projectinitializer.config import settings # type: ignore def ensure_default_icon_exists(): """ Checks if the default icon exists in the package's assets. Creates a dummy one if not, for development convenience of the tool itself. This helps prevent errors if the asset is accidentally deleted during development. """ icon_path = settings.DEFAULT_ICON_PATH if not icon_path.exists(): print(f"Warning: Default icon '{icon_path}' not found in package assets.", file=sys.stderr) print(f"Attempting to create a dummy empty icon file at that location.", file=sys.stderr) try: icon_path.parent.mkdir(parents=True, exist_ok=True) # Ensure assets directory exists icon_path.touch() print(f"Dummy '{settings.DEFAULT_ICON_FILE_NAME}' created at '{icon_path}'. " "Please replace it with a real .ico file for the tool to function correctly.", file=sys.stderr) except OSError as e: print(f"Critical Error: Could not create dummy icon at '{icon_path}': {e}. " "The tool might not be able to copy the icon to new projects.", file=sys.stderr) def main(): """ Main entry point for the Project Initializer tool. Determines whether to run in CLI or GUI mode. """ # Ensure the default icon asset is available for copying ensure_default_icon_exists() # Argument parser to decide mode (and for CLI args if that's the mode) # We use a basic parser here just to check for presence of CLI-specific args # or a potential --gui / --cli flag if we add one. # The full CLI parsing is delegated to cli.interface. parser = argparse.ArgumentParser( description="Python Project Initializer Tool.", add_help=False # We'll add help in a context-specific way or let sub-parsers do it ) # These arguments are for the CLI mode. If they are present, we assume CLI. # nargs='?' makes them optional for this initial parse, so GUI mode doesn't fail. parser.add_argument("root_directory", nargs="?", help=argparse.SUPPRESS) # Suppress from top-level help parser.add_argument("project_name", nargs="?", help=argparse.SUPPRESS) # Suppress from top-level help # Optional explicit mode flags (could be useful in future) # mode_group = parser.add_mutually_exclusive_group() # mode_group.add_argument("--cli", action="store_true", help="Force Command Line Interface mode.") # mode_group.add_argument("--gui", action="store_true", help="Force Graphical User Interface mode.") # Parse known arguments without exiting on error for missing positional ones yet. # This allows us to check if any arguments were passed that might indicate CLI intent. # All arguments including script name are in sys.argv # Heuristic: if there are arguments beyond the script name itself, # and they are not flags like --help (which cli.interface would handle), # it's likely an attempt to run CLI. # A very simple check: if sys.argv has more than 1 element (script name + something else) # A slightly better one: check if root_directory and project_name are likely provided. # If sys.argv has more than 1 element (meaning some args were passed) # AND those arguments are not specific GUI launch flags (if we add them later) # then, we assume it's for the CLI. Otherwise, default to GUI. # Let's try parsing the arguments. If root_directory and project_name are provided, # it's CLI mode. Otherwise, it's GUI. This relies on argparse's behavior. # sys.argv[0] is script name or -m module_name # If any arguments are passed (beyond script name), assume CLI intent. # The cli.interface.handle_cli_invocation will perform full parsing and error handling. # If no arguments are passed, launch GUI. # This is a simplification. A --cli or --gui flag would be more robust. # Check if sys.argv contains arguments that are likely positional arguments for CLI # sys.argv = ['project_initializer/__main__.py', 'arg1', 'arg2'] for `python -m project_initializer arg1 arg2` # sys.argv = ['script.py'] for `python script.py` # A common pattern for this is to try to parse, and if specific args are found, run one mode. # For simplicity now: if arguments are passed, assume CLI. cli.interface will validate them. # If no arguments are passed (only script name), assume GUI. args_to_parse = sys.argv[1:] # Heuristic: if the first argument doesn't start with '-' and there are two arguments, # it's highly probable they are the positional 'root_directory' and 'project_name'. # This avoids accidentally going to CLI if someone types `python -m project_initializer --some-unknown-gui-flag`. is_cli_intent = False if len(args_to_parse) >= 2: # Check if the first two args are likely our positional CLI args # (i.e., they don't look like options/flags) if not args_to_parse[0].startswith('-') and not args_to_parse[1].startswith('-'): is_cli_intent = True elif len(args_to_parse) == 1 and (args_to_parse[0] == "--help" or args_to_parse[0] == "-h"): # If only help is requested, let CLI handler show its help message is_cli_intent = True if is_cli_intent: # Pass all arguments (sys.argv[1:]) to the CLI handler interface.handle_cli_invocation(args_to_parse) else: # No arguments or arguments that don't match CLI pattern, launch GUI if args_to_parse and not (len(args_to_parse) == 1 and (args_to_parse[0] == "--help" or args_to_parse[0] == "-h")): # Arguments were passed that didn't fit the CLI pattern, # and it wasn't a simple help request. Show a warning/help. print("Info: Unrecognized arguments for CLI mode. Defaulting to GUI mode.", file=sys.stdout) print("For CLI, provide: ", file=sys.stdout) print("Example: python -m project_initializer /path/to/projects MyNewApp\n", file=sys.stdout) print("Launching GUI mode...") # Useful feedback if launched from terminal app_window.launch_gui_application() if __name__ == "__main__": main()