Handles running the external SCIP indexer binaries. Takes a project path and language, runs the appropriate CLI, and returns the path to the resulting index.scip file.
| 156 | |
| 157 | |
| 158 | class ScipIndexer: |
| 159 | """ |
| 160 | Handles running the external SCIP indexer binaries. |
| 161 | Takes a project path and language, runs the appropriate CLI, and |
| 162 | returns the path to the resulting index.scip file. |
| 163 | """ |
| 164 | |
| 165 | def run(self, project_path: Path, lang: str, output_dir: Path) -> Optional[Path]: |
| 166 | """ |
| 167 | Run the SCIP indexer for `lang` on `project_path`. |
| 168 | Returns path to index.scip, or None if the indexer failed / is not installed. |
| 169 | """ |
| 170 | binary, expected_binary, install_hint, docker_image = self._get_binary(lang) |
| 171 | output_file = output_dir / "index.scip" |
| 172 | |
| 173 | if binary: |
| 174 | cmd = self._build_command(lang, binary, project_path, output_file, scratch_dir=output_dir) |
| 175 | if not cmd: |
| 176 | warning_logger(f"No SCIP command template defined for language: {lang}") |
| 177 | return None |
| 178 | |
| 179 | info_logger(f"Running local SCIP indexer: {' '.join(str(c) for c in cmd)}") |
| 180 | try: |
| 181 | result = subprocess.run( |
| 182 | cmd, |
| 183 | cwd=str(project_path), |
| 184 | capture_output=True, |
| 185 | text=True, |
| 186 | timeout=_resolve_scip_timeout(), |
| 187 | ) |
| 188 | if result.returncode == 0 and output_file.exists(): |
| 189 | info_logger(f"SCIP index written to {output_file}") |
| 190 | return output_file |
| 191 | warning_logger(f"Local SCIP indexer failed (code {result.returncode}). stderr: {result.stderr[:500]}") |
| 192 | except Exception as e: |
| 193 | warning_logger(f"Local SCIP indexer failed: {e}") |
| 194 | |
| 195 | # Fallback to Docker |
| 196 | if docker_image and shutil.which("docker"): |
| 197 | info_logger(f"Attempting SCIP indexing via Docker ({docker_image})...") |
| 198 | try: |
| 199 | # 1. Pre-run: for Go we often need 'go mod tidy' |
| 200 | if lang == "go": |
| 201 | info_logger("Running 'go mod tidy' inside container first...") |
| 202 | subprocess.run( |
| 203 | ["docker", "run", "--rm", "-v", f"{project_path.resolve()}:/src", "-w", "/src", docker_image, "go", "mod", "tidy"], |
| 204 | capture_output=True, timeout=120 |
| 205 | ) |
| 206 | |
| 207 | # 2. Run indexer |
| 208 | docker_cmd = [ |
| 209 | "docker", "run", "--rm", |
| 210 | "-v", f"{project_path.resolve()}:/src", |
| 211 | "-v", f"{output_dir.resolve()}:/out", |
| 212 | "-w", "/src", |
| 213 | docker_image, |
| 214 | ] |
| 215 |
no outgoing calls