Resurrect code generation through tests
This commit is contained in:
parent
69d8c3e26e
commit
95687af37b
|
@ -17,6 +17,6 @@ pest = "2.2.1"
|
|||
serde = { version = "1.0.125", features = ["derive"] }
|
||||
serde_json = "1.0.64"
|
||||
|
||||
[build-dependencies]
|
||||
[dev-dependencies]
|
||||
pest_generator = "2.2.1"
|
||||
proc-macro2 = "1.0.37"
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
use std::{error::Error, fs};
|
||||
|
||||
const PREAMBLE: &str = "\
|
||||
//! This is @generated code, do not edit by hand.
|
||||
//! See `graphql.pest` and `tests/codegen.rs`.
|
||||
#![allow(unused_attributes)]
|
||||
use super::GraphQLParser;
|
||||
";
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
generated_code()?;
|
||||
println!("cargo:rerun-if-changed=src/graphql.pest");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generated_code() -> Result<(), Box<dyn Error>> {
|
||||
let input = r###"
|
||||
#[derive(Parser)]
|
||||
#[grammar = r#"graphql.pest"#]
|
||||
struct GraphQLParser;
|
||||
"###
|
||||
.parse::<proc_macro2::TokenStream>()
|
||||
.unwrap();
|
||||
let tokens = pest_generator::derive_parser(input, false);
|
||||
let new = tokens.to_string();
|
||||
let code = format!("{}\n{}", PREAMBLE, &new);
|
||||
let current_code = fs::read_to_string("./src/parse/generated.rs").unwrap();
|
||||
if current_code != code {
|
||||
fs::write("./src/parse/generated.rs", code).unwrap();
|
||||
}
|
||||
Ok(())
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -3,3 +3,70 @@
|
|||
//!
|
||||
//! To avoid that, let's just dump generated code to string into this
|
||||
//! repository, and add a test that checks that the code is fresh.
|
||||
use std::{
|
||||
fs,
|
||||
io::Write,
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
|
||||
const PREAMBLE: &str = r#"
|
||||
//! This is @generated code, do not edit by hand.
|
||||
//! See `graphql.pest` and `tests/codegen.rs`.
|
||||
#![allow(unused_attributes)]
|
||||
use super::GraphQLParser;
|
||||
"#;
|
||||
|
||||
#[test]
|
||||
fn generated_code_is_fresh() {
|
||||
let input = format!(
|
||||
r###"
|
||||
#[derive(Parser)]
|
||||
#[grammar = r#"graphql.pest"#]
|
||||
struct GraphQLParser;
|
||||
"###,
|
||||
)
|
||||
.parse::<proc_macro2::TokenStream>()
|
||||
.unwrap();
|
||||
|
||||
let tokens = pest_generator::derive_parser(input.into(), false);
|
||||
let current =
|
||||
String::from_utf8(fs::read("./src/parse/generated.rs").unwrap_or_default()).unwrap();
|
||||
|
||||
let current_content = match current.len() > PREAMBLE.len() {
|
||||
true => ¤t[PREAMBLE.len()..],
|
||||
false => current.as_str(),
|
||||
};
|
||||
|
||||
let new = tokens.to_string();
|
||||
let is_up_to_date = normalize(¤t_content) == normalize(&new);
|
||||
|
||||
if is_up_to_date {
|
||||
return;
|
||||
}
|
||||
|
||||
let code = format!("{}\n{}", PREAMBLE, reformat(&new));
|
||||
fs::write("./src/parse/generated.rs", code).unwrap();
|
||||
panic!("Generated code in the repository is outdated, updating...");
|
||||
}
|
||||
|
||||
fn reformat(code: &str) -> String {
|
||||
let mut cmd = Command::new("rustfmt")
|
||||
.args(&["--config", "tab_spaces=2"])
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
cmd.stdin
|
||||
.take()
|
||||
.unwrap()
|
||||
.write_all(code.as_bytes())
|
||||
.unwrap();
|
||||
let output = cmd.wait_with_output().unwrap();
|
||||
assert!(output.status.success());
|
||||
String::from_utf8(output.stdout).unwrap()
|
||||
}
|
||||
|
||||
fn normalize(code: &str) -> String {
|
||||
code.replace(|c: char| c.is_ascii_whitespace() || "{},".contains(c), "")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue