feat: in-place per-file progress for classify, count, and large-file steps
This commit is contained in:
parent
bbaf387cb7
commit
206d2d34f6
3 changed files with 49 additions and 10 deletions
40
luminos.py
40
luminos.py
|
|
@ -3,8 +3,9 @@
|
|||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
from luminos_lib.tree import build_tree, render_tree
|
||||
from luminos_lib.filetypes import classify_files, summarize_categories
|
||||
|
|
@ -15,6 +16,28 @@ from luminos_lib.watch import watch_loop
|
|||
from luminos_lib.report import format_report
|
||||
|
||||
|
||||
def _progress(label):
|
||||
"""Return (on_file, finish) for in-place per-file progress on stderr.
|
||||
|
||||
on_file(path) overwrites the current line with the label and truncated path.
|
||||
finish() finalises the line with a newline.
|
||||
"""
|
||||
cols = shutil.get_terminal_size((80, 20)).columns
|
||||
prefix = f" [scan] {label}... "
|
||||
available = max(cols - len(prefix), 10)
|
||||
|
||||
def on_file(path):
|
||||
rel = os.path.relpath(path)
|
||||
if len(rel) > available:
|
||||
rel = "..." + rel[-(available - 3):]
|
||||
print(f"\r{prefix}{rel}\033[K", end="", file=sys.stderr, flush=True)
|
||||
|
||||
def finish():
|
||||
print(f"\r{prefix}done\033[K", file=sys.stderr, flush=True)
|
||||
|
||||
return on_file, finish
|
||||
|
||||
|
||||
def scan(target, depth=3, show_hidden=False):
|
||||
"""Run all analyses on the target directory and return a report dict."""
|
||||
report = {}
|
||||
|
|
@ -24,16 +47,21 @@ def scan(target, depth=3, show_hidden=False):
|
|||
report["tree"] = tree
|
||||
report["tree_rendered"] = render_tree(tree)
|
||||
|
||||
print(" [scan] Classifying files...", file=sys.stderr)
|
||||
classified = classify_files(target, show_hidden=show_hidden)
|
||||
on_file, finish = _progress("Classifying files")
|
||||
classified = classify_files(target, show_hidden=show_hidden, on_file=on_file)
|
||||
finish()
|
||||
report["file_categories"] = summarize_categories(classified)
|
||||
report["classified_files"] = classified
|
||||
|
||||
print(" [scan] Detecting languages and counting lines...", file=sys.stderr)
|
||||
languages, loc = detect_languages(classified)
|
||||
on_file, finish = _progress("Counting lines")
|
||||
languages, loc = detect_languages(classified, on_file=on_file)
|
||||
finish()
|
||||
report["languages"] = languages
|
||||
report["lines_of_code"] = loc
|
||||
report["large_files"] = find_large_files(classified)
|
||||
|
||||
on_file, finish = _progress("Checking for large files")
|
||||
report["large_files"] = find_large_files(classified, on_file=on_file)
|
||||
finish()
|
||||
|
||||
print(" [scan] Finding recently modified files...", file=sys.stderr)
|
||||
report["recent_files"] = find_recent_files(target, show_hidden=show_hidden)
|
||||
|
|
|
|||
|
|
@ -34,10 +34,11 @@ def _count_lines(filepath):
|
|||
return 0
|
||||
|
||||
|
||||
def detect_languages(classified_files):
|
||||
def detect_languages(classified_files, on_file=None):
|
||||
"""Detect languages present and count lines of code per language.
|
||||
|
||||
Returns (languages_set, loc_by_language).
|
||||
on_file(path) is called per source file, if provided.
|
||||
"""
|
||||
source_files = [f for f in classified_files if f["category"] == "source"]
|
||||
languages = set()
|
||||
|
|
@ -49,12 +50,17 @@ def detect_languages(classified_files):
|
|||
languages.add(lang)
|
||||
lines = _count_lines(f["path"])
|
||||
loc[lang] = loc.get(lang, 0) + lines
|
||||
if on_file:
|
||||
on_file(f["path"])
|
||||
|
||||
return sorted(languages), loc
|
||||
|
||||
|
||||
def find_large_files(classified_files):
|
||||
"""Find files that are unusually large (>1000 lines or >10MB)."""
|
||||
def find_large_files(classified_files, on_file=None):
|
||||
"""Find files that are unusually large (>1000 lines or >10MB).
|
||||
|
||||
on_file(path) is called per source file checked, if provided.
|
||||
"""
|
||||
source_files = [f for f in classified_files if f["category"] == "source"]
|
||||
large = []
|
||||
|
||||
|
|
@ -68,5 +74,7 @@ def find_large_files(classified_files):
|
|||
if reasons:
|
||||
large.append({"path": f["path"], "name": f["name"],
|
||||
"reasons": reasons})
|
||||
if on_file:
|
||||
on_file(f["path"])
|
||||
|
||||
return large
|
||||
|
|
|
|||
|
|
@ -86,10 +86,11 @@ def _classify_one(filepath):
|
|||
return "unknown", desc
|
||||
|
||||
|
||||
def classify_files(target, show_hidden=False):
|
||||
def classify_files(target, show_hidden=False, on_file=None):
|
||||
"""Walk the target directory and classify every file.
|
||||
|
||||
Returns a list of dicts: {path, name, category, size, description}.
|
||||
on_file(path) is called after each file is classified, if provided.
|
||||
"""
|
||||
results = []
|
||||
for root, dirs, files in os.walk(target):
|
||||
|
|
@ -112,6 +113,8 @@ def classify_files(target, show_hidden=False):
|
|||
"size": size,
|
||||
"description": desc,
|
||||
})
|
||||
if on_file:
|
||||
on_file(full)
|
||||
return results
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue