Convert raw CLI targets into normalized selector specs. Each spec is a dict with: - raw: original user input - normalized: normalized repo-relative selector - kind: file | dir | glob | invalid
(targets: list[str] | None, repo_root: Path)
| 259 | |
| 260 | |
| 261 | def compile_target_specs(targets: list[str] | None, repo_root: Path) -> list[TargetSpec] | None: |
| 262 | """ |
| 263 | Convert raw CLI targets into normalized selector specs. |
| 264 | |
| 265 | Each spec is a dict with: |
| 266 | - raw: original user input |
| 267 | - normalized: normalized repo-relative selector |
| 268 | - kind: file | dir | glob | invalid |
| 269 | """ |
| 270 | if not targets: |
| 271 | return None |
| 272 | |
| 273 | specs: list[TargetSpec] = [] |
| 274 | |
| 275 | for raw in targets: |
| 276 | normalized = normalize_target_spec(raw, repo_root) |
| 277 | if not normalized: |
| 278 | specs.append({"raw": raw, "normalized": "", "kind": "invalid"}) |
| 279 | continue |
| 280 | |
| 281 | if any(ch in normalized for ch in GLOB_CHARS): |
| 282 | specs.append({"raw": raw, "normalized": normalized, "kind": "glob"}) |
| 283 | continue |
| 284 | |
| 285 | # Treat explicit trailing slash/backslash as directory intent |
| 286 | if raw.endswith(("/", "\\")): |
| 287 | specs.append({"raw": raw, "normalized": normalized, "kind": "dir"}) |
| 288 | continue |
| 289 | |
| 290 | candidate = Path(normalized) |
| 291 | abs_candidate = candidate if candidate.is_absolute() else (repo_root / candidate) |
| 292 | if abs_candidate.exists() and abs_candidate.is_dir(): |
| 293 | specs.append({"raw": raw, "normalized": normalized, "kind": "dir"}) |
| 294 | else: |
| 295 | specs.append({"raw": raw, "normalized": normalized, "kind": "file"}) |
| 296 | |
| 297 | return specs |
| 298 | |
| 299 | |
| 300 | def target_spec_matches_path(rel_path: str, spec: TargetSpec) -> bool: |
no test coverage detected