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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//! Hook events and dispatch for the plugin system.
use std::fmt;
use std::time::Duration;
/// Events that can trigger plugin hooks.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum HookEvent {
/// Before build starts
PreBuild,
/// After build completes
PostBuild,
/// Before tests run
PreTest,
/// After tests complete
PostTest,
/// Before run command
PreRun,
/// After run completes
PostRun,
/// Before clean
PreClean,
/// After clean completes
PostClean,
/// Before lock generation
PreLock,
/// After lock completes
PostLock,
/// Project initialization
Init,
}
impl HookEvent {
/// Get all hook events.
pub fn all() -> &'static [HookEvent] {
&[
HookEvent::PreBuild,
HookEvent::PostBuild,
HookEvent::PreTest,
HookEvent::PostTest,
HookEvent::PreRun,
HookEvent::PostRun,
HookEvent::PreClean,
HookEvent::PostClean,
HookEvent::PreLock,
HookEvent::PostLock,
HookEvent::Init,
]
}
/// Get the hook name as used in configuration.
pub fn config_key(&self) -> &'static str {
match self {
HookEvent::PreBuild => "pre_build",
HookEvent::PostBuild => "post_build",
HookEvent::PreTest => "pre_test",
HookEvent::PostTest => "post_test",
HookEvent::PreRun => "pre_run",
HookEvent::PostRun => "post_run",
HookEvent::PreClean => "pre_clean",
HookEvent::PostClean => "post_clean",
HookEvent::PreLock => "pre_lock",
HookEvent::PostLock => "post_lock",
HookEvent::Init => "init",
}
}
/// Get the Scheme function name for this hook.
pub fn scheme_function(&self) -> &'static str {
match self {
HookEvent::PreBuild => "pre-build-hook",
HookEvent::PostBuild => "post-build-hook",
HookEvent::PreTest => "pre-test-hook",
HookEvent::PostTest => "post-test-hook",
HookEvent::PreRun => "pre-run-hook",
HookEvent::PostRun => "post-run-hook",
HookEvent::PreClean => "pre-clean-hook",
HookEvent::PostClean => "post-clean-hook",
HookEvent::PreLock => "pre-lock-hook",
HookEvent::PostLock => "post-lock-hook",
HookEvent::Init => "init-hook",
}
}
/// Check if this is a "pre" event.
pub fn is_pre(&self) -> bool {
matches!(
self,
HookEvent::PreBuild
| HookEvent::PreTest
| HookEvent::PreRun
| HookEvent::PreClean
| HookEvent::PreLock
)
}
/// Check if this is a "post" event.
pub fn is_post(&self) -> bool {
matches!(
self,
HookEvent::PostBuild
| HookEvent::PostTest
| HookEvent::PostRun
| HookEvent::PostClean
| HookEvent::PostLock
)
}
}
impl fmt::Display for HookEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.config_key())
}
}
/// Result of running a hook.
#[derive(Debug, Clone)]
pub struct HookResult {
/// Whether the hook succeeded.
pub success: bool,
/// How long the hook took to run.
pub duration: Duration,
/// Output from the hook (if any).
pub output: Option<String>,
/// Error message if failed.
pub error: Option<String>,
}
impl HookResult {
/// Create a successful result.
pub fn success(duration: Duration) -> Self {
HookResult {
success: true,
duration,
output: None,
error: None,
}
}
/// Create a successful result with output.
pub fn success_with_output(duration: Duration, output: String) -> Self {
HookResult {
success: true,
duration,
output: Some(output),
error: None,
}
}
/// Create a failed result.
pub fn failure(duration: Duration, error: String) -> Self {
HookResult {
success: false,
duration,
output: None,
error: Some(error),
}
}
/// Create a skipped result (hook not defined).
pub fn skipped() -> Self {
HookResult {
success: true,
duration: Duration::ZERO,
output: None,
error: None,
}
}
}