Skip to content

Commit 433acfc

Browse files
committed
chore(config): Enable pedantic lints for loading and schemas
1 parent 3f6d144 commit 433acfc

15 files changed

Lines changed: 340 additions & 75 deletions

‎src/config/loading/config_builder.rs‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,45 @@ pub struct ConfigBuilderLoader {
2020

2121
impl ConfigBuilderLoader {
2222
/// Sets whether to interpolate environment variables in the config.
23+
#[must_use]
2324
pub const fn interpolate_env(mut self, interpolate: bool) -> Self {
2425
self.interpolate_env = interpolate;
2526
self
2627
}
2728

2829
/// Sets the secrets map for secret interpolation.
30+
#[must_use]
2931
pub fn secrets(mut self, secrets: HashMap<String, String>) -> Self {
3032
self.secrets = secrets;
3133
self
3234
}
3335

3436
/// Sets whether to allow empty configuration.
37+
#[must_use]
3538
pub const fn allow_empty(mut self, allow_empty: bool) -> Self {
3639
self.builder.allow_empty = allow_empty;
3740
self
3841
}
3942

40-
/// Builds the ConfigBuilderLoader and loads configuration from the specified paths.
43+
/// Builds the `ConfigBuilderLoader` and loads configuration from the specified paths.
44+
// https://github.com/vectordotdev/vector/issues/23659
45+
#[allow(
46+
clippy::missing_errors_doc,
47+
reason = "Audit and document the existing error contracts separately from lint enforcement."
48+
)]
4149
pub fn load_from_paths(
4250
self,
4351
config_paths: &[super::ConfigPath],
4452
) -> Result<ConfigBuilder, Vec<String>> {
4553
super::loader_from_paths(self, config_paths)
4654
}
4755

48-
/// Builds the ConfigBuilderLoader and loads configuration from an input reader.
56+
/// Builds the `ConfigBuilderLoader` and loads configuration from an input reader.
57+
// https://github.com/vectordotdev/vector/issues/23659
58+
#[allow(
59+
clippy::missing_errors_doc,
60+
reason = "Audit and document the existing error contracts separately from lint enforcement."
61+
)]
4962
pub fn load_from_input<R: Read>(
5063
self,
5164
input: R,
@@ -113,7 +126,7 @@ impl Process for ConfigBuilderLoader {
113126
None => {
114127
self.builder.append(deserialize_config_map(map)?)?;
115128
}
116-
};
129+
}
117130

118131
Ok(())
119132
}

‎src/config/loading/interpolation.rs‎

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ use serde_json::Value;
66
use super::representation::ConfigMap;
77

88
/// Interpolates environment variables in string leaves without changing keys or value types.
9+
// https://github.com/vectordotdev/vector/issues/23659
10+
#[allow(
11+
clippy::implicit_hasher,
12+
reason = "Keep the current collection type and API bounds during the lint rollout."
13+
)]
14+
#[allow(
15+
clippy::missing_errors_doc,
16+
reason = "Audit and document the existing error contracts separately from lint enforcement."
17+
)]
918
pub fn interpolate_config_map_with_env_vars(
1019
map: &ConfigMap,
1120
vars: &HashMap<String, String>,
@@ -73,6 +82,15 @@ pub static ENVIRONMENT_VARIABLE_INTERPOLATION_REGEX: LazyLock<Regex> = LazyLock:
7382
});
7483

7584
/// Result<interpolated config, errors>
85+
// https://github.com/vectordotdev/vector/issues/23659
86+
#[allow(
87+
clippy::implicit_hasher,
88+
reason = "Keep the current collection type and API bounds during the lint rollout."
89+
)]
90+
#[allow(
91+
clippy::missing_errors_doc,
92+
reason = "Audit and document the existing error contracts separately from lint enforcement."
93+
)]
7694
pub fn interpolate(input: &str, vars: &HashMap<String, String>) -> Result<String, Vec<String>> {
7795
let mut errors = Vec::new();
7896

@@ -83,7 +101,7 @@ pub fn interpolate(input: &str, vars: &HashMap<String, String>) -> Result<String
83101
caps.get(1)
84102
.or_else(|| caps.get(2))
85103
.map(|m| m.as_str())
86-
.map(|name| {
104+
.map_or("$", |name| {
87105
// Get the value and check for newlines (LF or CR)
88106
let val = vars.get(name).and_then(|v| {
89107
if v.contains(['\n', '\r']) {
@@ -125,7 +143,6 @@ pub fn interpolate(input: &str, vars: &HashMap<String, String>) -> Result<String
125143
}),
126144
}
127145
})
128-
.unwrap_or("$")
129146
.to_string()
130147
})
131148
.into_owned();
@@ -188,7 +205,7 @@ mod test {
188205
("FOOBAR".into(), "cats".into()),
189206
// Java commonly uses .s in env var names
190207
("FOO.BAR".into(), "turtles".into()),
191-
("EMPTY".into(), "".into()),
208+
("EMPTY".into(), String::new()),
192209
]
193210
.into_iter()
194211
.collect();

‎src/config/loading/loader.rs‎

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ impl ComponentHint {
3535

3636
/// Joins a component sub-folder to a provided path, for traversal. Since `Self` is a
3737
/// `Copy`, this is more efficient to pass by value than ref.
38+
#[must_use]
3839
pub fn join_path(self, path: &Path) -> PathBuf {
3940
path.join(self.as_component_field())
4041
}
@@ -49,7 +50,10 @@ impl ComponentHint {
4950
pub(super) mod process {
5051
use std::io::Read;
5152

52-
use super::*;
53+
use super::{
54+
ComponentHint, ConfigMap, Format, Path, Value, component_name, deserialize_config,
55+
merge_with_value, open_file, read_dir,
56+
};
5357

5458
/// This trait contains methods that deserialize files/folders. There are a few methods
5559
/// in here with subtly different names that can be hidden from public view, hence why
@@ -71,6 +75,15 @@ pub(super) mod process {
7175

7276
/// Helper method used by other methods to recursively handle file/dir loading, merging
7377
/// values against a provided configuration map.
78+
// https://github.com/vectordotdev/vector/issues/23659
79+
#[allow(
80+
clippy::manual_let_else,
81+
reason = "Keep the existing branching and control flow during the lint rollout."
82+
)]
83+
#[allow(
84+
clippy::unnecessary_debug_formatting,
85+
reason = "Preserve the existing diagnostic text and escaping behavior."
86+
)]
7487
fn load_dir_into(
7588
&mut self,
7689
path: &Path,
@@ -94,8 +107,7 @@ pub(super) mod process {
94107
if !entry
95108
.file_name()
96109
.and_then(|name| name.to_str())
97-
.map(|name| name.starts_with('.'))
98-
.unwrap_or(false)
110+
.is_some_and(|name| name.starts_with('.'))
99111
{
100112
folders.push(entry);
101113
}
@@ -106,7 +118,7 @@ pub(super) mod process {
106118
"Could not read entry in config dir: {path:?}, {err}."
107119
));
108120
}
109-
};
121+
}
110122
}
111123

112124
for entry in files {
@@ -217,6 +229,11 @@ where
217229
/// Consumes Self, and returns the final, deserialized `T`.
218230
fn take(self) -> T;
219231

232+
// https://github.com/vectordotdev/vector/issues/23659
233+
#[allow(
234+
clippy::missing_errors_doc,
235+
reason = "Audit and document the existing error contracts separately from lint enforcement."
236+
)]
220237
fn load_from_str<R: std::io::Read>(
221238
&mut self,
222239
input: R,
@@ -230,6 +247,11 @@ where
230247

231248
/// Deserializes a file with the provided format, and makes the result available via `take`.
232249
/// Returns a vector of non-fatal warnings on success, or a vector of error strings on failure.
250+
// https://github.com/vectordotdev/vector/issues/23659
251+
#[allow(
252+
clippy::missing_errors_doc,
253+
reason = "Audit and document the existing error contracts separately from lint enforcement."
254+
)]
233255
fn load_from_file(&mut self, path: &Path, format: Format) -> Result<(), Vec<String>> {
234256
if let Some((_, map)) = self.load_file(path, format)? {
235257
self.merge(map, None)?;
@@ -241,6 +263,11 @@ where
241263

242264
/// Deserializes a dir with the provided format, and makes the result available via `take`.
243265
/// Returns a vector of non-fatal warnings on success, or a vector of error strings on failure.
266+
// https://github.com/vectordotdev/vector/issues/23659
267+
#[allow(
268+
clippy::missing_errors_doc,
269+
reason = "Audit and document the existing error contracts separately from lint enforcement."
270+
)]
244271
fn load_from_dir(&mut self, path: &Path) -> Result<(), Vec<String>> {
245272
// Iterator containing component-specific sub-folders to attempt traversing into.
246273
let hints = [

‎src/config/loading/mod.rs‎

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![warn(clippy::pedantic)]
2+
13
mod config_builder;
24
pub(crate) mod interpolation;
35
mod loader;
@@ -34,6 +36,11 @@ static ALLOW_ENV_VAR_INTERPOLATION: OnceLock<bool> = OnceLock::new();
3436

3537
/// Sets whether environment variable interpolation is enabled for the process.
3638
/// Must be called exactly once at startup before any config loading.
39+
// https://github.com/vectordotdev/vector/issues/23659
40+
#[allow(
41+
clippy::missing_panics_doc,
42+
reason = "Audit and document the existing panic conditions separately from lint enforcement."
43+
)]
3744
pub fn set_env_var_interpolation(allow: bool) {
3845
ALLOW_ENV_VAR_INTERPOLATION
3946
.set(allow)
@@ -56,7 +63,7 @@ pub(super) fn component_name<P: AsRef<Path> + Debug>(path: P) -> Result<String,
5663
path.as_ref()
5764
.file_stem()
5865
.and_then(|name| name.to_str())
59-
.map(|name| name.to_string())
66+
.map(std::string::ToString::to_string)
6067
.ok_or_else(|| vec![format!("Couldn't get component name for file: {path:?}")])
6168
}
6269

@@ -91,11 +98,16 @@ pub fn merge_path_lists(
9198

9299
/// Expand a list of paths (potentially containing glob patterns) into real
93100
/// config paths, replacing it with the default paths when empty.
101+
// https://github.com/vectordotdev/vector/issues/23659
102+
#[allow(
103+
clippy::missing_panics_doc,
104+
reason = "Audit and document the existing panic conditions separately from lint enforcement."
105+
)]
94106
pub fn process_paths(config_paths: &[ConfigPath]) -> Option<Vec<ConfigPath>> {
95-
let starting_paths = if !config_paths.is_empty() {
96-
config_paths.to_owned()
97-
} else {
107+
let starting_paths = if config_paths.is_empty() {
98108
default_config_paths()
109+
} else {
110+
config_paths.to_owned()
99111
};
100112

101113
let mut paths = Vec::new();
@@ -125,7 +137,7 @@ pub fn process_paths(config_paths: &[ConfigPath]) -> Option<Vec<ConfigPath>> {
125137
}
126138
ConfigPath::Dir(_) => {
127139
for path in matches {
128-
paths.push(ConfigPath::Dir(path))
140+
paths.push(ConfigPath::Dir(path));
129141
}
130142
}
131143
}
@@ -143,6 +155,11 @@ pub fn process_paths(config_paths: &[ConfigPath]) -> Option<Vec<ConfigPath>> {
143155
Some(paths)
144156
}
145157

158+
// https://github.com/vectordotdev/vector/issues/23659
159+
#[allow(
160+
clippy::missing_errors_doc,
161+
reason = "Audit and document the existing error contracts separately from lint enforcement."
162+
)]
146163
pub fn load_from_paths(config_paths: &[ConfigPath]) -> Result<Config, Vec<String>> {
147164
let builder = ConfigBuilderLoader::default().load_from_paths(config_paths)?;
148165
let (config, build_warnings) = builder.build_with_warnings()?;
@@ -157,6 +174,11 @@ pub fn load_from_paths(config_paths: &[ConfigPath]) -> Result<Config, Vec<String
157174
/// Loads a configuration from paths. Handle secret replacement and if a provider is present
158175
/// in the builder, the config is used as bootstrapping for a remote source. Otherwise,
159176
/// provider instantiation is skipped.
177+
// https://github.com/vectordotdev/vector/issues/23659
178+
#[allow(
179+
clippy::missing_errors_doc,
180+
reason = "Audit and document the existing error contracts separately from lint enforcement."
181+
)]
160182
pub async fn load_from_paths_with_provider_and_secrets(
161183
config_paths: &[ConfigPath],
162184
signal_handler: &mut signal::SignalHandler,
@@ -196,6 +218,11 @@ pub(crate) async fn load_builder_from_paths_with_secrets(
196218
.load_from_paths(config_paths)
197219
}
198220

221+
// https://github.com/vectordotdev/vector/issues/23659
222+
#[allow(
223+
clippy::missing_errors_doc,
224+
reason = "Audit and document the existing error contracts separately from lint enforcement."
225+
)]
199226
pub async fn load_from_str_with_secrets(
200227
input: &str,
201228
format: Format,
@@ -240,7 +267,7 @@ where
240267
L: Loader<T> + Process,
241268
R: std::io::Read,
242269
{
243-
loader.load_from_str(input, format).map(|_| loader.take())
270+
loader.load_from_str(input, format).map(|()| loader.take())
244271
}
245272

246273
/// Iterators over `ConfigPaths`, and processes a file/dir according to a provided `Loader`.
@@ -265,14 +292,12 @@ where
265292
) {
266293
Ok(()) => {}
267294
Err(errs) => errors.extend(errs),
268-
};
269-
}
270-
ConfigPath::Dir(path) => {
271-
match loader.load_from_dir(path) {
272-
Ok(()) => {}
273-
Err(errs) => errors.extend(errs),
274-
};
295+
}
275296
}
297+
ConfigPath::Dir(path) => match loader.load_from_dir(path) {
298+
Ok(()) => {}
299+
Err(errs) => errors.extend(errs),
300+
},
276301
}
277302
}
278303

@@ -284,12 +309,22 @@ where
284309
}
285310

286311
/// Uses `SourceLoader` to process `ConfigPaths`, deserializing to a JSON object.
312+
// https://github.com/vectordotdev/vector/issues/23659
313+
#[allow(
314+
clippy::missing_errors_doc,
315+
reason = "Audit and document the existing error contracts separately from lint enforcement."
316+
)]
287317
pub fn load_source_from_paths(
288318
config_paths: &[ConfigPath],
289319
) -> Result<serde_json::Map<String, serde_json::Value>, Vec<String>> {
290320
loader_from_paths(SourceLoader::new(), config_paths)
291321
}
292322

323+
// https://github.com/vectordotdev/vector/issues/23659
324+
#[allow(
325+
clippy::missing_errors_doc,
326+
reason = "Audit and document the existing error contracts separately from lint enforcement."
327+
)]
293328
pub fn load_from_str(input: &str, format: Format) -> Result<Config, Vec<String>> {
294329
let builder = load_from_inputs(std::iter::once((input.as_bytes(), format)))?;
295330
let (config, build_warnings) = builder.build_with_warnings()?;
@@ -310,7 +345,7 @@ fn load_from_inputs(
310345
for (input, format) in inputs {
311346
if let Err(errs) = load(input, format).and_then(|n| config.append(n)) {
312347
// TODO: add back paths
313-
errors.extend(errs.iter().map(|e| e.to_string()));
348+
errors.extend(errs.iter().cloned());
314349
}
315350
}
316351

@@ -321,6 +356,11 @@ fn load_from_inputs(
321356
}
322357
}
323358

359+
// https://github.com/vectordotdev/vector/issues/23659
360+
#[allow(
361+
clippy::missing_errors_doc,
362+
reason = "Audit and document the existing error contracts separately from lint enforcement."
363+
)]
324364
pub fn prepare_input<R: std::io::Read>(
325365
mut input: R,
326366
interpolate_env: bool,
@@ -349,6 +389,11 @@ pub fn prepare_input<R: std::io::Read>(
349389
}
350390
}
351391

392+
// https://github.com/vectordotdev/vector/issues/23659
393+
#[allow(
394+
clippy::missing_errors_doc,
395+
reason = "Audit and document the existing error contracts separately from lint enforcement."
396+
)]
352397
pub fn load<R: std::io::Read, T>(input: R, format: Format) -> Result<T, Vec<String>>
353398
where
354399
T: serde::de::DeserializeOwned,

‎src/config/loading/representation.rs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,11 @@ mod tests {
269269
_count: u64,
270270
}
271271

272+
// https://github.com/vectordotdev/vector/issues/23659
273+
#[allow(
274+
clippy::unnecessary_wraps,
275+
reason = "Preserve the existing return type and caller contracts during the lint rollout."
276+
)]
272277
fn default_optional_value() -> Option<String> {
273278
Some("default".to_string())
274279
}

0 commit comments

Comments
 (0)