Closed ssokolow closed 7 years ago
cc @ehiggs @gchp
Would it be adequate if there was a {verbatim}
tag which meant nothing was touched until {endverbatim}
? This appears to be the solution used in Django. Maybe {{cargo-verbatim}}
to differentiate between underlying nesting?
The Django approach assumes you've already opted into parsing the top level of your nested grammars as Django Templates by calling template()
on the path to the file.
Using opt-out is already an anti-pattern for templating (most of the files in a given project template are going to be passed verbatim unless you're using something like Yeoman (where the project template is a JavaScript program which asks the user a bunch of questions, then builds some project boilerplate based on the answers)), so it makes no sense to make every {{ ... }}
a bomb waiting for someone to forget to mark it as ignored) and that assumes the file format actually allows {{cargo-verbatim}}
to be inserted without horrendous hackery.
(Django Templates are already painful enough at their designed purpose for want of the whitespace-gobbling {{-
, -}}
, {%-
, and -%}
that Jinja 2 added to the grammar, simply because of how the HTML whitespace collapsing algorithm interacts with things like constructing comma-separated lists which are too complex for the join
filter.)
I see this as a less drastic case of of this hyperbolic hypothetical: "Django mangles my EXE download." "It contains {{
and }}
as embedded runs of characters. Use a hex editor to insert {% verbatim %}
at the beginning and {% endverbatim %}
at the end and you'll receive your original, valid EXE when you download it."
You raise a lot of good points. For web stuff, people will want to use templates to create projects where, they themselves, will use templates. Also, as Rust may be used in embedded systems, it's not unthinkable to have a few binary blobs sitting around in a template repository and it makes no sense to parse them as templatable files. I didn't really consider these use cases so I'm happy that you raise them.
Your suggestions could simplify the code since we're just going to copy the template tree and read some (presumably) toml manifest file to see which files need to be run through the template engine.
For bike shed fun: do we use toml? What is the toml file called (template-manifest.toml
?)? How do we make templates that can create files that have the manifest toml name?
How do we make templates that can create files that have the manifest toml name?
I'd suggest using the "rename list" mechanism I proposed as a way to have different LICENSE
and .travis.yml
files for the template and the projects generated from it.
I didn't bother to think about naming, elegance, or which should be the key and which should be the value, but here's an illustrative example that parsed correctly under PyTOML in the Python REPL:
[renames]
"LICENSE.gpl3" = "LICENSE"
".travis.proj.yml" = ".travis.yml"
"template-manifest.proj.toml" = "template-manifest.toml"
(That should solve the "template repo and generated repos want to do different things with the same name" problem once and for all and do so without any kind of knock-on side-effects.)
@alexcrichton there is a lot of good material here, imo. Do you think we should take a step back from the templates and put it through the RFC process?
@ehiggs yeah that seems like a reasonable course of action to me, this hasn't hit stable yet so we can back it out still. If you feel that's the best option, would you be ok preparing a PR?
Sure. I can disable it from the command line or I can rip the whole thing out. Any preference?
@ehiggs oh I had an opinion but I'll look at #3878 instead!
Templates have been removed pending an RFC. There is a pre-RFC thread here. I think this can be closed for now.
Thanks @ehiggs!
When I went to test the behaviour of a tweak to my CLI utility boilerplate and ran
just build-release
, I got an error about""
being incorrectly indented.After a little investigation, I realized that
cargo new --template
's default behaviour is incompatible with just because they use the same syntax for substitution.Here's how
--template
mangled the project that, up until now, I've been generating new projects from usingcp -r rust-cli-boilerplate "$1"; rm "$1"/.git; {some omitted stuff to sed into Cargo.toml}; git init
.Just isn't exactly the most obscure thing and I think you can see how this would be a problem, so I hope you'll agree that there needs to be some kind of solution to pass things like
justfile
(which use{{
and}}
in their own syntax) through literally.(Imagine if I want to include a
base.html.incl
with the Twitter Bootstrap boilerplate in a web project which uses a templating engine with this sort of Django/Jinja/Twig-style syntax.cargo new --template
would mangle that too.)Heck, in hindsight, it'd make a lot more sense to make it opt-in. Perhaps a backwards-compatible middle ground could be achieved using some kind of "template config file" which, if present, overrides the current behaviour. That'd allow...
README.md
which need to exist in the template repo, but not get copied over.LICENSE
and.travis.yml
where the template and the project it generates need different content for the same files. (My template is MIT/Apache, but it generates GPL3 boilerplate. Also, the template needs a special.travis.yml
to runcargo new --template
before testing.)