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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
use std::path::PathBuf;
use std::process::ExitStatus;
/// Error type for `treeboot-core` operations.
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// The current working directory could not be read.
#[error("failed to read current directory: {source}")]
CurrentDir {
/// Source I/O error.
#[source]
source: std::io::Error,
},
/// A filesystem path could not be normalized.
#[error("failed to normalize path {path:?}: {source}")]
NormalizePath {
/// Path that failed normalization.
path: PathBuf,
/// Source I/O error.
#[source]
source: std::io::Error,
},
/// The command was not run from a Git worktree.
#[error("not inside a Git worktree")]
NotGitWorktree,
/// A Git command could not be spawned.
#[error("failed to run {command}: {source}")]
GitIo {
/// Human-readable command label.
command: String,
/// Source I/O error.
#[source]
source: std::io::Error,
},
/// A Git command exited unsuccessfully.
#[error("{command} failed: {stderr}")]
GitFailed {
/// Human-readable command label.
command: String,
/// Standard error from Git.
stderr: String,
},
/// No root checkout path could be determined.
#[error("could not determine root checkout path")]
RootPathNotFound,
/// A specifically requested config file does not exist.
#[error("config file not found: {0:?}")]
ConfigNotFound(PathBuf),
/// A config file could not be read.
#[error("failed to read config {path:?}: {source}")]
ConfigIo {
/// Config file path.
path: PathBuf,
/// Source I/O error.
#[source]
source: std::io::Error,
},
/// A config file contains invalid TOML.
#[error("invalid config {path:?}: {message}")]
ConfigParse {
/// Config file path.
path: PathBuf,
/// Parse error message.
message: String,
},
/// A config file contains unsupported or invalid declarations.
#[error("invalid config {path:?}: {message}")]
ConfigInvalid {
/// Config file path.
path: PathBuf,
/// Validation error message.
message: String,
},
/// A treeboot boolean environment variable has an unsupported value.
#[error(
"invalid boolean environment value for {name}: {value:?} \
(expected one of 1, true, yes, on, 0, false, no, off)"
)]
InvalidBooleanEnv {
/// Environment variable name.
name: &'static str,
/// Environment variable value.
value: String,
},
/// No config was found while strict mode was enabled.
#[error("no config detected")]
NoConfigDetectedStrict,
/// The command was run from the root checkout while strict mode was enabled.
#[error("This is not a work tree")]
RootWorktreeStrict,
/// A configured command could not be spawned.
#[error("failed to run command {label}: {source}")]
CommandIo {
/// Human-readable command label.
label: String,
/// Source I/O error.
#[source]
source: std::io::Error,
},
/// A configured command exited unsuccessfully.
#[error("command {label} failed with {status}")]
CommandFailed {
/// Human-readable command label.
label: String,
/// Process exit status.
status: ExitStatus,
},
/// A file operation encountered an unsupported conflict.
#[error("{operation} file operation cannot use {path:?}: {message}")]
FileOperationConflict {
/// Operation being applied.
operation: &'static str,
/// Path involved in the conflict.
path: PathBuf,
/// Human-readable conflict detail.
message: String,
},
/// A manual file operation request is invalid.
#[error("invalid {operation} file operation: {message}")]
FileOperationInvalid {
/// Operation being planned.
operation: &'static str,
/// Human-readable validation detail.
message: String,
},
/// A file operation failed while accessing the filesystem.
#[error("{operation} file operation failed at {path:?}: {source}")]
FileOperationIo {
/// Operation being applied.
operation: &'static str,
/// Path being accessed.
path: PathBuf,
/// Source I/O error.
#[source]
source: std::io::Error,
},
/// An init script could not be spawned.
#[error("failed to run init script {path:?}: {source}")]
ScriptIo {
/// Script path.
path: PathBuf,
/// Source I/O error.
#[source]
source: std::io::Error,
},
/// An init script exited unsuccessfully.
#[error("init script {path:?} failed with {status}")]
ScriptFailed {
/// Script path.
path: PathBuf,
/// Script process status.
status: ExitStatus,
},
/// Writing output failed.
#[error("failed to write output: {source}")]
Output {
/// Source I/O error.
#[source]
source: std::io::Error,
},
/// `treeboot init` refused to replace an existing target.
#[error("init target already exists: {0:?}")]
InitTargetExists(PathBuf),
/// An init file could not be written.
#[error("failed to write init target {path:?}: {source}")]
InitIo {
/// Init target path.
path: PathBuf,
/// Source I/O error.
#[source]
source: std::io::Error,
},
}
impl Error {
/// Returns the CLI exit code associated with this error.
#[must_use]
pub const fn exit_code(&self) -> u8 {
1
}
}