|
1 | 1 | import os
|
| 2 | +import re |
| 3 | +from typing import List, Tuple |
2 | 4 | import sublime
|
3 | 5 | from sublime import Window
|
4 | 6 | from ..settings import PyRockSettings
|
@@ -33,35 +35,76 @@ def _get_indexer_script_path(self):
|
33 | 35 | def _is_indexing_needed(self) -> bool:
|
34 | 36 | file_path = os.path.join(PyRockConstants.INDEX_CACHE_DIRECTORY, PyRockConstants.IMPORT_INDEX_FILE_NAME)
|
35 | 37 | return os.path.exists(file_path)
|
36 |
| - |
37 |
| - def _run_import_indexer(self, window: Window, indexer_command: str): |
38 |
| - process = subprocess.Popen( |
39 |
| - indexer_command, |
40 |
| - shell=True, |
41 |
| - stdout=subprocess.PIPE, |
42 |
| - ) |
43 | 38 |
|
| 39 | + def _track_indexer_progress(self, window: Window, process: subprocess.Popen) -> bool: |
44 | 40 | start_time = time.perf_counter()
|
45 |
| - |
| 41 | + script_success: bool = False |
| 42 | + log_errors: bool = False |
46 | 43 | # Progress tracker
|
47 | 44 | for line in iter(process.stdout.readline, ""):
|
48 |
| - progress = line.decode('utf-8').strip() |
| 45 | + output = line.decode('utf-8').strip() |
49 | 46 | # Kill process after 20 sec
|
50 | 47 | if (time.perf_counter() - start_time) > 20:
|
51 |
| - logger.warning(f"Indexing stopped due to timeout at {progress}%") |
| 48 | + error_reason = f"Indexing stopped due to timeout at {output}%" |
| 49 | + logger.warning(error_reason) |
| 50 | + self._command_error_evidence.append(error_reason) |
52 | 51 | process.terminate()
|
| 52 | + script_success = False |
53 | 53 | break
|
54 |
| - logger.debug(f"Indexing imports...{progress}%") |
55 |
| - window.status_message(f"Indexing imports...{progress}%") |
56 |
| - if "99" in str(line) or progress == "": |
| 54 | + |
| 55 | + if log_errors: |
| 56 | + # Collect error generated from script |
| 57 | + self._command_error_evidence.append(output) |
| 58 | + elif re.match(r"^([1-9]|[1-9][0-9]|100)$", output): |
| 59 | + logger.debug(f"Indexing imports...{output}%") |
| 60 | + window.status_message(f"Indexing imports...{output}%") |
| 61 | + if 95 <= int(output) <= 100: |
| 62 | + script_success = True |
| 63 | + elif "FAILED_INDEXING" in output: |
| 64 | + script_success = False |
| 65 | + log_errors = True |
| 66 | + |
| 67 | + if output == "" or output is None: |
57 | 68 | break
|
| 69 | + return script_success |
| 70 | + |
| 71 | + def _collect_cmd_error_output(self, process: subprocess.Popen): |
| 72 | + # Collect error generated from command |
| 73 | + for line in iter(process.stderr.readline, ""): |
| 74 | + output = line.decode('utf-8').strip() |
| 75 | + if len(output) == 0 or output == "" or output is None: |
| 76 | + break |
| 77 | + logger.debug(output) |
| 78 | + self._command_error_evidence.append(output) |
| 79 | + |
| 80 | + def _run_import_indexer(self, window: Window, indexer_command: str) -> Tuple[bool, str]: |
| 81 | + process = subprocess.Popen( |
| 82 | + indexer_command, |
| 83 | + shell=True, |
| 84 | + stdout=subprocess.PIPE, |
| 85 | + stderr=subprocess.PIPE, |
| 86 | + ) |
| 87 | + message: str = "" |
| 88 | + script_success: bool = self._track_indexer_progress(window, process) |
| 89 | + |
| 90 | + if not script_success: |
| 91 | + if len(self._command_error_evidence) > 0: |
| 92 | + logger.error("\n".join(self._command_error_evidence)) |
| 93 | + else: |
| 94 | + self._collect_cmd_error_output(process) |
| 95 | + message = "\n".join(self._command_error_evidence) |
| 96 | + logger.error(message) |
| 97 | + |
| 98 | + return script_success, message |
58 | 99 |
|
59 | 100 | def _run_indexer(self, window: Window, force=False):
|
60 | 101 | if self._is_indexing_needed() and not force:
|
61 | 102 | logger.debug("Indexing not needed")
|
62 | 103 | window.status_message("Indexing not needed")
|
63 | 104 | return
|
64 | 105 |
|
| 106 | + self._command_error_evidence: List[str] = [] |
| 107 | + |
65 | 108 | self._generate_serialized_settings()
|
66 | 109 |
|
67 | 110 | window.set_status_bar_visible(True)
|
@@ -114,6 +157,10 @@ def _run_indexer(self, window: Window, force=False):
|
114 | 157 | )
|
115 | 158 |
|
116 | 159 | logger.debug(f"Import shell command using: {import_command}")
|
117 |
| - self._run_import_indexer(window, import_command) |
| 160 | + success, message = self._run_import_indexer(window, import_command) |
| 161 | + logger.debug(f"Indexing result: {success}") |
118 | 162 |
|
119 |
| - window.status_message("Finished imports...") |
| 163 | + if success: |
| 164 | + window.status_message("Finished imports...") |
| 165 | + else: |
| 166 | + sublime.error_message(f"Indexing Failed\n\n{message}") |
0 commit comments