sbt 0.13.13 adds a new command called new, to create new build definitions from a template.
The new
command is extensible via a mechanism called the template resolver.
First, you need sbt’s launcher version 0.13.13 or above.
Normally the exact version for the sbt
launcher does not matter
because it will use the version specified by sbt.version
in project/build.properties
;
however for new sbt’s launcher 0.13.13 or above is required as the command functions without a project/build.properties
present.
Next, run:
$ sbt new scala/scala-seed.g8
....
name [hello]:
Template applied in ./hello
This ran the template scala/scala-seed.g8 using Giter8, prompted for values for “name” (which has a default value of “hello”, which we accepted hitting [Enter]
), and created a build under ./hello
.
scala-seed
is the official template for a “minimal” Scala project, but it’s definitely not the only one out there.
Giter8 is a templating project originally started by Nathan Hamblen in 2010, and now maintained by the foundweekends project. The unique aspect of Giter8 is that it uses GitHub (or any other git repository) to host the templates, so it allows anyone to participate in template creation. Here are some of the templates provided by official sources:
For more, see Giter8 templates on the Giter8 wiki. sbt provides out-of-the-box support for Giter8 templates by shipping with a template resolver for Giter8.
You can append Giter8 parameters to the end of the command, so for example to specify a particular branch you can use:
$ sbt new scala/scala-seed.g8 --branch myBranch
See Making your own templates for the details on how to create a new Giter8 template.
$ sbt new foundweekends/giter8.g8
We recommend licensing software templates under CC0 1.0, which waives all copyrights and related rights, similar to the “public domain.”
If you reside in a country covered by the Berne Convention, such as the US, copyright will arise automatically without registration. Thus, people won’t have legal right to use your template if you do not declare the terms of license. The tricky thing is that even permissive licenses such as MIT License and Apache License will require attribution to your template in the template user’s software. To remove all claims to the templated snippets, distribute it under CC0, which is an international equivalent to public domain.
License
-------
Written in <YEAR> by <AUTHOR NAME> <AUTHOR E-MAIL ADDRESS>
[other author/contributor lines as appropriate]
To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
The rest of this page explains how to extend the sbt new
command
to provide support for something other than Giter8 templates.
You can skip this section if you’re not interested in extending new
.
A template resolver is a partial function that looks at the arguments
after sbt new
and determines whether it can resolve to a particular template. This is analogous to resolvers
resolving a ModuleID
from the Internet.
The Giter8TemplateResolver
takes the first argument that does not start with a hyphen (-
), and checks whether it looks like
a GitHub repo or a git repo that ends in ”.g8”.
If it matches one of the patterns, it will pass the arguments to Giter8 to process.
To create your own template resolver, create a library that has template-resolver
as a dependency:
val templateResolverApi = "org.scala-sbt" % "template-resolver" % "0.1"
and extend TemplateResolver
, which is defined as:
package sbt.template;
/** A way of specifying template resolver.
*/
public interface TemplateResolver {
/** Returns true if this resolver can resolve the given argument.
*/
public boolean isDefined(String[] arguments);
/** Resolve the given argument and run the template.
*/
public void run(String[] arguments);
}
Publish the library to sbt community repo or Maven Central.
Next, create an sbt plugin that adds a TemplateResolverInfo
to templateResolverInfos
.
import Def.Setting
import Keys._
/** An experimental plugin that adds the ability for Giter8 templates to be resolved
*/
object Giter8TemplatePlugin extends AutoPlugin {
override def requires = CorePlugin
override def trigger = allRequirements
override lazy val globalSettings: Seq[Setting[_]] =
Seq(
templateResolverInfos +=
TemplateResolverInfo(ModuleID("org.scala-sbt.sbt-giter8-resolver", "sbt-giter8-resolver", "0.1.0") cross CrossVersion.binary,
"sbtgiter8resolver.Giter8TemplateResolver")
)
}
This indirecton allows template resolvers to have a classpath independent from the rest of the build.