diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:47:55 +0000 |
commit | 2aadc03ef15cb5ca5cc2af8a7c08e070742f0ac4 (patch) | |
tree | 033cc839730fda84ff08db877037977be94e5e3a /tests/internal.rs | |
parent | Initial commit. (diff) | |
download | cargo-upstream.tar.xz cargo-upstream.zip |
Adding upstream version 0.70.1+ds1.upstream/0.70.1+ds1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/internal.rs')
-rw-r--r-- | tests/internal.rs | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/tests/internal.rs b/tests/internal.rs new file mode 100644 index 0000000..c42cfa8 --- /dev/null +++ b/tests/internal.rs @@ -0,0 +1,107 @@ +//! Tests for internal code checks. + +#![allow(clippy::all)] + +use std::fs; + +#[test] +fn check_forbidden_code() { + // Do not use certain macros, functions, etc. + if !cargo_util::is_ci() { + // Only check these on CI, otherwise it could be annoying. + use std::io::Write; + writeln!( + std::io::stderr(), + "\nSkipping check_forbidden_code test, set CI=1 to enable" + ) + .unwrap(); + return; + } + let root_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src"); + for entry in walkdir::WalkDir::new(&root_path) + .into_iter() + .filter_entry(|e| e.path() != root_path.join("doc")) + .filter_map(|e| e.ok()) + { + let path = entry.path(); + if !entry + .file_name() + .to_str() + .map(|s| s.ends_with(".rs")) + .unwrap_or(false) + { + continue; + } + eprintln!("checking {}", path.display()); + let c = fs::read_to_string(path).unwrap(); + for (line_index, line) in c.lines().enumerate() { + if line.trim().starts_with("//") { + continue; + } + if line_has_print(line) { + if entry.file_name().to_str().unwrap() == "cargo_new.rs" && line.contains("Hello") { + // An exception. + continue; + } + panic!( + "found print macro in {}:{}\n\n{}\n\n\ + print! macros should not be used in Cargo because they can panic.\n\ + Use one of the drop_print macros instead.\n\ + ", + path.display(), + line_index, + line + ); + } + if line_has_macro(line, "dbg") { + panic!( + "found dbg! macro in {}:{}\n\n{}\n\n\ + dbg! should not be used outside of debugging.", + path.display(), + line_index, + line + ); + } + } + } +} + +fn line_has_print(line: &str) -> bool { + line_has_macro(line, "print") + || line_has_macro(line, "eprint") + || line_has_macro(line, "println") + || line_has_macro(line, "eprintln") +} + +#[test] +fn line_has_print_works() { + assert!(line_has_print("print!")); + assert!(line_has_print("println!")); + assert!(line_has_print("eprint!")); + assert!(line_has_print("eprintln!")); + assert!(line_has_print("(print!(\"hi!\"))")); + assert!(!line_has_print("print")); + assert!(!line_has_print("i like to print things")); + assert!(!line_has_print("drop_print!")); + assert!(!line_has_print("drop_println!")); + assert!(!line_has_print("drop_eprint!")); + assert!(!line_has_print("drop_eprintln!")); +} + +fn line_has_macro(line: &str, mac: &str) -> bool { + for (i, _) in line.match_indices(mac) { + if line.get(i + mac.len()..i + mac.len() + 1) != Some("!") { + continue; + } + if i == 0 { + return true; + } + // Check for identifier boundary start. + let prev1 = line.get(i - 1..i).unwrap().chars().next().unwrap(); + if prev1.is_alphanumeric() || prev1 == '_' { + continue; + } + return true; + } + false +} |