Skip to main content

double_o/pattern/
builtins.rs

1use regex::Regex;
2
3use super::{FailurePattern, FailureStrategy, Pattern, SuccessPattern};
4
5/// Built-in pattern definitions for common commands.
6pub fn builtin_patterns() -> Vec<Pattern> {
7    vec![
8        // pytest
9        Pattern {
10            command_match: Regex::new(r"(?:^|\b)pytest\b")
11                .expect("valid regex: pytest command_match"),
12            success: Some(SuccessPattern {
13                pattern: Regex::new(r"(?P<passed>\d+) passed.*in (?P<time>[\d.]+)s")
14                    .expect("valid regex: pytest success pattern"),
15                summary: "{passed} passed, {time}s".into(),
16            }),
17            failure: Some(FailurePattern {
18                strategy: FailureStrategy::Tail { lines: 30 },
19            }),
20        },
21        // cargo test
22        Pattern {
23            command_match: Regex::new(r"\bcargo\s+test\b")
24                .expect("valid regex: cargo test command_match"),
25            success: Some(SuccessPattern {
26                pattern: Regex::new(
27                    r"test result: ok\. (?P<passed>\d+) passed; (?P<failed>\d+) failed.*finished in (?P<time>[\d.]+)s",
28                )
29                .expect("valid regex: cargo test success pattern"),
30                summary: "{passed} passed, {time}s".into(),
31            }),
32            failure: Some(FailurePattern {
33                strategy: FailureStrategy::Tail { lines: 40 },
34            }),
35        },
36        // go test
37        Pattern {
38            command_match: Regex::new(r"\bgo\s+test\b")
39                .expect("valid regex: go test command_match"),
40            success: Some(SuccessPattern {
41                pattern: Regex::new(r"ok\s+\S+\s+(?P<time>[\d.]+)s")
42                    .expect("valid regex: go test success pattern"),
43                summary: "ok ({time}s)".into(),
44            }),
45            failure: Some(FailurePattern {
46                strategy: FailureStrategy::Tail { lines: 30 },
47            }),
48        },
49        // jest / vitest
50        Pattern {
51            command_match: Regex::new(r"\b(?:jest|vitest|npx\s+(?:jest|vitest))\b")
52                .expect("valid regex: jest/vitest command_match"),
53            success: Some(SuccessPattern {
54                pattern: Regex::new(
55                    r"Tests:\s+(?P<passed>\d+) passed.*Time:\s+(?P<time>[\d.]+)\s*s",
56                )
57                .expect("valid regex: jest/vitest success pattern"),
58                summary: "{passed} passed, {time}s".into(),
59            }),
60            failure: Some(FailurePattern {
61                strategy: FailureStrategy::Tail { lines: 30 },
62            }),
63        },
64        // ruff
65        Pattern {
66            command_match: Regex::new(r"\bruff\s+check\b")
67                .expect("valid regex: ruff check command_match"),
68            success: Some(SuccessPattern {
69                pattern: Regex::new(r"All checks passed")
70                    .expect("valid regex: ruff check success pattern"),
71                summary: String::new(), // empty = quiet success
72            }),
73            failure: None, // show all violations
74        },
75        // eslint
76        Pattern {
77            command_match: Regex::new(r"\beslint\b")
78                .expect("valid regex: eslint command_match"),
79            success: Some(SuccessPattern {
80                pattern: Regex::new(r"(?s).*")
81                    .expect("valid regex: eslint success pattern (always matches)"),
82                summary: String::new(),
83            }),
84            failure: None,
85        },
86        // cargo build
87        Pattern {
88            command_match: Regex::new(r"\bcargo\s+build\b")
89                .expect("valid regex: cargo build command_match"),
90            success: Some(SuccessPattern {
91                pattern: Regex::new(r"(?s).*")
92                    .expect("valid regex: cargo build success pattern (always matches)"),
93                summary: String::new(),
94            }),
95            failure: Some(FailurePattern {
96                strategy: FailureStrategy::Head { lines: 20 },
97            }),
98        },
99        // go build
100        Pattern {
101            command_match: Regex::new(r"\bgo\s+build\b")
102                .expect("valid regex: go build command_match"),
103            success: Some(SuccessPattern {
104                pattern: Regex::new(r"(?s).*")
105                    .expect("valid regex: go build success pattern (always matches)"),
106                summary: String::new(),
107            }),
108            failure: Some(FailurePattern {
109                strategy: FailureStrategy::Head { lines: 20 },
110            }),
111        },
112        // tsc
113        Pattern {
114            command_match: Regex::new(r"\btsc\b")
115                .expect("valid regex: tsc command_match"),
116            success: Some(SuccessPattern {
117                pattern: Regex::new(r"(?s).*")
118                    .expect("valid regex: tsc success pattern (always matches)"),
119                summary: String::new(),
120            }),
121            failure: Some(FailurePattern {
122                strategy: FailureStrategy::Head { lines: 20 },
123            }),
124        },
125        // cargo clippy
126        Pattern {
127            command_match: Regex::new(r"\bcargo\s+clippy\b")
128                .expect("valid regex: cargo clippy command_match"),
129            success: Some(SuccessPattern {
130                pattern: Regex::new(r"(?s).*")
131                    .expect("valid regex: cargo clippy success pattern (always matches)"),
132                summary: String::new(),
133            }),
134            failure: None,
135        },
136    ]
137}