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
//! Errors produced while rendering Ninja manifests.
use crate::localization::{self, LocalizedMessage, keys};
use std::fmt;
use thiserror::Error;
/// Errors produced while rendering Ninja manifests.
#[derive(Debug, Error)]
pub enum NinjaGenError {
/// The build graph referenced an action that was not defined.
#[error("{message}")]
MissingAction {
/// Identifier of the missing action referenced by a build edge.
id: String,
/// Localized error message.
message: LocalizedMessage,
},
/// An action built outside manifest deserialization has no command entries.
#[error("command-list action {action_index} has no command entries")]
EmptyCommandRecipe {
/// One-based stable position in generated action order.
action_index: usize,
},
/// A list entry starts multiple background jobs, which cannot be
/// attributed reliably by a shared POSIX shell.
#[error(
"command-list action {action_index}, entry {entry_index} has unsupported background jobs"
)]
MultipleBackgroundJobs {
/// One-based stable position in generated action order.
action_index: usize,
/// One-based stable position in the command list.
entry_index: usize,
},
/// A list entry uses `exec` in a shell structure the wrapper cannot
/// supervise without changing its semantics.
#[error(
"command-list action {action_index}, entry {entry_index} has unsupported exec structure"
)]
UnsupportedCommandListExec {
/// One-based stable position in generated action order.
action_index: usize,
/// One-based stable position in the command list.
entry_index: usize,
},
/// A list entry contains a dynamic `eval` payload whose background jobs
/// cannot be attributed reliably.
#[error(
"command-list action {action_index}, entry {entry_index} has an unanalyzable eval payload"
)]
UnanalyzableCommandListEval {
/// One-based stable position in generated action order.
action_index: usize,
/// One-based stable position in the command list.
entry_index: usize,
},
/// A list entry contains a control character that cannot be serialized in
/// one Ninja command binding.
#[error(
"command-list action {action_index}, entry {entry_index} contains an unsafe Ninja control character"
)]
NinjaControlCharacter {
/// One-based stable position in generated action order.
action_index: usize,
/// One-based stable position in the command list.
entry_index: usize,
},
/// Completed recipe text cannot be represented safely in one Ninja binding.
#[error("recipe text contains an unsafe Ninja control character")]
UnsafeNinjaValue,
/// A PowerShell recipe exceeds the bounded in-memory encoding limit.
#[error(
"PowerShell recipe is {actual_bytes} bytes, exceeding the {maximum_bytes}-byte encoding limit"
)]
PowerShellRecipeTooLarge {
/// UTF-8 byte length of the completed recipe before PowerShell wrapping.
actual_bytes: usize,
/// Largest completed recipe Netsuke encodes in memory.
maximum_bytes: usize,
},
/// A graph with serial dependencies cannot be represented by a single
/// build-file string; callers must use [`crate::ninja_gen::generate_bundle`].
#[error("{message}")]
DyndepFilesRequired {
/// Localized error message.
message: LocalizedMessage,
},
/// A user graph path collides with Netsuke's reserved state namespace.
#[error("{message}")]
ReservedOutputPath {
/// Colliding path.
path: camino::Utf8PathBuf,
/// Localized error message.
message: LocalizedMessage,
},
/// A path contains a character unsupported by Ninja path syntax.
#[error("{message}")]
UnsupportedPathCharacter {
/// Path containing the unsupported character.
path: camino::Utf8PathBuf,
/// Unsupported character.
character: char,
/// Localized error message.
message: LocalizedMessage,
},
/// A path cannot be represented consistently in a Ninja build edge.
#[error("Ninja path contains an unsafe character: {path}")]
UnsafeNinjaPath {
/// Path rejected before its build edge reaches the generated file.
path: String,
},
/// Formatting the Ninja output failed.
#[error("{message}")]
Format {
/// Underlying formatting error.
#[source]
source: fmt::Error,
/// Localized error message.
message: LocalizedMessage,
},
}
impl From<fmt::Error> for NinjaGenError {
fn from(source: fmt::Error) -> Self {
Self::Format {
message: localization::message(keys::NINJA_GEN_FORMAT),
source,
}
}
}