From 05771ca80da4d50d23418b37764f18dcfd4d7b50 Mon Sep 17 00:00:00 2001 From: ManfredHair Date: Tue, 29 Apr 2025 21:40:43 -0300 Subject: [PATCH 01/10] count external dependencies --- .../analyzers/count_external_dependencies.py | 196 ++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 spice/analyzers/count_external_dependencies.py diff --git a/spice/analyzers/count_external_dependencies.py b/spice/analyzers/count_external_dependencies.py new file mode 100644 index 0000000..24b4644 --- /dev/null +++ b/spice/analyzers/count_external_dependencies.py @@ -0,0 +1,196 @@ +# this will count external dependencies (imports/requires from external libraries) +# EXTERNAL DEPENDENCY is an import/require statement that references an external library +from utils.get_lexer import get_lexer_for_file +from lexers.token import TokenType +import os +import re +import sys + +# Python standard library modules to exclude from dependency count +PYTHON_STD_LIBS = set([ + 'abc', 'argparse', 'ast', 'asyncio', 'base64', 'collections', 'concurrent', 'contextlib', + 'copy', 'csv', 'ctypes', 'datetime', 'decimal', 'enum', 'functools', 'glob', 'gzip', + 'hashlib', 'http', 'importlib', 'inspect', 'io', 'itertools', 'json', 'logging', 'math', + 'multiprocessing', 'operator', 'os', 'pathlib', 'pickle', 'queue', 're', 'random', + 'shutil', 'signal', 'socket', 'sqlite3', 'statistics', 'string', 'subprocess', 'sys', + 'tempfile', 'threading', 'time', 'typing', 'unittest', 'urllib', 'uuid', 'warnings', + 'weakref', 'xml', 'zipfile', 'zlib' +]) + +# Node.js standard modules to exclude +NODE_STD_LIBS = set([ + 'assert', 'async_hooks', 'buffer', 'child_process', 'cluster', 'console', 'constants', + 'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'module', 'net', + 'os', 'path', 'perf_hooks', 'process', 'punycode', 'querystring', 'readline', 'repl', + 'stream', 'string_decoder', 'timers', 'tls', 'tty', 'url', 'util', 'v8', 'vm', 'zlib' +]) + +# Go standard packages to exclude +GO_STD_LIBS = set([ + 'archive', 'bufio', 'builtin', 'bytes', 'compress', 'container', 'context', 'crypto', + 'database', 'debug', 'encoding', 'errors', 'expvar', 'flag', 'fmt', 'go', 'hash', + 'html', 'image', 'index', 'io', 'log', 'math', 'mime', 'net', 'os', 'path', 'plugin', + 'reflect', 'regexp', 'runtime', 'sort', 'strconv', 'strings', 'sync', 'syscall', + 'testing', 'text', 'time', 'unicode', 'unsafe' +]) + +# Ruby standard libraries to exclude +RUBY_STD_LIBS = set([ + 'abbrev', 'base64', 'benchmark', 'bigdecimal', 'cgi', 'csv', 'date', 'delegate', + 'digest', 'drb', 'e2mmap', 'erb', 'etc', 'fcntl', 'fiddle', 'fileutils', 'find', + 'forwardable', 'io', 'ipaddr', 'irb', 'json', 'logger', 'matrix', 'monitor', 'mutex_m', + 'net', 'observer', 'open-uri', 'open3', 'optparse', 'ostruct', 'pathname', 'pp', + 'prettyprint', 'prime', 'profile', 'profiler', 'pstore', 'pty', 'racc', 'rake', + 'rdoc', 'readline', 'resolv', 'rexml', 'rinda', 'ripper', 'rss', 'rubygems', 'scanf', + 'sdbm', 'set', 'shellwords', 'singleton', 'socket', 'stringio', 'strscan', 'sync', + 'syslog', 'tempfile', 'thread', 'thwait', 'time', 'timeout', 'tmpdir', 'tracer', + 'tsort', 'uri', 'weakref', 'webrick', 'yaml', 'zlib' +]) + +def count_external_dependencies(file_path): + """Count external dependencies in a file. + + Args: + file_path (str): Path to the file to analyze + + Returns: + int: Number of external dependencies found + """ + # Get file extension to determine language + _, ext = os.path.splitext(file_path) + + # Read the file content + with open(file_path, 'r', encoding='utf-8') as f: + code = f.read() + + # Count dependencies based on the language + if ext == '.py': + return count_python_dependencies(code) + elif ext == '.js': + return count_javascript_dependencies(code) + elif ext == '.rb': + return count_ruby_dependencies(code) + elif ext == '.go': + return count_go_dependencies(code) + else: + # Default to 0 for unsupported languages + return 0 + +def count_python_dependencies(code): + """Count external dependencies in Python code.""" + # Regular expressions for import patterns + import_pattern = r'^\s*import\s+([a-zA-Z0-9_.,\s]+)' + from_pattern = r'^\s*from\s+([a-zA-Z0-9_.]+)\s+import' + + dependencies = set() + + # Find all import statements + for line in code.split('\n'): + # Check for 'import X' pattern + import_match = re.match(import_pattern, line) + if import_match: + modules = [m.strip() for m in import_match.group(1).split(',')] + for module in modules: + # Get the top-level package + top_level = module.split('.')[0] + dependencies.add(top_level) + + # Check for 'from X import Y' pattern + from_match = re.match(from_pattern, line) + if from_match: + # Get the top-level package + module = from_match.group(1) + top_level = module.split('.')[0] + dependencies.add(top_level) + + # Filter out standard library modules + external_deps = {dep for dep in dependencies if dep not in PYTHON_STD_LIBS} + + return len(external_deps) + +def count_javascript_dependencies(code): + """Count external dependencies in JavaScript code.""" + # Regular expressions for require and import patterns + require_pattern = r'(?:const|let|var)\s+.+\s*=\s*require\([\'"]([^\'".]+)[\'"]' + import_pattern = r'import\s+(?:.+\s+from\s+)?[\'"]([^\'".]+)[\'"]' + + dependencies = set() + + # Find all require statements + for match in re.finditer(require_pattern, code): + module_name = match.group(1) + dependencies.add(module_name) + + # Find all import statements + for match in re.finditer(import_pattern, code): + module_name = match.group(1) + dependencies.add(module_name) + + # Filter out Node.js standard libraries and relative imports + external_deps = { + dep for dep in dependencies + if dep not in NODE_STD_LIBS and not dep.startswith('./') and not dep.startswith('../') + } + + return len(external_deps) + +def count_ruby_dependencies(code): + """Count external dependencies in Ruby code.""" + # Regular expressions for require and gem patterns + require_pattern = r'require\s+[\'"]([^\'"]+)[\'"]' + gem_pattern = r'gem\s+[\'"]([^\'"]+)[\'"]' + + dependencies = set() + + # Find all require statements + for match in re.finditer(require_pattern, code): + module_name = match.group(1) + dependencies.add(module_name) + + # Find all gem statements + for match in re.finditer(gem_pattern, code): + module_name = match.group(1) + dependencies.add(module_name) + + # Filter out Ruby standard libraries + external_deps = { + dep for dep in dependencies + if dep not in RUBY_STD_LIBS and not dep.startswith('./') and not dep.startswith('../') + } + + return len(external_deps) + +def count_go_dependencies(code): + """Count external dependencies in Go code.""" + # Regular expression for import statements + single_import_pattern = r'import\s+[\'"]([^\'"]+)[\'"]' + multi_import_pattern = r'import\s+\(\s*((?:[\'"][^\'"]+[\'"][\s\n]*)+)\)' + + dependencies = set() + + # Find all single import statements + for match in re.finditer(single_import_pattern, code): + module_path = match.group(1) + if module_path: + # Get the top-level package + dependencies.add(module_path) + + # Find all multi-line import statements + for match in re.finditer(multi_import_pattern, code, re.DOTALL): + imports_block = match.group(1) + for line in imports_block.strip().split('\n'): + line = line.strip() + if line and (line.startswith('"') or line.startswith("'")): + # Extract package path from quoted string + module_path = re.findall(r'[\'"]([^\'"]+)[\'"]', line) + if module_path: + dependencies.add(module_path[0]) + + # Filter out standard library imports (packages without a domain or github.com/) + external_deps = set() + for dep in dependencies: + # Skip standard library packages (no dots in path) + if '.' in dep and not any(dep.startswith(std + '/') for std in GO_STD_LIBS): + external_deps.add(dep) + + return len(external_deps) \ No newline at end of file From 4479e58c002e5d3aa17ad9691404f7ee4ec8b10f Mon Sep 17 00:00:00 2001 From: ManfredHair Date: Tue, 29 Apr 2025 21:40:51 -0300 Subject: [PATCH 02/10] analyze external dependencies --- spice/analyze.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/spice/analyze.py b/spice/analyze.py index ca40aa4..20213a8 100644 --- a/spice/analyze.py +++ b/spice/analyze.py @@ -11,7 +11,7 @@ def analyze_file(file_path: str, selected_stats: Optional[List[str]] = None) -> file_path (str): Path to the file to analyze selected_stats (list, optional): List of stats to compute. If None, compute all stats. Valid stats are: "line_count", "function_count", "comment_line_count", - "inline_comment_count", "indentation_level" + "inline_comment_count", "external_dependencies_count", "indentation_level" Returns: dict: Dictionary containing the requested stats and file information @@ -35,7 +35,14 @@ def analyze_file(file_path: str, selected_stats: Optional[List[str]] = None) -> raise ValueError("File has no extension") # Define valid stats - valid_stats = ["line_count", "function_count", "comment_line_count", "inline_comment_count", "indentation_level"] + valid_stats = [ + "line_count", + "function_count", + "comment_line_count", + "inline_comment_count", + "external_dependencies_count", + "indentation_level" + ] # default to all stats if none specified if selected_stats is None: @@ -79,6 +86,11 @@ def analyze_file(file_path: str, selected_stats: Optional[List[str]] = None) -> LexerClass = get_lexer_for_file(file_path) lexer = LexerClass(source_code=code) # Pass source_code explicitly results["inline_comment_count"] = count_inline_comments(file_path) + + # external dependencies count if requested + if "external_dependencies_count" in selected_stats: + from spice.analyzers.count_external_dependencies import count_external_dependencies + results["external_dependencies_count"] = count_external_dependencies(file_path) # indentation analysis if requested if "indentation_level" in selected_stats: From 9ab6c2f9d17ec6a645a4219b63d9cd5a047c17fd Mon Sep 17 00:00:00 2001 From: ManfredHair Date: Tue, 29 Apr 2025 21:41:01 -0300 Subject: [PATCH 03/10] count for external dependencies --- cli/commands/analyze.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cli/commands/analyze.py b/cli/commands/analyze.py index 595afa9..6808d3c 100644 --- a/cli/commands/analyze.py +++ b/cli/commands/analyze.py @@ -18,6 +18,7 @@ def analyze_command(file, all, json_output, LANG_FILE): "function_count", "comment_line_count", "inline_comment_count", + "external_dependencies_count", "indentation_level" ] @@ -27,6 +28,7 @@ def analyze_command(file, all, json_output, LANG_FILE): "function_count": messages.get("function_count_option", "Function Count"), "comment_line_count": messages.get("comment_line_count_option", "Comment Line Count"), "inline_comment_count": messages.get("inline_comment_count_option", "Inline Comment Count"), + "external_dependencies_count": messages.get("external_dependencies_count_option", "External Dependencies Count"), "indentation_level": messages.get("indentation_level_option", "Indentation Analysis") } From b807736da48900fc68af565248e9b7545cef1e2a Mon Sep 17 00:00:00 2001 From: ManfredHair Date: Tue, 29 Apr 2025 21:41:19 -0300 Subject: [PATCH 04/10] translations for external dependencies --- cli/translations/en.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cli/translations/en.py b/cli/translations/en.py index 7c9885a..6c4f598 100644 --- a/cli/translations/en.py +++ b/cli/translations/en.py @@ -10,12 +10,14 @@ "function_count": "The file has {count} functions", "comment_line_count": "The file has {count} comment lines", "inline_comment_count": "The file has {count} inline comments", + "external_dependencies_count": "The file has {count} external dependencies", # keys for analyze command checkbox menu "select_stats": "Select stats to display:", "line_count_option": "Line Count", "function_count_option": "Function Count", "comment_line_count_option": "Comment Line Count", "inline_comment_count_option": "Inline Comment Count", + "external_dependencies_count_option": "External Dependencies Count", "no_stats_selected": "No stats selected. Analysis cancelled.", "confirm_and_analyze": "Confirm and analyze", "checkbox_hint": "(Use space to select, enter to confirm)", From 3d0859be0d4124c7ac47c984fbc6ad6da84fb05b Mon Sep 17 00:00:00 2001 From: ManfredHair Date: Tue, 29 Apr 2025 21:41:23 -0300 Subject: [PATCH 05/10] external dependencies --- cli/translations/pt-br.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cli/translations/pt-br.py b/cli/translations/pt-br.py index c5afdf9..173a0ac 100644 --- a/cli/translations/pt-br.py +++ b/cli/translations/pt-br.py @@ -10,12 +10,14 @@ "function_count": "O arquivo tem {count} funções", "comment_line_count": "O arquivo tem {count} linhas de comentário", "inline_comment_count": "O arquivo tem {count} comentários inline", + "external_dependencies_count": "O arquivo tem {count} dependências externas", # chaves para o menu de seleção do comando analyze "select_stats": "Selecione as estatísticas para exibir:", "line_count_option": "Contagem de Linhas", "function_count_option": "Contagem de Funções", "comment_line_count_option": "Contagem de Linhas de Comentário", "inline_comment_count_option": "Contagem de Comentários Inline", + "external_dependencies_count_option": "Contagem de Dependências Externas", "no_stats_selected": "Nenhuma estatística selecionada. Análise cancelada.", "confirm_and_analyze": "Confirmar e analisar", "checkbox_hint": "(Use espaço para selecionar, enter para confirmar)" From 346e5e166936d9d3c64cb87bb7d991d45a467c22 Mon Sep 17 00:00:00 2001 From: ManfredHair Date: Tue, 29 Apr 2025 21:41:26 -0300 Subject: [PATCH 06/10] external dependencies --- cli/translations/fremen.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cli/translations/fremen.py b/cli/translations/fremen.py index f7bb68b..536d833 100644 --- a/cli/translations/fremen.py +++ b/cli/translations/fremen.py @@ -10,12 +10,14 @@ "function_count": "The file holds {count} sacred routines", "comment_line_count": "The file whispers {count} lines of hidden lore", "inline_comment_count": "The file contains {count} passages of dual meaning", + "external_dependencies_count": "The file summons {count} foreign powers from beyond the sands", # keys for analyze command checkbox menu "select_stats": "Choose the omens to unveil:", "line_count_option": "Dune Count", "function_count_option": "Sacred Routines", "comment_line_count_option": "Whispered Lore", "inline_comment_count_option": "Passages of Dual Meaning", + "external_dependencies_count_option": "Foreign Powers Beyond the Sands", "no_stats_selected": "No omens were heeded. The analysis fades into the sands.", "confirm_and_analyze": "Seal your fate and analyze", "checkbox_hint": "(Use space to mark, enter to proceed)" From 6fbc10665efd3648e3ec954ed1c0929c9b175374 Mon Sep 17 00:00:00 2001 From: ManfredHair Date: Tue, 29 Apr 2025 21:41:43 -0300 Subject: [PATCH 07/10] test external dependencies in py --- tests/analyze/test_external_dependencies.py | 123 ++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 tests/analyze/test_external_dependencies.py diff --git a/tests/analyze/test_external_dependencies.py b/tests/analyze/test_external_dependencies.py new file mode 100644 index 0000000..ae57d9f --- /dev/null +++ b/tests/analyze/test_external_dependencies.py @@ -0,0 +1,123 @@ +import os +import tempfile +from spice.analyzers.count_external_dependencies import count_external_dependencies + +# Get path to the sample files +SAMPLES_DIR = os.path.join(os.path.dirname(__file__), "..", "sample-code") +PY_SAMPLE = os.path.join(SAMPLES_DIR, "example.py") +JS_SAMPLE = os.path.join(SAMPLES_DIR, "example.js") +GO_SAMPLE = os.path.join(SAMPLES_DIR, "example.go") +RB_SAMPLE = os.path.join(SAMPLES_DIR, "example.rb") + +def test_count_dependencies_in_samples(): + """Test counting external dependencies in sample files.""" + # These test values may need to be adjusted based on actual sample file content + py_count = count_external_dependencies(PY_SAMPLE) + js_count = count_external_dependencies(JS_SAMPLE) + go_count = count_external_dependencies(GO_SAMPLE) + rb_count = count_external_dependencies(RB_SAMPLE) + + # The expected values should be updated to match actual sample file content + assert isinstance(py_count, int), "Python dependency count should be an integer" + assert isinstance(js_count, int), "JavaScript dependency count should be an integer" + assert isinstance(go_count, int), "Go dependency count should be an integer" + assert isinstance(rb_count, int), "Ruby dependency count should be an integer" + +def test_python_dependencies(): + """Test counting external dependencies in Python code.""" + # Create a temporary file with Python imports + with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as temp: + temp.write(b"import os\n") # Standard library (not counted) + temp.write(b"import sys\n") # Standard library (not counted) + temp.write(b"import numpy as np\n") # External library (counted) + temp.write(b"from django import forms\n") # External library (counted) + temp.write(b"import math\n") # Standard library (not counted) + temp_name = temp.name + + try: + count = count_external_dependencies(temp_name) + assert count == 2, f"Expected 2 external dependencies, got {count}" + finally: + os.unlink(temp_name) + +def test_javascript_dependencies(): + """Test counting external dependencies in JavaScript code.""" + # Create a temporary file with JavaScript imports + with tempfile.NamedTemporaryFile(suffix=".js", delete=False) as temp: + temp.write(b"const fs = require('fs');\n") # Standard library (not counted) + temp.write(b"const path = require('path');\n") # Standard library (not counted) + temp.write(b"const express = require('express');\n") # External library (counted) + temp.write(b"import React from 'react';\n") # External library (counted) + temp.write(b"import { useState } from 'react';\n") # Same as above, counts as 1 + temp.write(b"import './local-file.js';\n") # Relative import (not counted) + temp_name = temp.name + + try: + count = count_external_dependencies(temp_name) + assert count == 2, f"Expected 2 external dependencies, got {count}" + finally: + os.unlink(temp_name) + +def test_go_dependencies(): + """Test counting external dependencies in Go code.""" + # Create a temporary file with Go imports + with tempfile.NamedTemporaryFile(suffix=".go", delete=False) as temp: + temp.write(b'import "fmt"\n') # Standard library (not counted) + temp.write(b'import "os"\n') # Standard library (not counted) + temp.write(b'import "github.com/gorilla/mux"\n') # External library (counted) + temp.write(b'import "github.com/jinzhu/gorm"\n') # External library (counted) + temp.write(b'import (\n') + temp.write(b' "io"\n') # Standard library (not counted) + temp.write(b' "github.com/spf13/cobra"\n') # External library (counted) + temp.write(b')\n') + temp_name = temp.name + + try: + count = count_external_dependencies(temp_name) + assert count == 3, f"Expected 3 external dependencies, got {count}" + finally: + os.unlink(temp_name) + +def test_ruby_dependencies(): + """Test counting external dependencies in Ruby code.""" + # Create a temporary file with Ruby requires + with tempfile.NamedTemporaryFile(suffix=".rb", delete=False) as temp: + temp.write(b'require "json"\n') # Standard library (not counted) + temp.write(b'require "date"\n') # Standard library (not counted) + temp.write(b'require "rails"\n') # External library (counted) + temp.write(b'require "sinatra"\n') # External library (counted) + temp.write(b'require_relative "./local_file"\n') # Relative import (not counted) + temp.write(b'gem "activerecord"\n') # External gem (counted) + temp_name = temp.name + + try: + count = count_external_dependencies(temp_name) + assert count == 3, f"Expected 3 external dependencies, got {count}" + finally: + os.unlink(temp_name) + +def test_empty_file(): + """Test counting external dependencies in an empty file.""" + with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as temp: + temp_name = temp.name + + try: + count = count_external_dependencies(temp_name) + assert count == 0, f"Expected 0 external dependencies in empty file, got {count}" + finally: + os.unlink(temp_name) + +def test_file_with_no_dependencies(): + """Test counting external dependencies in a file with code but no imports.""" + with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as temp: + temp.write(b"def hello():\n") + temp.write(b" print('Hello, world!')\n") + temp.write(b"\n") + temp.write(b"hello()\n") + temp_name = temp.name + + try: + count = count_external_dependencies(temp_name) + assert count == 0, f"Expected 0 external dependencies, got {count}" + finally: + os.unlink(temp_name) \ No newline at end of file From 4d699b20a6f734b7e4c42bf6bc3a90d173c44e4c Mon Sep 17 00:00:00 2001 From: ManfredHair Date: Tue, 29 Apr 2025 21:41:50 -0300 Subject: [PATCH 08/10] test external dependencies in py json --- tests/analyze/test_analyze_json_python.py | 37 +++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/analyze/test_analyze_json_python.py b/tests/analyze/test_analyze_json_python.py index 8eac2aa..04e249e 100644 --- a/tests/analyze/test_analyze_json_python.py +++ b/tests/analyze/test_analyze_json_python.py @@ -2,6 +2,7 @@ import os from typer.testing import CliRunner from cli.main import app +from cli.commands.analyze import analyze_to_json # Setup test runner runner = CliRunner() @@ -9,6 +10,10 @@ # Get the absolute path to the sample file SAMPLE_FILE_PATH = os.path.join(os.path.dirname(__file__), "..", "sample-code", "example.py") +# Get path to the sample files +SAMPLES_DIR = os.path.join(os.path.dirname(__file__), "..", "sample-code") +PY_SAMPLE = os.path.join(SAMPLES_DIR, "example.py") + def test_analyze_command_with_json_flag(): """Test the analyze command with the --json flag for Python""" # Run the command with --json flag @@ -61,3 +66,35 @@ def test_analyze_command_with_nonexistent_file(): # Check if the output contains an error message assert "error" in output + +def test_analyze_json_python(): + result = analyze_to_json(PY_SAMPLE, ["line_count", "function_count", "comment_line_count", "blank_line_count", "inline_comment_count", "external_dependencies_count"]) + + json_obj = json.loads(result) + assert isinstance(json_obj, dict) + assert PY_SAMPLE in json_obj + + stats = json_obj[PY_SAMPLE] + assert isinstance(stats, dict) + assert "line_count" in stats + assert "function_count" in stats + assert "comment_line_count" in stats + assert "blank_line_count" in stats + assert "inline_comment_count" in stats + assert "external_dependencies_count" in stats + + assert isinstance(stats["line_count"], int) + assert isinstance(stats["function_count"], int) + assert isinstance(stats["comment_line_count"], int) + assert isinstance(stats["blank_line_count"], int) + assert isinstance(stats["inline_comment_count"], int) + assert isinstance(stats["external_dependencies_count"], int) + + assert stats["line_count"] > 0 + assert stats["function_count"] >= 0 + assert stats["comment_line_count"] >= 0 + assert stats["blank_line_count"] >= 0 + assert stats["inline_comment_count"] == 2 + # This assertion depends on the content of example.py + # If the sample file has external dependencies, this should be adjusted accordingly + assert isinstance(stats["external_dependencies_count"], int) From b4abb3ecabb3c96f8fb8ecd17c7ebd03da53c355 Mon Sep 17 00:00:00 2001 From: ManfredHair Date: Mon, 5 May 2025 20:02:08 -0300 Subject: [PATCH 09/10] fix? --- cli/commands/analyze.py | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/cli/commands/analyze.py b/cli/commands/analyze.py index 6808d3c..8d13ec7 100644 --- a/cli/commands/analyze.py +++ b/cli/commands/analyze.py @@ -4,6 +4,33 @@ from spice.analyze import analyze_file +def analyze_to_dict(file, selected_stats=None): + """ + Analyze the given file and return results as a dictionary. + This function is used by tests and the JSON output functionality. + + Args: + file (str): Path to the file to analyze + selected_stats (list): List of stats to include in analysis + + Returns: + dict: Analysis results in dictionary format + """ + # If no stats specified, use all available stats + if selected_stats is None: + selected_stats = [ + "line_count", + "function_count", + "comment_line_count", + "inline_comment_count", + "external_dependencies_count", + "indentation_level" + ] + + # Get analysis results from analyze_file + return analyze_file(file, selected_stats=selected_stats) + + def analyze_command(file, all, json_output, LANG_FILE): """ Analyze the given file. @@ -70,8 +97,8 @@ def analyze_command(file, all, json_output, LANG_FILE): if not json_output: print(f"{messages.get('analyzing_file', 'Analyzing file')}: {file}") - # get analysis results from analyze_file - results = analyze_file(file, selected_stats=selected_stat_keys) + # get analysis results using analyze_to_dict function + results = analyze_to_dict(file, selected_stats=selected_stat_keys) # output in JSON format if flag if json_output: @@ -93,4 +120,4 @@ def analyze_command(file, all, json_output, LANG_FILE): error_msg = str(e).replace('\n', ' ') print(json.dumps({"error": error_msg})) else: - print(f"{messages.get('error', 'Error')}: {e}") + print(f"{messages.get('error', 'Error')}: {e}") \ No newline at end of file From 83a5e79f010298edb7537d63c0ac318ff21265d2 Mon Sep 17 00:00:00 2001 From: ManfredHair Date: Mon, 5 May 2025 20:08:01 -0300 Subject: [PATCH 10/10] hopefully fixed now i cant keep fixing things forever --- tests/analyze/test_analyze_json_python.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/analyze/test_analyze_json_python.py b/tests/analyze/test_analyze_json_python.py index 04e249e..75d308c 100644 --- a/tests/analyze/test_analyze_json_python.py +++ b/tests/analyze/test_analyze_json_python.py @@ -2,7 +2,7 @@ import os from typer.testing import CliRunner from cli.main import app -from cli.commands.analyze import analyze_to_json +from cli.commands.analyze import analyze_to_dict # Setup test runner runner = CliRunner()