Spaces:
Sleeping
Sleeping
File size: 2,145 Bytes
f4dcf31 f974243 f4dcf31 f974243 f4dcf31 f974243 f4dcf31 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | """
Free-form command parser for the CI/CD Doctor environment.
Converts raw command strings into structured ParsedCommand objects.
"""
import re
from dataclasses import dataclass
from typing import Optional
@dataclass
class ParsedCommand:
type: str # "cat" | "echo_append" | "sed" | "pipeline_run" | "pipeline_logs" | "pipeline_status" | "diagnose" | "unknown"
filename: Optional[str] = None
content: Optional[str] = None # for echo >>
pattern: Optional[str] = None # for sed: old value
replacement: Optional[str] = None # for sed: new value
stage: Optional[str] = None
diagnosis: Optional[str] = None # for diagnose: agent's theory about the bug
def parse_command(command: str) -> ParsedCommand:
command = command.strip()
for sep in ["&&", ";"]:
if sep in command:
command = command.split(sep)[0].strip()
break
m = re.match(r"cat\s+(.+)", command)
if m:
return ParsedCommand(type="cat", filename=m.group(1).strip())
m = re.match(r'echo\s+([\'"])(.*?)\1\s*>>\s*(\S+)', command, re.DOTALL)
if m:
return ParsedCommand(
type="echo_append",
content=m.group(2),
filename=m.group(3),
)
# Example supported: sed -i 's/old/new/g' file OR sed -i "s|old|new|" file
m = re.match(
r"sed\s+-i\s+([\'\"]?)s(.)(.+?)\2(.*?)\2([g]*)\1\s+(\S+)",
command,
)
if m:
return ParsedCommand(
type="sed",
pattern=m.group(3),
replacement=m.group(4),
filename=m.group(6),
)
if re.fullmatch(r"pipeline\s+run", command):
return ParsedCommand(type="pipeline_run")
m = re.match(r"pipeline\s+logs(?:\s+(\S+))?\s*$", command)
if m:
return ParsedCommand(type="pipeline_logs", stage=m.group(1))
if re.fullmatch(r"pipeline\s+status", command):
return ParsedCommand(type="pipeline_status")
m = re.match(r'diagnose\s+([\'"])(.*?)\1\s*$', command, re.DOTALL)
if m:
return ParsedCommand(type="diagnose", diagnosis=m.group(2))
return ParsedCommand(type="unknown")
|