|
7 | 7 | //! * `tests/*.rs` are integration tests
|
8 | 8 | //!
|
9 | 9 | //! It is a bit tricky because we need match explicit information from `Cargo.toml`
|
10 |
| -//! with implicit info in directory layout |
| 10 | +//! with implicit info in directory layout. |
11 | 11 |
|
12 | 12 | use std::path::{Path, PathBuf};
|
13 | 13 | use std::fs::{self, DirEntry};
|
@@ -64,75 +64,6 @@ pub fn targets(manifest: &TomlManifest,
|
64 | 64 | Ok(targets)
|
65 | 65 | }
|
66 | 66 |
|
67 |
| -fn infer_from_directory(directory: &Path) -> Vec<(String, PathBuf)> { |
68 |
| - let entries = match fs::read_dir(directory) { |
69 |
| - Err(_) => return Vec::new(), |
70 |
| - Ok(dir) => dir |
71 |
| - }; |
72 |
| - |
73 |
| - entries |
74 |
| - .filter_map(|e| e.ok()) |
75 |
| - .filter(is_not_dotfile) |
76 |
| - .map(|e| e.path()) |
77 |
| - .filter(|f| f.extension().and_then(|s| s.to_str()) == Some("rs")) |
78 |
| - .filter_map(|f| { |
79 |
| - f.file_stem().and_then(|s| s.to_str()) |
80 |
| - .map(|s| (s.to_owned(), f.clone())) |
81 |
| - }) |
82 |
| - .collect() |
83 |
| -} |
84 |
| - |
85 |
| -fn inferred_lib(package_root: &Path) -> Option<PathBuf> { |
86 |
| - let lib = package_root.join("src").join("lib.rs"); |
87 |
| - if fs::metadata(&lib).is_ok() { |
88 |
| - Some(lib) |
89 |
| - } else { |
90 |
| - None |
91 |
| - } |
92 |
| -} |
93 |
| - |
94 |
| -fn inferred_bins(package_root: &Path, package_name: &str) -> Vec<(String, PathBuf)> { |
95 |
| - let main = package_root.join("src").join("main.rs"); |
96 |
| - let mut result = Vec::new(); |
97 |
| - if main.exists() { |
98 |
| - result.push((package_name.to_string(), main)); |
99 |
| - } |
100 |
| - result.extend(infer_from_directory(&package_root.join("src").join("bin"))); |
101 |
| - |
102 |
| - if let Ok(entries) = fs::read_dir(&package_root.join("src").join("bin")) { |
103 |
| - let multifile_bins = entries |
104 |
| - .filter_map(|e| e.ok()) |
105 |
| - .filter(is_not_dotfile) |
106 |
| - .filter(|e| match e.file_type() { |
107 |
| - Ok(t) if t.is_dir() => true, |
108 |
| - _ => false |
109 |
| - }) |
110 |
| - .filter_map(|entry| { |
111 |
| - let dir = entry.path(); |
112 |
| - let main = dir.join("main.rs"); |
113 |
| - let name = dir.file_name().and_then(|n| n.to_str()); |
114 |
| - match (main.exists(), name) { |
115 |
| - (true, Some(name)) => Some((name.to_owned(), main)), |
116 |
| - _ => None |
117 |
| - } |
118 |
| - }); |
119 |
| - result.extend(multifile_bins); |
120 |
| - } |
121 |
| - |
122 |
| - result |
123 |
| -} |
124 |
| - |
125 |
| -fn inferred_tests(package_root: &Path) -> Vec<(String, PathBuf)> { |
126 |
| - infer_from_directory(&package_root.join("tests")) |
127 |
| -} |
128 |
| - |
129 |
| -fn inferred_benches(package_root: &Path) -> Vec<(String, PathBuf)> { |
130 |
| - infer_from_directory(&package_root.join("benches")) |
131 |
| -} |
132 |
| - |
133 |
| -fn inferred_examples(package_root: &Path) -> Vec<(String, PathBuf)> { |
134 |
| - infer_from_directory(&package_root.join("examples")) |
135 |
| -} |
136 | 67 |
|
137 | 68 | fn clean_lib(toml_lib: Option<&TomlLibTarget>,
|
138 | 69 | package_root: &Path,
|
@@ -292,7 +223,6 @@ fn clean_bins(toml_bins: Option<&Vec<TomlBinTarget>>,
|
292 | 223 | }
|
293 | 224 | }
|
294 | 225 |
|
295 |
| - |
296 | 226 | fn clean_examples(toml_examples: Option<&Vec<TomlExampleTarget>>,
|
297 | 227 | package_root: &Path)
|
298 | 228 | -> CargoResult<Vec<Target>> {
|
@@ -378,6 +308,109 @@ fn clean_targets(target_kind_human: &str, target_kind: &str,
|
378 | 308 | Ok(result)
|
379 | 309 | }
|
380 | 310 |
|
| 311 | + |
| 312 | +fn inferred_lib(package_root: &Path) -> Option<PathBuf> { |
| 313 | + let lib = package_root.join("src").join("lib.rs"); |
| 314 | + if fs::metadata(&lib).is_ok() { |
| 315 | + Some(lib) |
| 316 | + } else { |
| 317 | + None |
| 318 | + } |
| 319 | +} |
| 320 | + |
| 321 | +fn inferred_bins(package_root: &Path, package_name: &str) -> Vec<(String, PathBuf)> { |
| 322 | + let main = package_root.join("src").join("main.rs"); |
| 323 | + let mut result = Vec::new(); |
| 324 | + if main.exists() { |
| 325 | + result.push((package_name.to_string(), main)); |
| 326 | + } |
| 327 | + result.extend(infer_from_directory(&package_root.join("src").join("bin"))); |
| 328 | + |
| 329 | + if let Ok(entries) = fs::read_dir(&package_root.join("src").join("bin")) { |
| 330 | + let multifile_bins = entries |
| 331 | + .filter_map(|e| e.ok()) |
| 332 | + .filter(is_not_dotfile) |
| 333 | + .filter(|e| match e.file_type() { |
| 334 | + Ok(t) if t.is_dir() => true, |
| 335 | + _ => false |
| 336 | + }) |
| 337 | + .filter_map(|entry| { |
| 338 | + let dir = entry.path(); |
| 339 | + let main = dir.join("main.rs"); |
| 340 | + let name = dir.file_name().and_then(|n| n.to_str()); |
| 341 | + match (main.exists(), name) { |
| 342 | + (true, Some(name)) => Some((name.to_owned(), main)), |
| 343 | + _ => None |
| 344 | + } |
| 345 | + }); |
| 346 | + result.extend(multifile_bins); |
| 347 | + } |
| 348 | + |
| 349 | + result |
| 350 | +} |
| 351 | + |
| 352 | +fn inferred_examples(package_root: &Path) -> Vec<(String, PathBuf)> { |
| 353 | + infer_from_directory(&package_root.join("examples")) |
| 354 | +} |
| 355 | + |
| 356 | +fn inferred_tests(package_root: &Path) -> Vec<(String, PathBuf)> { |
| 357 | + infer_from_directory(&package_root.join("tests")) |
| 358 | +} |
| 359 | + |
| 360 | +fn inferred_benches(package_root: &Path) -> Vec<(String, PathBuf)> { |
| 361 | + infer_from_directory(&package_root.join("benches")) |
| 362 | +} |
| 363 | + |
| 364 | +fn infer_from_directory(directory: &Path) -> Vec<(String, PathBuf)> { |
| 365 | + let entries = match fs::read_dir(directory) { |
| 366 | + Err(_) => return Vec::new(), |
| 367 | + Ok(dir) => dir |
| 368 | + }; |
| 369 | + |
| 370 | + entries |
| 371 | + .filter_map(|e| e.ok()) |
| 372 | + .filter(is_not_dotfile) |
| 373 | + .map(|e| e.path()) |
| 374 | + .filter(|f| f.extension().and_then(|s| s.to_str()) == Some("rs")) |
| 375 | + .filter_map(|f| { |
| 376 | + f.file_stem().and_then(|s| s.to_str()) |
| 377 | + .map(|s| (s.to_owned(), f.clone())) |
| 378 | + }) |
| 379 | + .collect() |
| 380 | +} |
| 381 | + |
| 382 | +fn is_not_dotfile(entry: &DirEntry) -> bool { |
| 383 | + entry.file_name().to_str().map(|s| s.starts_with('.')) == Some(false) |
| 384 | +} |
| 385 | + |
| 386 | + |
| 387 | +fn validate_has_name(target: &TomlTarget, |
| 388 | + target_kind_human: &str, |
| 389 | + target_kind: &str) -> CargoResult<()> { |
| 390 | + match target.name { |
| 391 | + Some(ref name) => if name.trim().is_empty() { |
| 392 | + bail!("{} target names cannot be empty", target_kind_human) |
| 393 | + }, |
| 394 | + None => bail!("{} target {}.name is required", target_kind_human, target_kind) |
| 395 | + } |
| 396 | + |
| 397 | + Ok(()) |
| 398 | +} |
| 399 | + |
| 400 | +/// Will check a list of toml targets, and make sure the target names are unique within a vector. |
| 401 | +fn validate_unique_names(targets: &[TomlTarget], target_kind: &str) -> CargoResult<()> { |
| 402 | + let mut seen = HashSet::new(); |
| 403 | + for name in targets.iter().map(|e| e.name()) { |
| 404 | + if !seen.insert(name.clone()) { |
| 405 | + bail!("found duplicate {target_kind} name {name}, \ |
| 406 | + but all {target_kind} targets must have a unique name", |
| 407 | + target_kind = target_kind, name = name); |
| 408 | + } |
| 409 | + } |
| 410 | + Ok(()) |
| 411 | +} |
| 412 | + |
| 413 | + |
381 | 414 | fn configure(toml: &TomlTarget, target: &mut Target) {
|
382 | 415 | let t2 = target.clone();
|
383 | 416 | target.set_tested(toml.test.unwrap_or(t2.tested()))
|
@@ -417,33 +450,3 @@ fn target_path(target: &TomlTarget,
|
417 | 450 | (None, Some(_)) => unreachable!()
|
418 | 451 | }
|
419 | 452 | }
|
420 |
| - |
421 |
| -fn validate_has_name(target: &TomlTarget, |
422 |
| - target_kind_human: &str, |
423 |
| - target_kind: &str) -> CargoResult<()> { |
424 |
| - match target.name { |
425 |
| - Some(ref name) => if name.trim().is_empty() { |
426 |
| - bail!("{} target names cannot be empty", target_kind_human) |
427 |
| - }, |
428 |
| - None => bail!("{} target {}.name is required", target_kind_human, target_kind) |
429 |
| - } |
430 |
| - |
431 |
| - Ok(()) |
432 |
| -} |
433 |
| - |
434 |
| -/// Will check a list of toml targets, and make sure the target names are unique within a vector. |
435 |
| -fn validate_unique_names(targets: &[TomlTarget], target_kind: &str) -> CargoResult<()> { |
436 |
| - let mut seen = HashSet::new(); |
437 |
| - for name in targets.iter().map(|e| e.name()) { |
438 |
| - if !seen.insert(name.clone()) { |
439 |
| - bail!("found duplicate {target_kind} name {name}, \ |
440 |
| - but all {target_kind} targets must have a unique name", |
441 |
| - target_kind = target_kind, name = name); |
442 |
| - } |
443 |
| - } |
444 |
| - Ok(()) |
445 |
| -} |
446 |
| - |
447 |
| -fn is_not_dotfile(entry: &DirEntry) -> bool { |
448 |
| - entry.file_name().to_str().map(|s| s.starts_with('.')) == Some(false) |
449 |
| -} |
|
0 commit comments