diff --git a/cli/commands/__init__.py b/cli/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cli/commands/analyze.py b/cli/commands/analyze.py new file mode 100644 index 0000000..cb47993 --- /dev/null +++ b/cli/commands/analyze.py @@ -0,0 +1,88 @@ +from InquirerPy import inquirer + +from cli.utils.get_translation import get_translation +from spice.analyze import analyze_file + + +def analyze_command(file, all, json_output, LANG_FILE): + """ + Analyze the given file. + """ + + # load translations + messages = get_translation(LANG_FILE) + + # define available stats UPDATE THIS WHEN NEEDED PLEASE !!!!!!!! + available_stats = [ + "line_count", + "function_count", + "comment_line_count" + ] + + # dictionary for the stats UPDATE THIS WHEN NEEDED PLEASE !!!!!!!! + stats_labels = { + "line_count": messages.get("line_count_option", "Line Count"), + "function_count": messages.get("function_count_option", "Function Count"), + "comment_line_count": messages.get("comment_line_count_option", "Comment Line Count") + } + + # If --all flag is used, skip the selection menu and use all stats + if all: + selected_stat_keys = available_stats + else: + # Don't show interactive menu in JSON mode (assumes all stats) + if json_output: + selected_stat_keys = available_stats + else: + # print checkbox menu to select which stats to show + selected_stats = inquirer.checkbox( + message=messages.get("select_stats", "Select stats to display:"), + choices=[stats_labels[stat] for stat in available_stats], + pointer="> ", + default=[stats_labels[stat] for stat in available_stats], # All selected by default + instruction=messages.get("checkbox_hint", "(Use space to select, enter to confirm)") + ).execute() + + # if no stats were selected + if not selected_stats: + if json_output: + import json + print(json.dumps({"error": messages.get("no_stats_selected", "No stats selected. Analysis cancelled.")})) + else: + print(messages.get("no_stats_selected", "No stats selected. Analysis cancelled.")) + return + + # create a mapping from displayed labels back to stat keys + reverse_mapping = {v: k for k, v in stats_labels.items()} + + # convert selected labels back to stat keys + selected_stat_keys = [reverse_mapping[label] for label in selected_stats] + + # try to analyze and if error then print the error + try: + # show analyzing message if not in JSON mode + if not json_output: + print(f"{messages['analyzing_file']}: {file}") + + # get analysis results from analyze_file + results = analyze_file(file, selected_stats=selected_stat_keys) + + # output in JSON format if flag + if json_output: + import json + print(json.dumps(results, indent=2)) + else: + # only print the selected stats in normal mode + for stat in selected_stat_keys: + if stat in results: + print(messages[stat].format(count=results[stat])) + + except Exception as e: + if json_output: + import json + # Replace newlines with spaces or escape them properly + error_msg = str(e).replace('\n', ' ') + print(json.dumps({"error": error_msg})) + else: + print(f"[red]{messages['error']}[/] {e}") + diff --git a/cli/commands/hello.py b/cli/commands/hello.py new file mode 100644 index 0000000..f58f7a9 --- /dev/null +++ b/cli/commands/hello.py @@ -0,0 +1,13 @@ +from rich import print # this add colors to the printed text + +from cli.utils.get_translation import get_translation + + +def hello_command(LANG_FILE): + + # load translations + messages = get_translation(LANG_FILE) + + # print the hello message + print(messages["welcome"]) + print(messages["description"]) \ No newline at end of file diff --git a/cli/commands/translate.py b/cli/commands/translate.py new file mode 100644 index 0000000..a9a00df --- /dev/null +++ b/cli/commands/translate.py @@ -0,0 +1,40 @@ +from InquirerPy import inquirer + + +def translate_command(LANG_FILE): + """ + Set the language for CLI messages. + """ + + # LIST OF ALL AVAILIBLE LANGAUGES ADD NEW TRANSLATIONS HERE PLEASE !!!!!!!!!!!!!!!!!!!!!!!! + LANGUAGES = { + "en": {"name": "English"}, + "pt-br": {"name": "Portuguese"}, + "fremen": {"name": "Fremen"}, + # Add more languages as needed + } + + # this just makes the list above actually work (i wanted to add emojis but flag emojies dont work on pc 😭) + choices = [ + f"{info['name']} ({lang})" for lang, info in LANGUAGES.items() + ] + + # intereacitive menu + selected_choice = inquirer.select( + message="Choose a language:", + choices=choices, + pointer="> ", + default="English" + ).execute() + + # will read the dicionary to see what langauggue is which does that make sense? its like the reverse of before + selected_lang = next( + lang for lang, info in LANGUAGES.items() if f"{info['name']} ({lang})" == selected_choice + ) + + # will write the new language to the langague file (to save it to HD instead of memory) (so its persistant between commands) + with open(LANG_FILE, "w") as file: + file.write(selected_lang) + + print(f"[green]Language set to:[/] {selected_lang}") + diff --git a/cli/commands/version.py b/cli/commands/version.py new file mode 100644 index 0000000..2e9111e --- /dev/null +++ b/cli/commands/version.py @@ -0,0 +1,41 @@ +import os +from rich import print # this add colors to the printed text + +from cli.utils.get_translation import get_translation + + +def version_command(LANG_FILE, CURRENT_DIR): + """ + Display the current version of the application. + """ + + # load translations + messages = get_translation(LANG_FILE) + + try: + # Get the path to setup.py in the parent directory + setup_path = os.path.join(os.path.dirname(CURRENT_DIR), "setup.py") + + # Check if setup.py exists + if not os.path.exists(setup_path): + print(f"[red]{messages.get('setup_not_found', 'Error: setup.py not found.')}") + return + + # Read setup.py to extract version + version_info = None + with open(setup_path, "r") as file: + for line in file: + if line.strip().startswith("version="): + # Extract version using string manipulation + version_line = line.strip() + version_info = version_line.split("=")[1].strip().strip('"').strip("'").strip(",") + break + + # Display version information + if version_info: + print(f"[green]{messages.get('version_info', 'SpiceCode Version:')}[/] {version_info}") + else: + print(f"[yellow]{messages.get('version_not_found', 'Version information not found in setup.py')}") + + except Exception as e: + print(f"[red]{messages.get('error', 'Error:')}[/] {e}") \ No newline at end of file diff --git a/cli/main.py b/cli/main.py index 834ce8b..a452d9c 100644 --- a/cli/main.py +++ b/cli/main.py @@ -1,11 +1,19 @@ import os import sys -import importlib import typer -from rich import print -from InquirerPy import inquirer + +# this is the analyzer from spice.analyze import analyze_file +# here we import utilities +from cli.utils.get_translation import get_translation + +# here we import the commands +from cli.commands.translate import translate_command +from cli.commands.hello import hello_command +from cli.commands.version import version_command +from cli.commands.analyze import analyze_command + # initialize typer app = typer.Typer() @@ -19,73 +27,18 @@ # select a file to save the current selected langague (if saved to memory it wont persist between commands) LANG_FILE = os.path.join(CURRENT_DIR, "lang.txt") -# this will load the translations -def get_translation(): - - # read the lang file to see what langague was set by user - if os.path.exists(LANG_FILE): - - # open the lang file - with open(LANG_FILE, "r") as file: - - # read the lang file - lang = file.read().strip() - - - if not lang: - lang = 'en' # if file is empty, default to english - - else: - lang = 'en' # default to English if there is not file but there will always be a file this is just in case ALSO THIS IS SO @icrcode DOESNT COMPLAIN ABOUT MY CODE NOT BEING CLEAN AND WHATEVER - - # this is actually import the translations - try: - return importlib.import_module(f"cli.translations.{lang}").messages - except ModuleNotFoundError: - return importlib.import_module("cli.translations.en").messages # default to English if any errors - - -# SPICE SET_LANG COMMAND +# SPICE TRANSLATE COMMAND @app.command() def translate(): """ Set the language for CLI messages. """ - # LIST OF ALL AVAILIBLE LANGAUGES ADD NEW TRANSLATIONS HERE PLEASE !!!!!!!!!!!!!!!!!!!!!!!! - LANGUAGES = { - "en": {"name": "English"}, - "pt-br": {"name": "Portuguese"}, - "fremen": {"name": "Fremen"}, - # Add more languages as needed - } - - # this just makes the list above actually work (i wanted to add emojis but flag emojies dont work on pc 😭) - choices = [ - f"{info['name']} ({lang})" for lang, info in LANGUAGES.items() - ] - - # intereacitive menu - selected_choice = inquirer.select( - message="Choose a language:", - choices=choices, - pointer="> ", - default="English" - ).execute() - - # will read the dicionary to see what langauggue is which does that make sense? its like the reverse of before - selected_lang = next( - lang for lang, info in LANGUAGES.items() if f"{info['name']} ({lang})" == selected_choice - ) - - # will write the new language to the langague file (to save it to HD instead of memory) (so its persistant between commands) - with open(LANG_FILE, "w") as file: - file.write(selected_lang) - - print(f"[green]Language set to:[/] {selected_lang}") + translate_command(LANG_FILE) +# -- end -- # # SPICE HELLO COMMAND @@ -95,12 +48,9 @@ def hello(): Welcome message. """ - # load translations - messages = get_translation() + hello_command(LANG_FILE) - # print the hello message - print(messages["welcome"]) - print(messages["description"]) +# -- end -- # # SPICE VERSION COMMAND @@ -110,36 +60,9 @@ def version(): Display the current version of the application. """ - # load translations - messages = get_translation() - - try: - # Get the path to setup.py in the parent directory - setup_path = os.path.join(os.path.dirname(CURRENT_DIR), "setup.py") - - # Check if setup.py exists - if not os.path.exists(setup_path): - print(f"[red]{messages.get('setup_not_found', 'Error: setup.py not found.')}") - return - - # Read setup.py to extract version - version_info = None - with open(setup_path, "r") as file: - for line in file: - if line.strip().startswith("version="): - # Extract version using string manipulation - version_line = line.strip() - version_info = version_line.split("=")[1].strip().strip('"').strip("'").strip(",") - break - - # Display version information - if version_info: - print(f"[green]{messages.get('version_info', 'Version:')}[/] {version_info}") - else: - print(f"[yellow]{messages.get('version_not_found', 'Version information not found in setup.py')}") - - except Exception as e: - print(f"[red]{messages.get('error', 'Error:')}[/] {e}") + version_command(LANG_FILE, CURRENT_DIR) + +#--- end ---# # SPICE ANALYZE COMMAND @@ -153,87 +76,19 @@ def analyze( Analyze the given file. """ - # load translations - messages = get_translation() - - # define available stats UPDATE THIS WHEN NEEDED PLEASE !!!!!!!! - available_stats = [ - "line_count", - "function_count", - "comment_line_count" - ] - - # dictionary for the stats UPDATE THIS WHEN NEEDED PLEASE !!!!!!!! - stats_labels = { - "line_count": messages.get("line_count_option", "Line Count"), - "function_count": messages.get("function_count_option", "Function Count"), - "comment_line_count": messages.get("comment_line_count_option", "Comment Line Count") - } - - # If --all flag is used, skip the selection menu and use all stats - if all: - selected_stat_keys = available_stats - else: - # Don't show interactive menu in JSON mode (assumes all stats) - if json_output: - selected_stat_keys = available_stats - else: - # print checkbox menu to select which stats to show - selected_stats = inquirer.checkbox( - message=messages.get("select_stats", "Select stats to display:"), - choices=[stats_labels[stat] for stat in available_stats], - pointer="> ", - default=[stats_labels[stat] for stat in available_stats], # All selected by default - instruction=messages.get("checkbox_hint", "(Use space to select, enter to confirm)") - ).execute() - - # if no stats were selected - if not selected_stats: - if json_output: - import json - print(json.dumps({"error": messages.get("no_stats_selected", "No stats selected. Analysis cancelled.")})) - else: - print(messages.get("no_stats_selected", "No stats selected. Analysis cancelled.")) - return - - # create a mapping from displayed labels back to stat keys - reverse_mapping = {v: k for k, v in stats_labels.items()} - - # convert selected labels back to stat keys - selected_stat_keys = [reverse_mapping[label] for label in selected_stats] - - # try to analyze and if error then print the error - try: - # show analyzing message if not in JSON mode - if not json_output: - print(f"{messages['analyzing_file']}: {file}") - - # get analysis results from analyze_file - results = analyze_file(file, selected_stats=selected_stat_keys) - - # output in JSON format if flag - if json_output: - import json - print(json.dumps(results, indent=2)) - else: - # only print the selected stats in normal mode - for stat in selected_stat_keys: - if stat in results: - print(messages[stat].format(count=results[stat])) - - except Exception as e: - if json_output: - import json - # Replace newlines with spaces or escape them properly - error_msg = str(e).replace('\n', ' ') - print(json.dumps({"error": error_msg})) - else: - print(f"[red]{messages['error']}[/] {e}") + analyze_command(file, all, json_output, LANG_FILE) + +# -- end -- # def main(): app() # run typer +# -- end -- # + + # whatever the fuck this is python makes no sense if __name__ == "__main__": - main() \ No newline at end of file + main() + +# -- end -- # \ No newline at end of file diff --git a/cli/translations/en.py b/cli/translations/en.py index 9f44294..0e3973a 100644 --- a/cli/translations/en.py +++ b/cli/translations/en.py @@ -18,7 +18,7 @@ "confirm_and_analyze": "Confirm and analyze", "checkbox_hint": "(Use space to select, enter to confirm)", # keys for the version command - "version_info": "Version:", + "version_info": "SpiceCode Version:", "version_not_found": "Version information not found in setup.py", "setup_not_found": "Error: setup.py not found." } \ No newline at end of file diff --git a/cli/utils/__init__.py b/cli/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cli/utils/get_translation.py b/cli/utils/get_translation.py new file mode 100644 index 0000000..e454258 --- /dev/null +++ b/cli/utils/get_translation.py @@ -0,0 +1,27 @@ +import importlib +import os + +# this will load the translations +def get_translation(LANG_FILE): + + # read the lang file to see what langague was set by user + if os.path.exists(LANG_FILE): + + # open the lang file + with open(LANG_FILE, "r") as file: + + # read the lang file + lang = file.read().strip() + + + if not lang: + lang = 'en' # if file is empty, default to english + + else: + lang = 'en' # default to English if there is not file but there will always be a file this is just in case ALSO THIS IS SO @icrcode DOESNT COMPLAIN ABOUT MY CODE NOT BEING CLEAN AND WHATEVER + + # this is actually import the translations + try: + return importlib.import_module(f"cli.translations.{lang}").messages + except ModuleNotFoundError: + return importlib.import_module("cli.translations.en").messages # default to English if any errors