generator: Run rustfmt over generated output before writing to disk (#735)

Some users are confused by seeing wildly different output after running
the generator, which is simply solved by running `rustfmt`.  As this is
both confusing and "somewhat" slow, invoke `rustfmt` directly within the
generator by piping string contents through it before redirecting to
disk.  This not only makes the output consistent, it is the fastest way
to reformat generator changes by omitting the round-trip to disk
entirely, nor having `rustfmt` recursively go through the workspace and
all files (including those that are not generated).

On a many-core machine these times are a bit skewed, but I want to
include them to prove the "speed" point nevertheless, even if simplicity
and consistency is the main reason to make this change:

Before:

    time ./target/debug/generator && time cargo fmt --all
    ./target/debug/generator  3.51s user 1.25s system 99% cpu 4.769 total
    cargo fmt --all  0.79s user 0.06s system 99% cpu 0.853 total

After:

    time ./target/debug/generator
    ./target/debug/generator  4.51s user 0.41s system 99% cpu 4.931 total
This commit is contained in:
Marijn Suijten 2023-04-07 01:48:26 +02:00 committed by GitHub
parent 42a2bd330f
commit 30cb8f1d7c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 24 deletions

View file

@ -36,8 +36,6 @@ jobs:
submodules: true
- name: Run generator
run: cargo run -p generator
- name: Format generated results
run: cargo fmt -p ash
- name: Diff autogen result
run: git diff --quiet || (echo "::error::Generated files are different, please regenerate with cargo run -p generator!"; git diff; false)

View file

@ -2937,19 +2937,18 @@ pub fn write_source_code<P: AsRef<Path>>(vk_headers_dir: &Path, src_dir: P) {
let vk_dir = src_dir.join("vk");
std::fs::create_dir_all(&vk_dir).expect("failed to create vk dir");
let mut vk_features_file = File::create(vk_dir.join("features.rs")).expect("vk/features.rs");
let mut vk_definitions_file =
let vk_features_file = File::create(vk_dir.join("features.rs")).expect("vk/features.rs");
let vk_definitions_file =
File::create(vk_dir.join("definitions.rs")).expect("vk/definitions.rs");
let mut vk_enums_file = File::create(vk_dir.join("enums.rs")).expect("vk/enums.rs");
let mut vk_bitflags_file = File::create(vk_dir.join("bitflags.rs")).expect("vk/bitflags.rs");
let mut vk_constants_file = File::create(vk_dir.join("constants.rs")).expect("vk/constants.rs");
let mut vk_extensions_file =
File::create(vk_dir.join("extensions.rs")).expect("vk/extensions.rs");
let mut vk_feature_extensions_file =
let vk_enums_file = File::create(vk_dir.join("enums.rs")).expect("vk/enums.rs");
let vk_bitflags_file = File::create(vk_dir.join("bitflags.rs")).expect("vk/bitflags.rs");
let vk_constants_file = File::create(vk_dir.join("constants.rs")).expect("vk/constants.rs");
let vk_extensions_file = File::create(vk_dir.join("extensions.rs")).expect("vk/extensions.rs");
let vk_feature_extensions_file =
File::create(vk_dir.join("feature_extensions.rs")).expect("vk/feature_extensions.rs");
let mut vk_const_debugs_file =
let vk_const_debugs_file =
File::create(vk_dir.join("const_debugs.rs")).expect("vk/const_debugs.rs");
let mut vk_aliases_file = File::create(vk_dir.join("aliases.rs")).expect("vk/aliases.rs");
let vk_aliases_file = File::create(vk_dir.join("aliases.rs")).expect("vk/aliases.rs");
let feature_code = quote! {
use std::os::raw::*;
@ -3022,18 +3021,36 @@ pub fn write_source_code<P: AsRef<Path>>(vk_headers_dir: &Path, src_dir: P) {
#(#aliases)*
};
write!(&mut vk_features_file, "{feature_code}").expect("Unable to write vk/features.rs");
write!(&mut vk_definitions_file, "{definition_code}")
.expect("Unable to write vk/definitions.rs");
write!(&mut vk_enums_file, "{enum_code}").expect("Unable to write vk/enums.rs");
write!(&mut vk_bitflags_file, "{bitflags_code}").expect("Unable to write vk/bitflags.rs");
write!(&mut vk_constants_file, "{constants_code}").expect("Unable to write vk/constants.rs");
write!(&mut vk_extensions_file, "{extension_code}").expect("Unable to write vk/extensions.rs");
write!(&mut vk_feature_extensions_file, "{feature_extensions_code}")
.expect("Unable to write vk/feature_extensions.rs");
write!(&mut vk_const_debugs_file, "{const_debugs}")
.expect("Unable to write vk/const_debugs.rs");
write!(&mut vk_aliases_file, "{aliases}").expect("Unable to write vk/aliases.rs");
fn write_formatted(text: &[u8], out: File) -> std::process::Child {
let mut child = std::process::Command::new("rustfmt")
.stdin(std::process::Stdio::piped())
.stdout(out)
.spawn()
.expect("Failed to spawn `rustfmt`");
let mut stdin = child.stdin.take().expect("Failed to open stdin");
stdin.write_all(text).unwrap();
drop(stdin);
child
}
let processes = [
write_formatted(feature_code.to_string().as_bytes(), vk_features_file),
write_formatted(definition_code.to_string().as_bytes(), vk_definitions_file),
write_formatted(enum_code.to_string().as_bytes(), vk_enums_file),
write_formatted(bitflags_code.to_string().as_bytes(), vk_bitflags_file),
write_formatted(constants_code.to_string().as_bytes(), vk_constants_file),
write_formatted(extension_code.to_string().as_bytes(), vk_extensions_file),
write_formatted(
feature_extensions_code.to_string().as_bytes(),
vk_feature_extensions_file,
),
write_formatted(const_debugs.to_string().as_bytes(), vk_const_debugs_file),
write_formatted(aliases.to_string().as_bytes(), vk_aliases_file),
];
for mut p in processes {
let status = p.wait().unwrap();
assert!(status.success());
}
let vk_include = vk_headers_dir.join("include");