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
Use include_bytes macro to avoid the need for a build script #199
Conversation
d57dbc5
to
cd04ede
Compare
Very nice, thanks for implementing this! I've thought about it myself a few times. Have you checked that this has the desired effect? (That is, touching a template file will trigger recompilation even without a build script.) One issue here is that I think it should probably include bytes for all templates used, including inherited templates, imported templates and included templates. That might be a bit more work to get right, and will actually need something that I've so far resisted doing, which is walking the entire template AST during the Are you up for taking a look at that? It basically means adapting |
Update: oh wait, you have handled all that stuff! More power to you! So, that means only the includes probably don't work correctly right now. |
I believe I handled includes properly too ;) I did test locally, and the rebuilds worked as intended. I did not test multi-level includes or extends but from the code I believe it should work correctly recursively already. /edit: To clarify, I did test extends, but not multi-level extends. /edit2: Currently, all travis tests for nightly are failing because of this: rust-lang/rust#57488 |
Hmm, it looks like the path comparison to avoid |
I also tested if a rebuild is properly triggered for nested includes, imports and extends now. On Linux, it works as expected. That still leaves the windows issues to fix. |
Did you test includes in a for or if block? |
I did now. Regardless of the true/false value of the condition, changes to the included file trigger a rebuild (which makes sense, since the I think the windows issue is caused by backslashes being parsed into escape sequences somewhere. Not sure why that happens though. |
Oh, of course. We're outputting source and there's backslashes in the string literal. Is there a proper way to escape string literals in the output of a procedural macro? |
Not sure, maybe look at the quote crate API? |
Also as follow-up (ideally in a separate commit) get rid of all the build script stuff? That includes in the README, the build script in the test crate and the helper code in the crates that supports the build script API. |
cd04ede
to
27f1399
Compare
This is meant to allow the compiler to understand the dependency between the generated code and the template source. It removes the need for a build script.
27f1399
to
227b39f
Compare
Right, I was meaning to ask if it should be deprecated, but if it can be removed, awesome :) Will do once the tests all pass. In the mean time, to give you an idea of what the resulting generated code looks like, this was generated from a template with nested imports, nested extends and a conditional include with a nested include (now using impl < 'a > ::askama::Template for Hello< 'a > {
fn render_into(&self, writer: &mut ::std::fmt::Write) -> ::askama::Result<()> {
include_bytes ! ( "/home/maarten/dev/rust/lummel/templates/base2.html" ) ;
include_bytes ! ( "/home/maarten/dev/rust/lummel/templates/base.html" ) ;
include_bytes ! ( "/home/maarten/dev/rust/lummel/templates/import1.html" ) ;
include_bytes ! ( "/home/maarten/dev/rust/lummel/templates/import2.html" ) ;
include_bytes ! ( "/home/maarten/dev/rust/lummel/templates/hello.html" ) ;
write!(
writer,
"<!DOCTYPE html>\n<html>\n<head>\n\t<title>{expr0}</title>\n\t\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"/css/main.css\">\n\t\n</head>\n<body>\n<p>Hello world!</p>\n",
expr0 = &::askama::MarkupDisplay::from(&self.title),
)?;
if self.include_foo {
writer.write_str("\n")?;
include_bytes ! ( "/home/maarten/dev/rust/lummel/templates/foo.html" ) ;
writer.write_str("FOO\n")?;
include_bytes ! ( "/home/maarten/dev/rust/lummel/templates/foo2.html" ) ;
writer.write_str("FOO2")?;
writer.write_str("\n")?;
}
writer.write_str("\n</body>\n</html>")?;
Ok(())
}
fn extension() -> Option<&'static str> {
Some("html")
}
}
impl < 'a > ::std::fmt::Display for Hello< 'a > {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
::askama::Template::render_into(self, f).map_err(|_| ::std::fmt::Error {})
}
} |
The tests are now passing, except for nightly still because of rust-lang/rust#57488. I added a commit to remove the It would probably also be prudent to update the version number in the README just before the next release, since |
bb5e071
to
74fc90c
Compare
Force pushed to re-trigger CI, it now passed =) |
Yeah, can you remove the note from the README again? Also I changed my mind, so maybe bring back After that I'm done, promise. |
74fc90c
to
7208aaf
Compare
Righty, removed the note from the readme and re-added the old function, but deprecated and with updated doc. |
Thanks, great work! |
Thanks for the review :) |
This PR adds an otherwise unused
include_bytes!(...);
statement in the generated template code for each template in the context map and for each included template. This allows the compiler to detect file level dependencies without the need for a custom build script.I believe I caught all the relevant file dependencies: extends, imports, includes and of course the template itself (if it is backed by a file, which requires some checks).
This gives more granular file-level dependency information than the build script, although I don't believe that actually gives any practical benefits right now.
Feedback welcome.