Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port the sysroot-crates-are-unstable Python script to rmake #129111

Merged
merged 1 commit into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 99 additions & 2 deletions tests/run-make/sysroot-crates-are-unstable/rmake.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,102 @@
use run_make_support::python_command;
// Check that crates in the sysroot are treated as unstable, unless they are
// on a list of known-stable sysroot crates.

use std::path::{Path, PathBuf};
use std::str;

use run_make_support::{rfs, rustc, target};

fn is_stable_crate(name: &str) -> bool {
matches!(name, "std" | "alloc" | "core" | "proc_macro")
}

fn main() {
python_command().arg("test.py").run();
for cr in get_unstable_sysroot_crates() {
check_crate_is_unstable(&cr);
}
println!("Done");
}

#[derive(Debug)]
struct Crate {
name: String,
path: PathBuf,
}

fn check_crate_is_unstable(cr: &Crate) {
let Crate { name, path } = cr;

print!("- Verifying that sysroot crate '{name}' is an unstable crate ...");

// Trying to use this crate from a user program should fail.
let output = rustc()
.crate_type("rlib")
.target(target())
.extern_(name, path)
.input("-")
.stdin(format!("extern crate {name};"))
.run_fail();

// Make sure it failed for the intended reason, not some other reason.
// (The actual feature required varies between crates.)
output.assert_stderr_contains("use of unstable library feature");

println!(" OK");
}

fn get_unstable_sysroot_crates() -> Vec<Crate> {
let sysroot = PathBuf::from(rustc().print("sysroot").run().stdout_utf8().trim());
let sysroot_libs_dir = sysroot.join("lib").join("rustlib").join(target()).join("lib");
println!("Sysroot libs dir: {sysroot_libs_dir:?}");

// Generate a list of all library crates in the sysroot.
let sysroot_crates = get_all_crates_in_dir(&sysroot_libs_dir);
println!(
"Found {} sysroot crates: {:?}",
sysroot_crates.len(),
sysroot_crates.iter().map(|cr| &cr.name).collect::<Vec<_>>()
);

// Self-check: If we didn't find `core`, we probably checked the wrong directory.
assert!(
sysroot_crates.iter().any(|cr| cr.name == "core"),
"Couldn't find `core` in {sysroot_libs_dir:?}"
);

let unstable_sysroot_crates =
sysroot_crates.into_iter().filter(|cr| !is_stable_crate(&cr.name)).collect::<Vec<_>>();
// Self-check: There should be at least one unstable crate in the directory.
assert!(
!unstable_sysroot_crates.is_empty(),
"Couldn't find any unstable crates in {sysroot_libs_dir:?}"
);
unstable_sysroot_crates
}

fn get_all_crates_in_dir(libs_dir: &Path) -> Vec<Crate> {
let mut libs = vec![];
rfs::read_dir_entries(libs_dir, |path| {
if !path.is_file() {
return;
}
if let Some(name) = crate_name_from_path(path) {
libs.push(Crate { name, path: path.to_owned() });
}
});
libs.sort_by(|a, b| a.name.cmp(&b.name));
libs
}

/// Treat a file as a crate if its name begins with `lib` and ends with `.rlib`.
/// The crate name is the part before the first hyphen (if any).
fn crate_name_from_path(path: &Path) -> Option<String> {
let name = path
.file_name()?
.to_str()?
.strip_prefix("lib")?
.strip_suffix(".rlib")?
.split('-')
.next()
.expect("split always yields at least one string");
Some(name.to_owned())
}
75 changes: 0 additions & 75 deletions tests/run-make/sysroot-crates-are-unstable/test.py

This file was deleted.

Loading