codespine 0.5.9__tar.gz → 0.5.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codespine-0.5.9 → codespine-0.5.10}/PKG-INFO +1 -1
- {codespine-0.5.9 → codespine-0.5.10}/codespine/__init__.py +1 -1
- {codespine-0.5.9 → codespine-0.5.10}/codespine/cli.py +28 -8
- {codespine-0.5.9 → codespine-0.5.10}/codespine.egg-info/PKG-INFO +1 -1
- {codespine-0.5.9 → codespine-0.5.10}/pyproject.toml +1 -1
- {codespine-0.5.9 → codespine-0.5.10}/LICENSE +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/README.md +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/analysis/__init__.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/analysis/community.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/analysis/context.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/analysis/coupling.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/analysis/crossmodule.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/analysis/deadcode.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/analysis/flow.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/analysis/impact.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/config.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/db/__init__.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/db/schema.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/db/store.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/diff/__init__.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/diff/branch_diff.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/indexer/__init__.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/indexer/call_resolver.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/indexer/engine.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/indexer/java_parser.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/indexer/symbol_builder.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/mcp/__init__.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/mcp/server.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/noise/__init__.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/noise/blocklist.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/overlay/__init__.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/overlay/git_state.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/overlay/merge.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/overlay/store.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/search/__init__.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/search/bm25.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/search/fuzzy.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/search/hybrid.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/search/rrf.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/search/vector.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/watch/__init__.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine/watch/watcher.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine.egg-info/SOURCES.txt +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine.egg-info/dependency_links.txt +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine.egg-info/entry_points.txt +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine.egg-info/requires.txt +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/codespine.egg-info/top_level.txt +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/gindex.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/setup.cfg +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/tests/test_branch_diff_normalize.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/tests/test_call_resolver.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/tests/test_community_detection.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/tests/test_deadcode.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/tests/test_index_and_hybrid.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/tests/test_java_parser.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/tests/test_multimodule_index.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/tests/test_overlay.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/tests/test_search_ranking.py +0 -0
- {codespine-0.5.9 → codespine-0.5.10}/tests/test_store_recovery.py +0 -0
|
@@ -77,6 +77,19 @@ def _dead_result_count(dead_result: list[dict] | None) -> int:
|
|
|
77
77
|
return sum(1 for item in dead_result if isinstance(item, dict) and "_stats" not in item)
|
|
78
78
|
|
|
79
79
|
|
|
80
|
+
def _bar(done: int, total: int, width: int = 20) -> str:
|
|
81
|
+
"""Return an ASCII progress bar like [████████░░░░] 40%."""
|
|
82
|
+
if total <= 0:
|
|
83
|
+
return f"[{'░' * width}] ---%"
|
|
84
|
+
frac = min(done / total, 1.0)
|
|
85
|
+
filled = int(width * frac)
|
|
86
|
+
return f"[{'█' * filled}{'░' * (width - filled)}] {int(frac * 100):3d}%"
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _spinner_char() -> str:
|
|
90
|
+
return "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"[int(time.perf_counter() * 8) % 10]
|
|
91
|
+
|
|
92
|
+
|
|
80
93
|
@click.group()
|
|
81
94
|
def main() -> None:
|
|
82
95
|
"""CodeSpine CLI."""
|
|
@@ -141,7 +154,7 @@ def analyse(path: str, full: bool, deep: bool, embed: bool, allow_running: bool)
|
|
|
141
154
|
|
|
142
155
|
# Shared progress state (reset per module)
|
|
143
156
|
parse_state = {"shown": False, "indexed": 0, "total": 0, "last_ts": 0.0, "printed_zero": False}
|
|
144
|
-
call_state = {"shown": False, "count": 0, "last_ts": 0.0}
|
|
157
|
+
call_state = {"shown": False, "count": 0, "last_ts": 0.0, "started_at": 0.0}
|
|
145
158
|
|
|
146
159
|
def _reset_state() -> None:
|
|
147
160
|
for k in list(parse_state):
|
|
@@ -171,22 +184,28 @@ def analyse(path: str, full: bool, deep: bool, embed: bool, allow_running: bool)
|
|
|
171
184
|
if total == 0:
|
|
172
185
|
return
|
|
173
186
|
if indexed == total or (now - parse_state["last_ts"]) >= 0.2:
|
|
174
|
-
click.echo(f"\rParsing code...
|
|
187
|
+
click.echo(f"\rParsing code... {_bar(indexed, total)} {indexed}/{total} ", nl=False)
|
|
175
188
|
parse_state["shown"] = True
|
|
176
189
|
parse_state["last_ts"] = now
|
|
177
190
|
return
|
|
178
191
|
if event == "resolve_calls_start" and parse_state["shown"]:
|
|
179
192
|
click.echo()
|
|
180
193
|
parse_state["shown"] = False
|
|
181
|
-
|
|
194
|
+
call_state["started_at"] = now
|
|
195
|
+
_phase("Tracing calls...", "starting...")
|
|
182
196
|
return
|
|
183
197
|
if event == "resolve_calls_start":
|
|
184
|
-
|
|
198
|
+
call_state["started_at"] = now
|
|
199
|
+
_phase("Tracing calls...", "starting...")
|
|
185
200
|
return
|
|
186
201
|
if event == "resolve_calls_progress":
|
|
187
202
|
call_state["count"] = int(payload.get("calls_resolved", 0))
|
|
188
203
|
if (now - call_state["last_ts"]) >= 0.25:
|
|
189
|
-
|
|
204
|
+
elapsed_s = now - call_state["started_at"]
|
|
205
|
+
click.echo(
|
|
206
|
+
f"\r{_spinner_char()} Tracing calls... {call_state['count']:>6} resolved {elapsed_s:.1f}s ",
|
|
207
|
+
nl=False,
|
|
208
|
+
)
|
|
190
209
|
call_state["shown"] = True
|
|
191
210
|
call_state["last_ts"] = now
|
|
192
211
|
return
|
|
@@ -194,7 +213,8 @@ def analyse(path: str, full: bool, deep: bool, embed: bool, allow_running: bool)
|
|
|
194
213
|
if call_state["shown"]:
|
|
195
214
|
click.echo()
|
|
196
215
|
call_state["shown"] = False
|
|
197
|
-
|
|
216
|
+
elapsed_s = (now - call_state["started_at"]) if call_state["started_at"] else 0.0
|
|
217
|
+
_phase("Tracing calls...", f"{int(payload.get('calls_resolved', 0))} calls resolved ({elapsed_s:.1f}s)")
|
|
198
218
|
return
|
|
199
219
|
if event == "resolve_types_start":
|
|
200
220
|
_phase("Analyzing types...", "running")
|
|
@@ -226,11 +246,11 @@ def analyse(path: str, full: bool, deep: bool, embed: bool, allow_running: bool)
|
|
|
226
246
|
# ── Helper for in-place progress updates ────────────────────────────
|
|
227
247
|
def _live_phase(label: str, status: str) -> None:
|
|
228
248
|
"""Overwrite the current line with a status update."""
|
|
229
|
-
click.echo(f"\r{label:<
|
|
249
|
+
click.echo(f"\r{_spinner_char()} {label:<28} {status:<48}", nl=False)
|
|
230
250
|
|
|
231
251
|
def _finish_phase(label: str, result: str) -> None:
|
|
232
252
|
"""Finalise an in-place phase line and move to the next line."""
|
|
233
|
-
click.echo(f"\r{label:<
|
|
253
|
+
click.echo(f"\r✓ {label:<28} {result:<48}")
|
|
234
254
|
|
|
235
255
|
# ── Cross-module call linking ──────────────────────────────────────
|
|
236
256
|
if is_multi and len(modules_with_ids) > 1:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|