Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use super::utils::{show_error, TestResult};
use std::ffi::OsStr;
use std::path::Path;
fn to_correct_name(s: &str) -> String {
let mut out = String::with_capacity(s.len());
for c in s.chars() {
if c.is_uppercase() {
if !out.is_empty() {
out.push('_');
}
out.push_str(c.to_lowercase().to_string().as_str());
} else {
out.push(c);
}
}
out
}
fn check_md_doc_path(p: &Path, md_line: &str, ty_line: &str) -> bool {
let parts = md_line.split('/').collect::<Vec<_>>();
if let Some(md_name) = parts.last().and_then(|n| n.split(".md").next()) {
if let Some(name) = ty_line.split_whitespace().filter(|s| !s.is_empty()).nth(2) {
if let Some(name) = name
.split('<')
.next()
.and_then(|n| n.split('{').next())
.and_then(|n| n.split('(').next())
.and_then(|n| n.split(';').next())
{
let correct = to_correct_name(name);
if correct.as_str() == md_name {
return true;
}
show_error(
p,
&format!(
"Invalid markdown file name `{md_name}`, should have been `{correct}`",
),
);
return false;
}
}
show_error(p, &format!("Cannot extract type name from `{ty_line}`"));
} else {
show_error(p, &format!("Cannot extract md name from `{md_line}`"));
}
false
}
fn check_doc_comments_before(p: &Path, lines: &[&str], start: usize) -> bool {
let mut found_docs = false;
for pos in (0..start).rev() {
let trimmed = lines[pos].trim();
if trimmed.starts_with("///") {
if !lines[start].trim().starts_with("pub enum ThreadStatus {") {
show_error(
p,
&format!(
"Types should use common documentation by using `#[doc = include_str!(` \
and by putting the markdown file in the `md_doc` folder instead of `{}`",
&lines[pos],
),
);
return false;
}
return true;
} else if trimmed.starts_with("#[doc = include_str!(") {
found_docs = true;
if !check_md_doc_path(p, trimmed, lines[start]) {
return false;
}
} else if !trimmed.starts_with("#[") && !trimmed.starts_with("//") {
break;
}
}
if !found_docs {
show_error(
p,
&format!(
"Missing documentation for public item: `{}` (if it's not supposed to be a public \
item, use `pub(crate)` instead)",
lines[start],
),
);
return false;
}
true
}
pub fn check_docs(content: &str, p: &Path) -> TestResult {
let mut res = TestResult {
nb_tests: 0,
nb_errors: 0,
};
// No need to check if we are in the `src` or `src/common` folder or if we are in a `ffi.rs`
// file.
if p.file_name().unwrap() == OsStr::new("ffi.rs") {
return res;
}
let path = format!(
"/{}",
p.parent().unwrap().display().to_string().replace('\\', "/")
);
if path.ends_with("/src") || path.ends_with("src/common") {
return res;
}
let lines = content.lines().collect::<Vec<_>>();
for pos in 1..lines.len() {
let line = lines[pos];
let trimmed = line.trim();
if trimmed.starts_with("//!") {
show_error(p, "There shouln't be inner doc comments (`//!`)");
res.nb_tests += 1;
res.nb_errors += 1;
continue;
} else if !line.starts_with("pub fn ")
&& !trimmed.starts_with("pub struct ")
&& !trimmed.starts_with("pub enum ")
{
continue;
}
res.nb_tests += 1;
if !check_doc_comments_before(p, &lines, pos) {
res.nb_errors += 1;
}
}
res
}

View File

@@ -0,0 +1,58 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use super::utils::{show_error, TestResult};
use std::path::Path;
pub fn check_license_header(content: &str, p: &Path) -> TestResult {
let mut lines = content.lines();
let next = lines.next();
let header = "// Take a look at the license at the top of the repository in the LICENSE file.";
match next {
Some(s) if s == header => {
let next = lines.next();
match next {
Some("") => TestResult {
nb_tests: 1,
nb_errors: 0,
},
Some(s) => {
show_error(
p,
&format!("Expected empty line after license header, found `{s}`"),
);
TestResult {
nb_tests: 1,
nb_errors: 1,
}
}
None => {
show_error(p, "This file should very likely not exist...");
TestResult {
nb_tests: 1,
nb_errors: 1,
}
}
}
}
Some(s) => {
show_error(
p,
&format!(
"Expected license header at the top of the file (`{header}`), found: `{s}`",
),
);
TestResult {
nb_tests: 1,
nb_errors: 1,
}
}
None => {
show_error(p, "This (empty?) file should very likely not exist...");
TestResult {
nb_tests: 1,
nb_errors: 1,
}
}
}
}

View File

@@ -0,0 +1,50 @@
// Take a look at the license at the top of the repository in the LICENSE file.
mod docs;
mod headers;
mod signals;
mod utils;
use std::path::Path;
use utils::TestResult;
#[allow(clippy::type_complexity)]
const CHECKS: &[(fn(&str, &Path) -> TestResult, &[&str])] = &[
(headers::check_license_header, &["src", "tests", "examples"]),
(signals::check_signals, &["src"]),
(docs::check_docs, &["src"]),
];
fn handle_tests(res: &mut [TestResult]) {
utils::read_dirs(
&["benches", "examples", "src", "tests"],
&mut |p: &Path, c: &str| {
if let Some(first) = p.iter().next().and_then(|first| first.to_str()) {
for (pos, (check, filter)) in CHECKS.iter().enumerate() {
if filter.contains(&first) {
res[pos] += check(c, p);
}
}
}
},
);
}
#[test]
fn code_checks() {
let mut res = Vec::new();
for _ in CHECKS {
res.push(TestResult {
nb_tests: 0,
nb_errors: 0,
});
}
handle_tests(&mut res);
for r in res {
assert_eq!(r.nb_errors, 0);
assert_ne!(r.nb_tests, 0);
}
}

View File

@@ -0,0 +1,64 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use super::utils::{show_error, TestResult};
use std::path::Path;
fn check_supported_signals_decl<'a>(lines: &mut impl Iterator<Item = &'a str>, p: &Path) -> usize {
for line in lines {
let trimmed = line.trim();
if trimmed.starts_with("const SUPPORTED_SIGNALS: &'static [Signal]") {
if trimmed != "const SUPPORTED_SIGNALS: &[Signal] = supported_signals();" {
show_error(
p,
"SUPPORTED_SIGNALS should be declared using `supported_signals()`",
);
return 1;
}
break;
}
}
0
}
fn check_kill_decl<'a>(lines: &mut impl Iterator<Item = &'a str>, p: &Path) -> usize {
let mut errors = 0;
while let Some(line) = lines.next() {
let trimmed = line.trim();
if trimmed.starts_with("fn kill(") {
show_error(p, "`Process::kill` should not be reimplemented!");
errors += 1;
} else if trimmed.starts_with("fn kill_with(") {
if let Some(line) = lines.next() {
let trimmed = line.trim();
if trimmed.ends_with("crate::sys::convert_signal(signal)?;") || trimmed == "None" {
continue;
} else {
show_error(p, "`Process::kill_with` should use `convert_signal`");
errors += 1;
}
}
}
}
errors
}
pub fn check_signals(content: &str, p: &Path) -> TestResult {
let mut lines = content.lines();
let mut res = TestResult {
nb_tests: 0,
nb_errors: 0,
};
while let Some(line) = lines.next() {
let trimmed = line.trim();
if trimmed.starts_with("impl SystemInner {") {
res.nb_tests += 1;
res.nb_errors += check_supported_signals_decl(&mut lines, p);
} else if trimmed.starts_with("impl ProcessInner {") {
res.nb_tests += 1;
res.nb_errors += check_kill_decl(&mut lines, p);
}
}
res
}

View File

@@ -0,0 +1,58 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use std::fs::{self, File};
use std::io::Read;
use std::path::Path;
pub struct TestResult {
pub nb_tests: usize,
pub nb_errors: usize,
}
impl std::ops::AddAssign for TestResult {
fn add_assign(&mut self, other: Self) {
self.nb_tests += other.nb_tests;
self.nb_errors += other.nb_errors;
}
}
pub fn read_dirs<P: AsRef<Path>, F: FnMut(&Path, &str)>(dirs: &[P], callback: &mut F) {
for dir in dirs {
read_dir(dir, callback);
}
}
fn read_dir<P: AsRef<Path>, F: FnMut(&Path, &str)>(dir: P, callback: &mut F) {
for entry in fs::read_dir(dir).expect("read_dir failed") {
let entry = entry.expect("entry failed");
let file_type = entry.file_type().expect("file_type failed");
let path = entry.path();
if file_type.is_dir() {
read_dir(path, callback);
} else if path
.extension()
.map(|ext| ext == "rs" || ext == "c" || ext == "h")
.unwrap_or(false)
{
let content = read_file(&path);
callback(&path, &content);
}
}
}
fn read_file<P: AsRef<Path>>(p: P) -> String {
let mut f = File::open(&p).expect("read_file::open failed");
let mut content =
String::with_capacity(f.metadata().map(|m| m.len() as usize + 1).unwrap_or(0));
if let Err(e) = f.read_to_string(&mut content) {
panic!(
"read_file::read_to_end failed for `{}: {e:?}",
p.as_ref().display()
);
}
content
}
pub fn show_error(p: &Path, err: &str) {
eprintln!("=> [{}]: {err}", p.display());
}