askama icon indicating copy to clipboard operation
askama copied to clipboard

Allow to easier access templates from OUT_DIR.

Open JohnScience opened this issue 4 years ago • 11 comments

Hello, I would like to have two rendering stages of templates. One occurring at compile time (with a custom syntax) and the second occurring at run time (with default syntax). For that, I'm using a build script (https://doc.rust-lang.org/cargo/reference/build-script-examples.html). Unfortunately, askama.toml allows only relative paths from the crate root, whereas the default OUT_DIR (https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts) location changes between build types (debug/release).

JohnScience avatar Apr 15 '21 00:04 JohnScience

Can you talk about what problem this entire setup is supposed to solve? What's the use case here? How custom is the syntax?

djc avatar Apr 15 '21 05:04 djc

I'm intending to perform some heavy computations on templates in build.rs to make sure that they are as light-weight as possible. Also, some of their content will rely on the results of rendering of other compile-time-rendered templates and the results of other somewhat heavy computations. According to the Cargo reference, build script cannot modify/produce files anywhere outside of the folder from OUT_DIR environment variable.

The compile-time syntax I'm currently using is such:

[[syntax]]
name = "compile-time"
block_start = "<%"
block_end = "%>"
comment_start = "<="
comment_end = "=>"
expr_start = "<#"
expr_end = "#>"

There is nothing special about the syntax itself. The main goal of this syntax is merely to be compatible with the default syntax and the files that are rendered.

JohnScience avatar Apr 15 '21 06:04 JohnScience

In terms of the contents of the compile-time-rendered templates, they produce run-time-rendered templates with the default syntax.

JohnScience avatar Apr 15 '21 06:04 JohnScience

Okay, but the paths you are trying to reference are actually in the crate root, so at least conceptually the restriction to the crate root isn't really the problem -- the use of debug vs release directories is? Have you considered rewriting askama.toml in your build script as well?

djc avatar Apr 15 '21 07:04 djc

The default build script (build.rs) is located in the crate root. So it shares the askama.toml with main.rs. Template derive proc macro searches for askama.toml in the crate root. Rewriting askama.toml with build.rs is impossible because build.rs is permitted to produce/modify files only in OUT_DIR and because Template derive proc macro searches for askama.toml only in the crate root.

JohnScience avatar Apr 15 '21 07:04 JohnScience

And I suppose adding both target/debug and target/release directories is also not optimal?

Maybe we could add a generated = true option in askama.toml that will change the root that we're searching in from the crate root to OUT_DIR.

@vallentin any thoughts/ideas?

djc avatar Apr 15 '21 08:04 djc

Honestly, I am not sufficiently familiar with Cargo. It might be so that OUT_DIR will differ between crates (askama and that of user). For debug mode, OUT_DIR of my crate points to crate_root/target/debug/build/crate_name-?hash?/out/. In crate_root/target/debug/build there are many other folders (for example const_fn-7600d0ff735224c5, const_fn-ef6fb01559d80b59). It seems that there are pairs of such folders. In each pair, one folder contains 5 files related to build script (build_script_build-7600d0ff735224c5.d, build_script_build-7600d0ff735224c5.exe, build_script_build-7600d0ff735224c5.pdb, build-script-build.exe) and the other contains four (invoked.timestamp, output, root-output, stderr).

JohnScience avatar Apr 15 '21 08:04 JohnScience

The hashes correspond to different compilations (different versions, or different Cargo features, different Rust versions, different RUSTFLAGS, that sort of thing). But it's a good point that the OUT_DIR for a crate in a workspace will depend on the hash, so just using a fixed name doesn't really work.

djc avatar Apr 15 '21 08:04 djc

Yet there is a way to check through all files in the directory and select those 2n (or maybe just 2) which start with the desired name. Since I'm not familiar with Cargo, I don't know how exactly it should and will work.

JohnScience avatar Apr 15 '21 08:04 JohnScience

Please check if #472 enables your use case.

djc avatar Apr 15 '21 09:04 djc

I don't have any thoughts or ideas beyond what's already discussed. :)

I only have a minor comment:

[...] build script cannot modify/produce files anywhere outside of the folder from OUT_DIR [...] + [...] Rewriting askama.toml with build.rs is impossible because build.rs is permitted to produce/modify files only in OUT_DIR [...]

Those two statements are not true, you can fs::write() anywhere you want. The Cargo Book specifically says "should not", it doesn't say "cannot". Whether it's useful or a solution for a workaround, is of course a different matter. :)

Build scripts may save any output files in the directory specified in the OUT_DIR environment variable. Scripts should not modify any files outside of that directory.

Outputs of the Build Script

vallentin avatar Apr 15 '21 10:04 vallentin