Skip to content

Commit cdbdcef

Browse files
committed
0.9.1
1 parent bc587f4 commit cdbdcef

File tree

4 files changed

+13
-160
lines changed

4 files changed

+13
-160
lines changed

codestate/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.9.0'
1+
__version__ = '0.9.1'

codestate/cli.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010
from .visualizer import ascii_bar_chart, print_comment_density, html_report, markdown_report, ascii_pie_chart, print_ascii_tree, ascii_complexity_heatmap, generate_markdown_summary, print_table, csv_report, generate_mermaid_structure, generate_lang_card_svg, generate_sustainability_badge_svg
1111
from . import __version__
1212

13+
# 在 main() 開頭加一個全域變數
14+
PRINT_FORCE_PLAIN = False
15+
1316
def main():
17+
global PRINT_FORCE_PLAIN
1418
import time
1519
if '--cache' in sys.argv:
1620
main._cache_start_time = time.time()
@@ -354,6 +358,7 @@ class Dummy:
354358
output_file.write(f'CodeState CLI Test Output\n')
355359
output_file.write(f'Start time: {time.strftime("%Y-%m-%d %H:%M:%S")}\n')
356360
output_file.write(f'Total commands: {total}\n\n')
361+
PRINT_FORCE_PLAIN = True
357362
for idx, cmd in enumerate(commands, 1):
358363
try:
359364
cmd_start = time.time()
@@ -669,7 +674,7 @@ class Dummy:
669674
# 依照 size 由大到小排序
670675
file_details = sorted(file_details, key=lambda x: x.get('size', 0), reverse=True)
671676
headers = ["path", "ext", "size", "total_lines", "comment_lines", "function_count"]
672-
print_table(file_details, headers=headers, title="File Sizes and Stats")
677+
print_table(file_details, headers=headers, title="File Sizes and Stats:")
673678
return
674679

675680
if args.trend:

codestate/visualizer.py

Lines changed: 4 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,6 @@
66
import csv
77
import io
88
import re
9-
# 加入 colorama 支援
10-
try:
11-
from colorama import Fore, Style, init as colorama_init
12-
colorama_init()
13-
COLORAMA = True
14-
except ImportError:
15-
COLORAMA = False
16-
class Dummy:
17-
RESET = ''
18-
RED = ''
19-
GREEN = ''
20-
YELLOW = ''
21-
BLUE = ''
22-
CYAN = ''
23-
WHITE = ''
24-
LIGHTBLACK_EX = ''
25-
Fore = Style = Dummy()
26-
27-
# rich 支援
28-
try:
29-
from rich.console import Console
30-
from rich.table import Table
31-
from rich import box as rich_box
32-
RICH = True
33-
_console = Console()
34-
except ImportError:
35-
RICH = False
369

3710
def ascii_bar_chart(data, value_key, label_key='ext', width=40, title=None):
3811
"""
@@ -225,73 +198,8 @@ def format_size(num_bytes):
225198

226199
def print_table(rows, headers=None, title=None):
227200
"""
228-
Print a list of dicts as a pretty aligned table. 若有 rich 則用 rich.Table。
201+
Print a list of dicts as a pretty aligned table.
229202
"""
230-
rows = [r for r in rows if r is not None]
231-
if not rows:
232-
print("No data to display.")
233-
return
234-
if headers is None:
235-
headers = list(rows[0].keys())
236-
# rich table
237-
if RICH:
238-
table = Table(title=title, box=rich_box.SIMPLE_HEAVY, show_lines=False, expand=True)
239-
for h in headers:
240-
# 每欄固定最大寬度,且不自動換行,超過用 ...
241-
table.add_column(str(h), style="cyan", overflow="ellipsis", no_wrap=True, max_width=18)
242-
for row in rows:
243-
row_data = []
244-
for h in headers:
245-
v = row.get(h, '')
246-
# 根據欄位自動上色
247-
if isinstance(v, float):
248-
v = f"{v:.1f}"
249-
vstr = str(v)
250-
# 數值欄位
251-
if h in ('total_lines', 'lines', 'size', 'code_lines', 'covered', 'changes'):
252-
try:
253-
num = float(str(vstr).replace(',', '').replace(' KB','').replace(' MB','').replace(' GB',''))
254-
if num >= 1000:
255-
vstr = f"[green]{vstr}[/green]"
256-
elif num >= 100:
257-
vstr = f"[yellow]{vstr}[/yellow]"
258-
else:
259-
vstr = f"[grey50]{vstr}[/grey50]"
260-
except Exception:
261-
pass
262-
elif 'percent' in h or '%' in vstr:
263-
try:
264-
num = float(vstr.replace('%','').replace(' ','').replace('(','').replace(')',''))
265-
if num >= 50:
266-
vstr = f"[green]{vstr}[/green]"
267-
elif num >= 10:
268-
vstr = f"[yellow]{vstr}[/yellow]"
269-
else:
270-
vstr = f"[grey50]{vstr}[/grey50]"
271-
except Exception:
272-
pass
273-
elif 'complexity' in h:
274-
try:
275-
num = float(vstr)
276-
if num >= 10:
277-
vstr = f"[red]{vstr}[/red]"
278-
elif num >= 3:
279-
vstr = f"[yellow]{vstr}[/yellow]"
280-
else:
281-
vstr = f"[green]{vstr}[/green]"
282-
except Exception:
283-
pass
284-
elif h in ('path', 'file', 'ext'):
285-
vstr = f"[cyan]{vstr}[/cyan]"
286-
elif h in ('reasons', 'desc', 'type') and vstr:
287-
vstr = f"[yellow]{vstr}[/yellow]"
288-
elif h == 'author' and row.get('workload_percent','').endswith('%') and float(row.get('workload_percent','0').replace('%','')) >= 50:
289-
vstr = f"[green]{vstr}[/green]"
290-
row_data.append(vstr)
291-
table.add_row(*row_data)
292-
_console.print(table)
293-
return
294-
# fallback: colorama/純文字
295203
# 過濾掉 None
296204
rows = [r for r in rows if r is not None]
297205
if not rows:
@@ -339,74 +247,14 @@ def print_table(rows, headers=None, title=None):
339247
formatted_rows.append(new_row)
340248
col_widths = [max(len(str(h)), max(len(str(row.get(h, ''))) for row in formatted_rows)) for h in headers]
341249
if title:
342-
if COLORAMA:
343-
print(Fore.BLUE + f"\n{title}" + Style.RESET_ALL)
344-
else:
345-
print(f"\n{title}")
250+
print(f"\n{title}")
346251
# Print header
347-
if COLORAMA:
348-
header_line = ' | '.join(Fore.CYAN + str(h).ljust(w) + Style.RESET_ALL for h, w in zip(headers, col_widths))
349-
else:
350-
header_line = ' | '.join(str(h).ljust(w) for h, w in zip(headers, col_widths))
252+
header_line = ' | '.join(str(h).ljust(w) for h, w in zip(headers, col_widths))
351253
print(header_line)
352254
print('-+-'.join('-'*w for w in col_widths))
353255
# Print rows
354256
for row in formatted_rows:
355-
colored_cells = []
356-
for h, w in zip(headers, col_widths):
357-
v = str(row.get(h, ''))
358-
# 根據欄位自動上色
359-
if COLORAMA:
360-
# 數值欄位
361-
if h in ('total_lines', 'lines', 'size', 'code_lines', 'covered', 'changes'):
362-
try:
363-
num = float(v.replace(',', '').replace(' KB','').replace(' MB','').replace(' GB',''))
364-
if num >= 1000:
365-
color = Fore.GREEN
366-
elif num >= 100:
367-
color = Fore.YELLOW
368-
else:
369-
color = Fore.LIGHTBLACK_EX
370-
v = color + v + Style.RESET_ALL
371-
except Exception:
372-
pass
373-
# 百分比欄位
374-
elif 'percent' in h or '%' in v:
375-
try:
376-
num = float(v.replace('%','').replace(' ','').replace('(','').replace(')',''))
377-
if num >= 50:
378-
color = Fore.GREEN
379-
elif num >= 10:
380-
color = Fore.YELLOW
381-
else:
382-
color = Fore.LIGHTBLACK_EX
383-
v = color + v + Style.RESET_ALL
384-
except Exception:
385-
pass
386-
# 複雜度欄位
387-
elif 'complexity' in h:
388-
try:
389-
num = float(v)
390-
if num >= 10:
391-
color = Fore.RED
392-
elif num >= 3:
393-
color = Fore.YELLOW
394-
else:
395-
color = Fore.GREEN
396-
v = color + v + Style.RESET_ALL
397-
except Exception:
398-
pass
399-
# 路徑/檔名
400-
elif h in ('path', 'file', 'ext'):
401-
v = Fore.CYAN + v + Style.RESET_ALL
402-
# 警告/建議/違規
403-
elif h in ('reasons', 'desc', 'type') and v:
404-
v = Fore.YELLOW + v + Style.RESET_ALL
405-
# 主要作者
406-
elif h == 'author' and row.get('workload_percent','').endswith('%') and float(row.get('workload_percent','0').replace('%','')) >= 50:
407-
v = Fore.GREEN + v + Style.RESET_ALL
408-
colored_cells.append(v.ljust(w))
409-
print(' | '.join(colored_cells))
257+
print(' | '.join(str(row.get(h, '')).ljust(w) for h, w in zip(headers, col_widths)))
410258

411259
def csv_report(data, headers=None):
412260
"""

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
setup(
44
name='codestate',
5-
version='0.9.0',
5+
version='0.9.1',
66
description='A CLI tool for codebase statistics and ASCII visualization',
77
author='Henry Lok',
88
packages=find_packages(),
9-
install_requires=['pathspec', 'openpyxl', 'rich'],
9+
install_requires=['pathspec', 'openpyxl'],
1010
entry_points={
1111
'console_scripts': [
1212
'codestate=codestate.cli:main', # This entry point allows users to run `codestate` in the terminal after installation.

0 commit comments

Comments
 (0)