Skip to content

Conversation

gchp
Copy link
Contributor

@gchp gchp commented Jun 25, 2015

Project templates allow users to define custom templates which can be
used to scaffold projects. These templates consists of a directory of
files, each of which will be treated as a mustache template.

Example:

cargo new myproject --template=http://github.com/someone/nickel-template

This would download the template called 'nickel-template' to
~/.cargo/templates/nickel-template. Each file in that directory would
then be compiled and rendered to the new project directory created by
cargo. Once the template is downloaded, future uses can just reference
it by name:

cargo new webapp --template nickel-template

Certain files will be ignored in template directories. These are namely
files which mustache will not be able to compile. Image files, for
example are all ignored.

Closes issue #396

Project templates allow users to define custom templates which can be
used to scaffold projects. These templates consists of a directory of
files, each of which will be treated as a mustache template.

Example:

    cargo new myproject --template=http://github.com/someone/nickel-template

This would download the template called 'nickel-template' to
~/.cargo/templates/nickel-template. Each file in that directory would
then be compiled and rendered to the new project directory created by
cargo. Once the template is downloaded, future uses can just reference
it by name:

    cargo new webapp --template nickel-template

Certain files will be ignored in template directories. These are namely
files which mustache will not be able to compile. Image files, for
example are all ignored.

Closes issue rust-lang#396
@rust-highfive
Copy link

r? @huonw

(rust_highfive has picked a reviewer for you, use r? to override)

@gchp
Copy link
Contributor Author

gchp commented Jun 25, 2015

Also to note, this converts the standard lib & bin templates to mustache templates. This means that passing cargo new foo --bin is the same as cargo new foo --template bin and cargo new foo is the same as cargo new foo --template lib.

@gchp
Copy link
Contributor Author

gchp commented Jun 25, 2015

It's also a bit rough around the edges. Let me know where you think I can improve it!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, I meant to revert the changes to this file, will update!

@alexcrichton alexcrichton assigned alexcrichton and unassigned huonw Jun 29, 2015
@alexcrichton
Copy link
Member

Whoa, nice! I'm quite excited to see some progress on this front :) Some thoughts of mine:

  • I do agree that with adding templates we'll probably need some form of templating language, but I haven't looked into mustache yet and would just want to take the step lightly to "blessing" the template format for Cargo. It's likely that it may leak out into other parts of Cargo once we add support.
  • Templates coming through various different protocols probably want to be specified as such. It's somewhat ambiguous how to download an http template because it could be a tarball, SVN, git, etc. I think the syntax for fetching a template remotely will just want to indicate what protocol should be used as well.
  • It looks like no tests have been added, but I'd like to have extensive testing for this feature.
  • How does one update a template? For example if a git or http template updates over time, it's not automatically picked up with cargo new --template name.

I think it'd also be worth looking into other package managers to see what they do here. For example how does this compare to bundler's template integration (or is it Rails that has templates over there?).

Also cc @wycats, I'm sure you'll have many opinions on this!

@alexcrichton
Copy link
Member

Also cc @rust-lang/tools, you'll probably all in general be interested in this.

@gchp
Copy link
Contributor Author

gchp commented Jun 30, 2015

@alexcrichton thanks for the comments!

I figured this would spark some discussion, but wanted to get an initial draft done to kickstart it.

  • I figured the use of mustache would be questioned. Would you prefer I change (for now) to use something else? Perhaps just a regex solution?
  • I'm working on getting tests together at the moment, I will update here when I have them. Hopefully this afternoon / evening.
  • re updating, I'm not sure. I could change it so that if you specify a remote template which has already been downloaded, that the existing copy would be deleted, and re-downloaded? Or I could look at adding a cargo template command for managing templates? cargo template download <url> or cargo template update <name>. Let me know what you think is the best approach here.

I know that Django has support for project templates, but I'll check out a few similar solutions and see how they approach it. I'll update this PR as I go. Looking forward to more feedback!

@alexcrichton
Copy link
Member

I chatted with @wycats on IRC and he mentioned that handlebars may be more appropriate as a templating language (I'm personally unfamiliar with both), but I just want to make sure that we consider other possibilities.

I'm also not 100% sure about what to do on the update front, so I'm curious what other projects do in this regard. To match cargo's existing behavior then cargo new --template foo will update foo if it's a remote template every time the cargo new command is run, but that's probably a little too surprising.

@wycats
Copy link
Contributor

wycats commented Jun 30, 2015

I'm obviously biased about Handlebars, but it's basically 98% compatible with Mustache but also supports helpers exposed by the host language. In contrast, Mustache supports loops and conditionals.

@bors
Copy link
Contributor

bors commented Jul 1, 2015

☔ The latest upstream changes (presumably #1748) made this pull request unmergeable. Please resolve the merge conflicts.

@gsingh93
Copy link

Having the template download/update commands be separate from the project initialization command makes more sense to me. It feels weird to first specify a URL with --template and then change that to a name. The download/update commands could themselves be the same command, maybe just cargo template get?

@gchp
Copy link
Contributor Author

gchp commented Jul 10, 2015

Sorry for the delay on updating this, working on tests at the moment, then switching over the handlebars per the comments from @wycats. Hopefully get that part done in the next few days!

Another possibility for managing templates would be to just not store them at all. Just download the one you want, scaffold the project, then remove the template. Next time you want it, repeat the process. Just s thought...

@gchp
Copy link
Contributor Author

gchp commented Aug 27, 2015

So, just did some digging into how the django-admin.py script handles this, which is where I got the idea from in the first place.

It downloads templates to a temporary directory, which will get removed after use. You can also point it at a local folder, which obviously won't download anything. This is a better approach I think. It means that templates won't go out of date, because you need to re-download them every time you want them. If you find yourself re-using a template multiple times then you can download it yourself and point cargo at that each time instead. This changes the responsibility for managing the templates to the user, rather than cargo itself.

What do you think of that approach?

@alexcrichton
Copy link
Member

Sounds like a good idea to me!

@alexcrichton
Copy link
Member

Closing due to inactivity, but feel free to reopen with a rebase and comments addressed!

@ehiggs
Copy link
Contributor

ehiggs commented Aug 8, 2016

This was closed due to inactivity. It's almost a year old so I expect rebasing is not an option. Are there any other options for resurrecting it? It's a really useful project!

@alexcrichton
Copy link
Member

Yeah unfortunately this'll need to go through a rebase or start from scratch.

bors added a commit that referenced this pull request Feb 1, 2017
Resubmission of templating PR (#1747)

This is a manual rebase of the older #1747 PR which was basically unrebasable due to the time it's been dormant.. This implements templating for Cargo and is basically the work of Greg Chapple (@gchp).

I'd love for this feature to move forward since it's really tedious to create all the directories (e.g. `src/bin`) and copy paste docopt examples which I then edit. Then implement the `main` program to delegate to the subcommands in `src/bin`, etc.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants