fn manifest() -> String {
let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("Cargo.toml");
std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("cannot read {}: {e}", path.display()))
}
fn declaration_lines(manifest: &str, name: &str) -> Vec<String> {
manifest
.lines()
.map(str::trim)
.filter(|line| !line.starts_with('#'))
.filter(|line| {
line.starts_with(&format!("{name} "))
|| line.starts_with(&format!("{name}="))
|| line.contains(&format!("dependencies.{name}]"))
})
.map(str::to_string)
.collect()
}
#[test]
fn mimalloc_is_not_a_dependency() {
let found = declaration_lines(&manifest(), "mimalloc");
assert!(
found.is_empty(),
"mimalloc is a C allocator and was removed in v1.2.2 as the removable \
half of the C toolchain. Measurement, not preference, decided it: the \
system allocator was not slower on any measured path for this one-shot \
CLI. Re-add it only with a new measurement that says otherwise.\n{}",
found.join("\n")
);
}
#[test]
fn the_allocator_is_not_overridden_in_main() {
let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src/main.rs");
let main = std::fs::read_to_string(&path)
.unwrap_or_else(|e| panic!("cannot read {}: {e}", path.display()));
let overridden = main
.lines()
.map(str::trim)
.any(|line| line.starts_with("#[global_allocator]"));
assert!(
!overridden,
"src/main.rs registers a #[global_allocator]. The process uses the \
system allocator on purpose; a custom one is the dependency this gate \
removed."
);
}
#[test]
fn every_blake3_declaration_disables_default_features() {
let manifest = manifest();
let declarations = declaration_lines(&manifest, "blake3");
assert!(
!declarations.is_empty(),
"blake3 is expected to be declared; the gate would otherwise pass vacuously"
);
for line in &declarations {
assert!(
line.contains("default-features = false"),
"a blake3 declaration keeps its default features, which makes its \
build script compile C and assembly and puts `cc` back on the \
build path. Declare it as \
`default-features = false, features = [\"std\", \"pure\"]`.\n{line}"
);
assert!(
line.contains("\"pure\""),
"a blake3 declaration disables default features but omits `pure`, \
which is the feature that actually stops the C build.\n{line}"
);
assert!(
line.contains("\"std\""),
"a blake3 declaration drops `std`, which the crate needs for its \
`Write`/`Read` impls. Keep it alongside `pure`.\n{line}"
);
}
assert!(
declarations.len() >= 2,
"expected blake3 in both [dependencies] and [dev-dependencies]; found \
{} declaration(s). If one was dropped, drop this expectation with it.\n{}",
declarations.len(),
declarations.join("\n")
);
}
#[test]
fn the_retired_miri_allocator_cfg_is_gone() {
let manifest = manifest();
let still_declared = manifest
.lines()
.map(str::trim)
.filter(|line| !line.starts_with('#'))
.any(|line| line.contains("sqlite_graphrag_miri"));
assert!(
!still_declared,
"`sqlite_graphrag_miri` existed only to disable the mimalloc global \
allocator under Miri, which cannot model `mi_malloc_aligned`. With the \
allocator gone the cfg reads nothing, and a registered cfg nobody sets \
is the kind of dead channel this release is removing."
);
}
fn build_script_objects(dir: &std::path::Path) -> Vec<std::path::PathBuf> {
let mut out = Vec::new();
let Ok(entries) = std::fs::read_dir(dir) else {
return out;
};
for entry in entries.filter_map(Result::ok) {
let path = entry.path();
if path.is_dir() {
out.extend(build_script_objects(&path));
continue;
}
if path.extension().is_some_and(|e| e == "o") && is_under_build_out(&path) {
out.push(path);
}
}
out
}
fn is_under_build_out(path: &std::path::Path) -> bool {
let parts: Vec<_> = path
.components()
.map(|c| c.as_os_str().to_string_lossy().into_owned())
.collect();
parts.windows(3).any(|w| w[0] == "build" && w[2] == "out")
}
fn blake3_objects_from_a_clean_build() -> Result<Vec<std::path::PathBuf>, String> {
let scratch = std::env::temp_dir().join(format!(
"sgr-c-toolchain-gate-{}-{}",
std::process::id(),
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_nanos())
.unwrap_or_default()
));
let src = scratch.join("src");
std::fs::create_dir_all(&src).map_err(|e| format!("mkdir {}: {e}", src.display()))?;
std::fs::write(
scratch.join("Cargo.toml"),
"[package]\nname = \"blake3-c-probe\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\
\n[dependencies]\nblake3 = { version = \"1\", default-features = false, \
features = [\"std\", \"pure\"] }\n\n[workspace]\n",
)
.map_err(|e| format!("write manifest: {e}"))?;
std::fs::write(
src.join("lib.rs"),
"pub fn probe() -> blake3::Hash { blake3::hash(b\"x\") }\n",
)
.map_err(|e| format!("write lib.rs: {e}"))?;
let target = scratch.join("target");
let output = std::process::Command::new(env!("CARGO"))
.arg("build")
.arg("--offline")
.arg("--quiet")
.current_dir(&scratch)
.env("CARGO_TARGET_DIR", &target)
.env_remove("RUSTFLAGS")
.env_remove("CARGO_BUILD_TARGET_DIR")
.output()
.map_err(|e| format!("spawn cargo: {e}"))?;
if !output.status.success() {
let _ = std::fs::remove_dir_all(&scratch);
return Err(format!(
"probe build failed ({:?}):\n{}",
output.status.code(),
String::from_utf8_lossy(&output.stderr)
));
}
let objects = build_script_objects(&target);
let _ = std::fs::remove_dir_all(&scratch);
Ok(objects)
}
#[test]
fn a_clean_blake3_build_compiles_no_c_objects() {
match blake3_objects_from_a_clean_build() {
Ok(objects) => assert!(
objects.is_empty(),
"blake3 compiled {} C object(s) with `default-features = false, \
features = [\"std\", \"pure\"]`. `pure` is the feature that keeps the \
C compiler out of a consumer's build; if it stopped doing so, this \
project needs a different hash crate, not a louder comment.\n{}",
objects.len(),
objects
.iter()
.map(|p| p.display().to_string())
.collect::<Vec<_>>()
.join("\n")
),
Err(reason) => eprintln!(
"skipping the clean-build probe: {reason}\n\
This check needs a registry cache holding blake3 and a working \
`cargo build --offline`."
),
}
}
#[test]
fn the_c_toolchain_exception_has_exactly_the_two_known_consumers() {
let lock = std::fs::read_to_string(
std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("Cargo.lock"),
)
.expect("Cargo.lock must be readable");
assert!(
lock.contains("\nname = \"cc\"\n"),
"`cc` is gone from Cargo.lock. That is good news and it invalidates \
this test's premise — rewrite the fence, and update GAP-SG-196, \
instead of deleting the check"
);
let mut consumers: Vec<String> = Vec::new();
for package in lock.split("[[package]]").skip(1) {
let Some(name) = package
.lines()
.find_map(|line| line.strip_prefix("name = \""))
.and_then(|rest| rest.split('"').next())
else {
continue;
};
let Some(deps) = package.split("dependencies = [").nth(1) else {
continue;
};
let Some(block) = deps.split(']').next() else {
continue;
};
if block
.lines()
.any(|line| line.trim().trim_matches(['"', ',']) == "cc")
{
consumers.push(name.to_string());
}
}
consumers.sort();
consumers.dedup();
let expected = [
"blake3",
"generator",
"iana-time-zone-haiku",
"libsqlite3-sys",
"ring",
];
assert_eq!(
consumers, expected,
"the set of packages declaring a C-compiler build dependency changed.\n\
expected: {expected:?}\n\
found: {consumers:?}\n\
This project states a rust-native, self-contained goal, and GAP-SG-196 \
records the two entries that genuinely violate it today along with the \
measurements showing no alternative is ready. Anything new here needs \
the same treatment: find out whether it actually compiles C on a \
supported target, write down why it has to stay, and widen this list \
on purpose — never to make the test pass."
);
}