From b5a2e4a12ef672896a35c6fadc900b66bb48688d Mon Sep 17 00:00:00 2001
From: Andre Anjos <andre.dos.anjos@gmail.com>
Date: Fri, 25 Jan 2019 15:34:27 +0100
Subject: [PATCH] Implements new project creation closes #3 and #6

---
 MANIFEST.in                                   |   3 +-
 bob/devtools/scripts/new.py                   | 180 +++++
 bob/devtools/templates/.gitignore             |  20 +
 bob/devtools/templates/.gitlab-ci.yml         |   1 +
 bob/devtools/templates/COPYING                | 674 ++++++++++++++++++
 bob/devtools/templates/LICENSE                |  27 +
 bob/devtools/templates/MANIFEST.in            |   2 +
 bob/devtools/templates/README.rst             |  46 ++
 bob/devtools/templates/buildout.cfg           |  14 +
 bob/devtools/templates/conda/meta.yaml        |  52 ++
 bob/devtools/templates/doc/.DS_Store          | Bin 0 -> 6148 bytes
 bob/devtools/templates/doc/conf.py            | 254 +++++++
 .../templates/doc/img/beat-128x128.png        | Bin 0 -> 25056 bytes
 .../templates/doc/img/beat-favicon.ico        | Bin 0 -> 27438 bytes
 bob/devtools/templates/doc/img/beat-logo.png  | Bin 0 -> 13399 bytes
 .../templates/doc/img/bob-128x128.png         | Bin 0 -> 6547 bytes
 .../templates/doc/img/bob-favicon.ico         | Bin 0 -> 4286 bytes
 bob/devtools/templates/doc/img/bob-logo.png   | Bin 0 -> 6266 bytes
 bob/devtools/templates/doc/index.rst          |  23 +
 bob/devtools/templates/doc/links.rst          |   8 +
 bob/devtools/templates/pkg/__init__.py        |   3 +
 bob/devtools/templates/requirements.txt       |   2 +
 bob/devtools/templates/setup.py               |  66 ++
 bob/devtools/templates/version.txt            |   1 +
 conda/meta.yaml                               |   2 +
 doc/index.rst                                 |   1 +
 doc/templates.rst                             | 523 ++++++++++++++
 setup.py                                      |   2 +
 28 files changed, 1903 insertions(+), 1 deletion(-)
 create mode 100644 bob/devtools/scripts/new.py
 create mode 100644 bob/devtools/templates/.gitignore
 create mode 100644 bob/devtools/templates/.gitlab-ci.yml
 create mode 100644 bob/devtools/templates/COPYING
 create mode 100644 bob/devtools/templates/LICENSE
 create mode 100644 bob/devtools/templates/MANIFEST.in
 create mode 100644 bob/devtools/templates/README.rst
 create mode 100644 bob/devtools/templates/buildout.cfg
 create mode 100644 bob/devtools/templates/conda/meta.yaml
 create mode 100644 bob/devtools/templates/doc/.DS_Store
 create mode 100644 bob/devtools/templates/doc/conf.py
 create mode 100644 bob/devtools/templates/doc/img/beat-128x128.png
 create mode 100644 bob/devtools/templates/doc/img/beat-favicon.ico
 create mode 100644 bob/devtools/templates/doc/img/beat-logo.png
 create mode 100644 bob/devtools/templates/doc/img/bob-128x128.png
 create mode 100644 bob/devtools/templates/doc/img/bob-favicon.ico
 create mode 100644 bob/devtools/templates/doc/img/bob-logo.png
 create mode 100644 bob/devtools/templates/doc/index.rst
 create mode 100644 bob/devtools/templates/doc/links.rst
 create mode 100644 bob/devtools/templates/pkg/__init__.py
 create mode 100644 bob/devtools/templates/requirements.txt
 create mode 100644 bob/devtools/templates/setup.py
 create mode 100644 bob/devtools/templates/version.txt
 create mode 100644 doc/templates.rst

diff --git a/MANIFEST.in b/MANIFEST.in
index 86a6e92e..64a24146 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,4 @@
 include LICENSE README.rst buildout.cfg version.txt
-recursive-include doc conf.py *.rst *.sh
+recursive-include doc conf.py *.rst *.sh *.png *.ico
 recursive-include bob/devtools/data *.md *.yaml *.pem matplotlibrc
+recursive-include bob/devtools/templates conf.py *.rst *.png *.ico LICENSE COPYING .gitlab-ci.yml .gitignore *.cfg *.txt *.py
diff --git a/bob/devtools/scripts/new.py b/bob/devtools/scripts/new.py
new file mode 100644
index 00000000..c6f7b8e2
--- /dev/null
+++ b/bob/devtools/scripts/new.py
@@ -0,0 +1,180 @@
+#!/usr/bin/env python
+
+import os
+import shutil
+import logging
+import datetime
+logger = logging.getLogger(__name__)
+
+import click
+import jinja2
+import pkg_resources
+
+from . import bdt
+from ..log import verbosity_option
+
+
+def copy_file(template, output_dir):
+  '''Copies a file from the template directory to the output directory
+
+  Args:
+
+    template: The path to the template, from the internal templates directory
+    output_dir: Where to save the output
+  '''
+
+  template_file = pkg_resources.resource_filename(__name__, os.path.join('..',
+    'templates', template))
+  output_file = os.path.join(output_dir, template)
+
+  basedir = os.path.dirname(output_file)
+  if not os.path.exists(basedir):
+    logger.info('mkdir %s', basedir)
+    os.makedirs(basedir)
+
+  logger.info('cp -a %s %s', template_file, output_file)
+  shutil.copy2(template_file, output_file)
+
+
+def render_template(jenv, template, context, output_dir):
+  '''Renders a template to the output directory using specific context
+
+  Args:
+
+    jenv: The Jinja2 environment to use for rendering the template
+    template: The path to the template, from the internal templates directory
+    context: A dictionary with the context to render the template with
+    output_dir: Where to save the output
+  '''
+
+  output_file = os.path.join(output_dir, template)
+
+  basedir = os.path.dirname(output_file)
+  if not os.path.exists(basedir):
+    logger.info('mkdir %s', basedir)
+    os.makedirs(basedir)
+
+  with open(output_file, 'wt') as f:
+    logger.info('rendering %s', output_file)
+    T = jenv.get_template(template)
+    f.write(T.render(**context))
+
+
+@click.command(epilog='''
+Examples:
+
+  1. Generates a new project for Bob:
+
+     $ bdt new -vv bob/bob.newpackage "John Doe" "joe@example.com"
+''')
+@click.argument('package')
+@click.argument('author')
+@click.argument('email')
+@click.option('-t', '--title', show_default=True,
+    default='New package', help='This entry defines the package title. ' \
+        'The package title should be a few words only.  It will appear ' \
+        'at the description of your package and as the title of your ' \
+        'documentation')
+@click.option('-l', '--license', type=click.Choice(['bsd', 'gplv3']),
+    default='gplv3', show_default=True,
+    help='Changes the default licensing scheme to use for your package')
+@click.option('-o', '--output-dir', help='Directory where to dump the new ' \
+          'project - must not exist')
+@verbosity_option()
+@bdt.raise_on_error
+def new(package, author, email, title, license, output_dir):
+    """Creates a folder structure for a new Bob/BEAT package
+    """
+
+    if '/' not in package:
+        raise RuntimeError('PACKAGE should be specified as "group/name"')
+
+    group, name = package.split('/')
+
+    # creates the rst title, which looks like this:
+    # =======
+    #  Title
+    # =======
+    rst_title = ('=' * (2+len(title))) + '\n ' + title + '\n' + \
+        ('=' * (2+len(title)))
+
+    # the jinja context defines the substitutions to be performed
+    today = datetime.datetime.today()
+    context = dict(
+        package = package,
+        group = group,
+        name = name,
+        author = author,
+        email = email,
+        title = title,
+        rst_title = rst_title,
+        license = license,
+        year = today.strftime('%Y'),
+        date = today.strftime('%c'),
+        )
+
+    # copy the whole template structure and de-templatize the needed files
+    if output_dir is None:
+      output_dir = os.path.join(os.path.realpath(os.curdir), name)
+    logger.info('Creating structure for %s at directory %s', package,
+        output_dir)
+
+    if os.path.exists(output_dir):
+      raise IOError('The package directory %s already exists - cannot '
+          'overwrite!' % output_dir)
+
+    logger.info('mkdir %s', output_dir)
+    os.makedirs(output_dir)
+
+    # base jinja2 engine
+    env = jinja2.Environment(
+        loader=jinja2.PackageLoader('bob.devtools', 'templates'),
+        autoescape=jinja2.select_autoescape(['html', 'xml'])
+        )
+
+    # other standard files
+    simple = [
+        'requirements.txt',
+        'buildout.cfg',
+        'MANIFEST.in',
+        'setup.py',
+        '.gitignore',
+        'doc/index.rst',
+        'doc/conf.py',
+        'doc/links.rst',
+        '.gitlab-ci.yml',
+        'README.rst',
+        'version.txt',
+        ]
+    for k in simple:
+      render_template(env, k, context, output_dir)
+
+    # handles the license file
+    if license == 'gplv3':
+      render_template(env, 'COPYING', context, output_dir)
+    else:
+      render_template(env, 'LICENSE', context, output_dir)
+
+    # creates the base python module structure
+    template_dir = pkg_resources.resource_filename(__name__, os.path.join('..',
+      'templates'))
+    logger.info('Creating base %s python module', group)
+    shutil.copytree(os.path.join(template_dir, 'pkg'),
+        os.path.join(output_dir, group))
+
+    # copies specific images to the right spot
+    copy_file(os.path.join('doc', 'img', '%s-favicon.ico' % group), output_dir)
+    copy_file(os.path.join('doc', 'img', '%s-128x128.png' % group), output_dir)
+    copy_file(os.path.join('doc', 'img', '%s-logo.png' % group), output_dir)
+
+    # finally, render the conda recipe template-template!
+    # this one is special since it is already a jinja2 template
+    conda_env = jinja2.Environment(
+        loader=jinja2.PackageLoader('bob.devtools', 'templates'),
+        autoescape=jinja2.select_autoescape(['html', 'xml']),
+        block_start_string='(%', block_end_string='%)',
+        variable_start_string='((', variable_end_string='))',
+        comment_start_string='(#', comment_end_string='#)',
+        )
+    render_template(conda_env, os.path.join('conda', 'meta.yaml'), context,
+        output_dir)
diff --git a/bob/devtools/templates/.gitignore b/bob/devtools/templates/.gitignore
new file mode 100644
index 00000000..424ce240
--- /dev/null
+++ b/bob/devtools/templates/.gitignore
@@ -0,0 +1,20 @@
+*~
+*.swp
+*.pyc
+bin
+eggs
+parts
+.installed.cfg
+.mr.developer.cfg
+*.egg-info
+src
+develop-eggs
+sphinx
+dist
+.nfs*
+.gdb_history
+build
+.coverage
+record.txt
+miniconda.sh
+miniconda/
diff --git a/bob/devtools/templates/.gitlab-ci.yml b/bob/devtools/templates/.gitlab-ci.yml
new file mode 100644
index 00000000..845b719f
--- /dev/null
+++ b/bob/devtools/templates/.gitlab-ci.yml
@@ -0,0 +1 @@
+include: 'https://gitlab.idiap.ch/bob/bob.devtools/raw/master/bob/devtools/data/gitlab-ci/single-package.yaml'
diff --git a/bob/devtools/templates/COPYING b/bob/devtools/templates/COPYING
new file mode 100644
index 00000000..94a9ed02
--- /dev/null
+++ b/bob/devtools/templates/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/bob/devtools/templates/LICENSE b/bob/devtools/templates/LICENSE
new file mode 100644
index 00000000..b0de7349
--- /dev/null
+++ b/bob/devtools/templates/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) {{ year }} Idiap Research Institute, http://www.idiap.ch/
+Written by {{ author }} <{{ email }}>
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors
+may be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/bob/devtools/templates/MANIFEST.in b/bob/devtools/templates/MANIFEST.in
new file mode 100644
index 00000000..fac97cf2
--- /dev/null
+++ b/bob/devtools/templates/MANIFEST.in
@@ -0,0 +1,2 @@
+include README.rst buildout.cfg {% if license.startswith('gpl') %}COPYING {% endif %}version.txt requirements.txt
+recursive-include doc *.rst *.png *.ico *.txt
diff --git a/bob/devtools/templates/README.rst b/bob/devtools/templates/README.rst
new file mode 100644
index 00000000..466e50a3
--- /dev/null
+++ b/bob/devtools/templates/README.rst
@@ -0,0 +1,46 @@
+.. -*- coding: utf-8 -*-
+
+.. image:: https://img.shields.io/badge/docs-stable-yellow.svg
+   :target: https://www.idiap.ch/software/bob/docs/{{ package }}/stable/index.html
+.. image:: https://img.shields.io/badge/docs-latest-orange.svg
+   :target: https://www.idiap.ch/software/bob/docs/{{ package }}/master/index.html
+.. image:: https://gitlab.idiap.ch/{{ package }}/badges/master/build.svg
+   :target: https://gitlab.idiap.ch/{{ package }}/commits/master
+.. image:: https://gitlab.idiap.ch/{{ package }}/badges/master/coverage.svg
+   :target: https://gitlab.idiap.ch/{{ package }}/commits/master
+.. image:: https://img.shields.io/badge/gitlab-project-0000c0.svg
+   :target: https://gitlab.idiap.ch/{{ package }}
+.. image:: https://img.shields.io/pypi/v/{{ name }}.svg
+   :target: https://pypi.python.org/pypi/{{ name }}
+
+
+{{ rst_title }}
+
+This package is part of {% if group == "bob" %}the signal-processing and machine learning toolbox Bob_{% else %}BEAT_, an open-source evaluation platform for data science algorithms and workflows{% endif %}.
+
+.. todo::
+
+   **Complete the sentence above to include one phrase about your
+   package!  Once this is done, delete this to-do!**
+
+
+Installation
+------------
+
+Complete {{ group }}'s `installation`_ instructions. Then, to install this
+package, run::
+
+  $ conda install {{ name }}
+
+
+Contact
+-------
+
+For questions or reporting issues to this software package, contact our
+development `mailing list`_.
+
+
+.. Place your references here:
+.. _{{ group }}: https://www.idiap.ch/software/{{ group }}
+.. _installation: https://www.idiap.ch/software/{{ group }}/install
+.. _mailing list: https://www.idiap.ch/software/{{ group }}/discuss
diff --git a/bob/devtools/templates/buildout.cfg b/bob/devtools/templates/buildout.cfg
new file mode 100644
index 00000000..de25db7d
--- /dev/null
+++ b/bob/devtools/templates/buildout.cfg
@@ -0,0 +1,14 @@
+; -*- coding: utf-8 -*-
+; {{ date }}
+
+[buildout]
+parts = scripts
+develop = .
+eggs = {{ name }}
+extensions = bob.buildout
+newest = false
+verbose = true
+
+[scripts]
+recipe = bob.buildout:scripts
+dependent-scripts = true
diff --git a/bob/devtools/templates/conda/meta.yaml b/bob/devtools/templates/conda/meta.yaml
new file mode 100644
index 00000000..4fd8b9e9
--- /dev/null
+++ b/bob/devtools/templates/conda/meta.yaml
@@ -0,0 +1,52 @@
+{% set name = '(( name ))' %}
+{% set project_dir = environ.get('RECIPE_DIR') + '/..' %}
+
+package:
+  name: {{ name }}
+  version: {{ environ.get('BOB_PACKAGE_VERSION', '0.0.1') }}
+
+build:
+  number: {{ environ.get('BOB_BUILD_NUMBER', 0) }}
+  run_exports:
+    - {{ pin_subpackage(name) }}
+  script:
+    - cd {{ project_dir }}
+    {% if environ.get('BUILD_EGG') %}
+    - python setup.py sdist --formats=zip
+    {% endif %}
+    - python setup.py install --single-version-externally-managed --record record.txt
+
+requirements:
+  # place your build dependencies before the 'host' section
+  host:
+    - python {{ python }}
+    - setuptools {{ setuptools }}
+    # place your other host dependencies here
+  run:
+    - python
+    - setuptools
+    # place other runtime dependencies here (same as requirements.txt)
+
+test:
+  imports:
+    - {{ name }}
+  commands:
+    # test commands ("script" entry-points) from your package here
+    - nosetests --with-coverage --cover-package={{ name }} -sv {{ name }}
+    - sphinx-build -aEW {{ project_dir }}/doc {{ project_dir }}/sphinx
+    - sphinx-build -aEb doctest {{ project_dir }}/doc sphinx
+    - conda inspect linkages -p $PREFIX {{ name }}  # [not win]
+    - conda inspect objects -p $PREFIX {{ name }}  # [osx]
+  requires:
+    - bob-devel {{ bob_devel }}.*
+    - nose
+    - coverage
+    - sphinx
+    - sphinx_rtd_theme
+    # extend this list with further test-time-only dependencies
+
+about:
+  home: https://www.idiap.ch/software/bob/
+  license: (% if license == 'gplv3' %)GNU General Public License v3 (GPLv3)(% else %)BSD 3-Clause(% endif %)
+  license_family: (% if license == 'gplv3' %)GPL(% else %)BSD(% endif %)
+  summary: (( title ))
diff --git a/bob/devtools/templates/doc/.DS_Store b/bob/devtools/templates/doc/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..940e942902c4c95c53cc11d73aa9ce43019c31f2
GIT binary patch
literal 6148
zcmeH~J!%6%427R!7lt%jx}3%b$PET#pTHMLVK4#Pfk0Bv(ew1vWSu%J;R&QS(yZ9s
zuh>}uu>I%x1(*PA=&sm#n3*wO;SD!jzD^(a>-+t}idTWBh?%i6VYXk}5)lvq5fA|p
z5P<~|$Wt7f=LJ2J9z_I1U>OAb`_SmFy>z6;r-LCz0P33MFs@^kpf)d1d+A7Jg=RH9
zShZS=AzqJmYOCvd=}66XSPdUmcQ&75XqN4;#)M`)L_q{ZU`Ak-`Q+#Sk^bBKKWkAc
z0wVCw2-x~?I_&vUb+$gdp4VTi>gz$L#^nq@egc^IQM{#xaliS3+Dk_&D>VHG1O^2W
H_)`MkK;;pJ

literal 0
HcmV?d00001

diff --git a/bob/devtools/templates/doc/conf.py b/bob/devtools/templates/doc/conf.py
new file mode 100644
index 00000000..62015937
--- /dev/null
+++ b/bob/devtools/templates/doc/conf.py
@@ -0,0 +1,254 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import os
+import pkg_resources
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+needs_sphinx = '1.3'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = [
+    'sphinx.ext.todo',
+    'sphinx.ext.coverage',
+    'sphinx.ext.ifconfig',
+    'sphinx.ext.autodoc',
+    'sphinx.ext.autosummary',
+    'sphinx.ext.doctest',
+    'sphinx.ext.graphviz',
+    'sphinx.ext.intersphinx',
+    'sphinx.ext.napoleon',
+    'sphinx.ext.viewcode',
+    'sphinx.ext.mathjax',
+    #'matplotlib.sphinxext.plot_directive'
+]
+
+# Be picky about warnings
+nitpicky = False
+
+# Ignores stuff we can't easily resolve on other project's sphinx manuals
+nitpick_ignore = []
+
+# Allows the user to override warnings from a separate file
+if os.path.exists('nitpick-exceptions.txt'):
+    for line in open('nitpick-exceptions.txt'):
+        if line.strip() == "" or line.startswith("#"):
+            continue
+        dtype, target = line.split(None, 1)
+        target = target.strip()
+        nitpick_ignore.append((dtype, target))
+
+# Always includes todos
+todo_include_todos = True
+
+# Generates auto-summary automatically
+autosummary_generate = True
+
+# Create numbers on figures with captions
+numfig = True
+
+# If we are on OSX, the 'dvipng' path maybe different
+dvipng_osx = '/Library/TeX/texbin/dvipng'
+if os.path.exists(dvipng_osx):
+    pngmath_dvipng = dvipng_osx
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'{{ name }}'
+import time
+copyright = u'%s, Idiap Research Institute' % time.strftime('%Y')
+
+# Grab the setup entry
+distribution = pkg_resources.require(project)[0]
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = distribution.version
+# The full version, including alpha/beta/rc tags.
+release = distribution.version
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['links.rst']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# Some variables which are useful for generated material
+project_variable = project.replace('.', '_')
+short_description = u'{{ title }}'
+owner = [u'Idiap Research Institute']
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+import sphinx_rtd_theme
+html_theme = 'sphinx_rtd_theme'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = project_variable
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+html_logo = 'img/{{ group }}-logo.png'
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+html_favicon = 'img/{{ group }}-favicon.ico'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+#html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = project_variable + u'_doc'
+
+# -- Post configuration --------------------------------------------------------
+
+# Included after all input documents
+rst_epilog = """
+.. |project| replace:: Bob
+.. |version| replace:: %s
+.. |current-year| date:: %%Y
+""" % (version, )
+
+# Default processing flags for sphinx
+autoclass_content = 'class'
+autodoc_member_order = 'bysource'
+autodoc_default_flags = [
+    'members',
+    'undoc-members',
+    'show-inheritance',
+]
+
+# For inter-documentation mapping:
+from bob.extension.utils import link_documentation, load_requirements
+sphinx_requirements = "extra-intersphinx.txt"
+if os.path.exists(sphinx_requirements):
+    intersphinx_mapping = link_documentation(
+        additional_packages=['python', 'numpy'] +
+        load_requirements(sphinx_requirements))
+else:
+    intersphinx_mapping = link_documentation()
+
+# We want to remove all private (i.e. _. or __.__) members
+# that are not in the list of accepted functions
+accepted_private_functions = ['__array__']
+
+
+def member_function_test(app, what, name, obj, skip, options):
+    # test if we have a private function
+    if len(name) > 1 and name[0] == '_':
+        # test if this private function should be allowed
+        if name not in accepted_private_functions:
+            # omit privat functions that are not in the list of accepted private functions
+            return skip
+        else:
+            # test if the method is documented
+            if not hasattr(obj, '__doc__') or not obj.__doc__:
+                return skip
+    return False
+
+
+def setup(app):
+    app.connect('autodoc-skip-member', member_function_test)
diff --git a/bob/devtools/templates/doc/img/beat-128x128.png b/bob/devtools/templates/doc/img/beat-128x128.png
new file mode 100644
index 0000000000000000000000000000000000000000..96e1f1f6a334f22adc7119b14a89778b7b0d1609
GIT binary patch
literal 25056
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
Hu0mjfb9bXL

literal 0
HcmV?d00001

diff --git a/bob/devtools/templates/doc/img/beat-favicon.ico b/bob/devtools/templates/doc/img/beat-favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..acbc0d0056cc417e7e8b71c3aac7231df78e46b7
GIT binary patch
literal 27438
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
MKhUe!$HnUZ2W-4cjQ{`u

literal 0
HcmV?d00001

diff --git a/bob/devtools/templates/doc/img/beat-logo.png b/bob/devtools/templates/doc/img/beat-logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..180021b7d25cf7bee47a4c38039562462265c8ab
GIT binary patch
literal 13399
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
PKnNvyHMwGxY4HC5CQyi4

literal 0
HcmV?d00001

diff --git a/bob/devtools/templates/doc/img/bob-128x128.png b/bob/devtools/templates/doc/img/bob-128x128.png
new file mode 100644
index 0000000000000000000000000000000000000000..787d77b3ec4f143f8dd66162227b5f385f5183f1
GIT binary patch
literal 6547
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
FV1j@GAe{gJ

literal 0
HcmV?d00001

diff --git a/bob/devtools/templates/doc/img/bob-favicon.ico b/bob/devtools/templates/doc/img/bob-favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..4cc3264302627d40868261add69eb755856611b6
GIT binary patch
literal 4286
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

literal 0
HcmV?d00001

diff --git a/bob/devtools/templates/doc/img/bob-logo.png b/bob/devtools/templates/doc/img/bob-logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..b60858a7068bf45c1ed8e3da12fe244ccdcfe85d
GIT binary patch
literal 6266
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

literal 0
HcmV?d00001

diff --git a/bob/devtools/templates/doc/index.rst b/bob/devtools/templates/doc/index.rst
new file mode 100644
index 00000000..39014e71
--- /dev/null
+++ b/bob/devtools/templates/doc/index.rst
@@ -0,0 +1,23 @@
+.. -*- coding: utf-8 -*-
+
+.. _{{ package }}:
+
+{{ rst_title }}
+
+.. todo ::
+   Write here a small (1 paragraph) introduction explaining this project. See
+   other projects for examples.
+
+
+
+Users Guide
+===========
+
+.. toctree::
+   :maxdepth: 2
+
+   api
+
+.. todolist::
+
+.. include:: links.rst
diff --git a/bob/devtools/templates/doc/links.rst b/bob/devtools/templates/doc/links.rst
new file mode 100644
index 00000000..e3da9b03
--- /dev/null
+++ b/bob/devtools/templates/doc/links.rst
@@ -0,0 +1,8 @@
+.. -*- coding: utf-8 -*-
+
+.. This file contains all links we use for documentation in a centralized place
+
+.. _idiap: http://www.idiap.ch
+.. _bob: http://www.idiap.ch/software/bob
+.. _installation: https://www.idiap.ch/software/bob/install
+.. _mailing list: https://www.idiap.ch/software/bob/discuss
diff --git a/bob/devtools/templates/pkg/__init__.py b/bob/devtools/templates/pkg/__init__.py
new file mode 100644
index 00000000..2ab1e28b
--- /dev/null
+++ b/bob/devtools/templates/pkg/__init__.py
@@ -0,0 +1,3 @@
+# see https://docs.python.org/3/library/pkgutil.html
+from pkgutil import extend_path
+__path__ = extend_path(__path__, __name__)
diff --git a/bob/devtools/templates/requirements.txt b/bob/devtools/templates/requirements.txt
new file mode 100644
index 00000000..a85739ed
--- /dev/null
+++ b/bob/devtools/templates/requirements.txt
@@ -0,0 +1,2 @@
+setuptools
+numpy
diff --git a/bob/devtools/templates/setup.py b/bob/devtools/templates/setup.py
new file mode 100644
index 00000000..ba9f4583
--- /dev/null
+++ b/bob/devtools/templates/setup.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+{% if group == 'beat' %}from setuptools import setup, find_packages
+
+def load_requirements(f):
+  retval = [str(k.strip()) for k in open(f, 'rt')]
+  return [k for k in retval if k and k[0] not in ('#', '-')]
+
+install_requires=load_requirements('requirements.txt')
+{% else %}from setuptools import setup, dist
+dist.Distribution(dict(setup_requires=['bob.extension']))
+
+from bob.extension.utils import load_requirements, find_packages
+install_requires = load_requirements()
+{% endif %}
+
+setup(
+
+    name='{{ name }}',
+    version=open("version.txt").read().rstrip(),
+    description='{{ title }}',
+
+    url='https://gitlab.idiap.ch/{{ package }}',
+    {% if license == 'gplv3' %}license='GPLv3'{% else %}license='BSD'{% endif %},
+
+    # there may be multiple authors (separate entries by comma)
+    author='{{ author }}',
+    author_email='{{ email }}',
+
+    # there may be a maintainer apart from the author - you decide
+    #maintainer='?'
+    #maintainer_email='email@example.com'
+
+    # you may add more keywords separating those by commas (a, b, c, ...)
+    keywords = "{{ group }}",
+
+    long_description=open('README.rst').read(),
+
+    # leave this here, it is pretty standard
+    packages=find_packages(),
+    include_package_data=True,
+    zip_safe = False,
+
+    install_requires=install_requires,
+
+    entry_points={
+      # add entry points (scripts, {{ group }} resources here, if any)
+      },
+
+    # check classifiers, add and remove as you see fit
+    # full list here: https://pypi.org/classifiers/
+    # don't remove the Bob framework unless it's not a {{ group }} package
+    classifiers = [
+      {% if group == 'bob' %}'Framework :: Bob',
+      {% endif %}'Development Status :: 4 - Beta',
+      'Intended Audience :: Science/Research',
+      {% if license == 'gplv3' %}'License :: OSI Approved :: GNU General Public License v3 (GPLv3)'{% else %}'License :: OSI Approved :: BSD License'{% endif %},
+      'Natural Language :: English',
+      'Programming Language :: Python',
+      'Programming Language :: Python :: 3',
+      'Topic :: Scientific/Engineering :: Artificial Intelligence',
+      'Topic :: Software Development :: Libraries :: Python Modules',
+      ],
+
+)
diff --git a/bob/devtools/templates/version.txt b/bob/devtools/templates/version.txt
new file mode 100644
index 00000000..30893e11
--- /dev/null
+++ b/bob/devtools/templates/version.txt
@@ -0,0 +1 @@
+0.0.1b0
diff --git a/conda/meta.yaml b/conda/meta.yaml
index 29370595..23f5ed3a 100644
--- a/conda/meta.yaml
+++ b/conda/meta.yaml
@@ -45,6 +45,7 @@ requirements:
     - pyyaml
     - twine
     - lxml
+    - jinja2
 
 test:
   requires:
@@ -64,6 +65,7 @@ test:
     - bdt build --help
     - bdt getpath --help
     - bdt caupdate --help
+    - bdt new --help
     - bdt ci --help
     - bdt ci build --help
     - bdt ci deploy --help
diff --git a/doc/index.rst b/doc/index.rst
index f26dfe22..c5c9d035 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -17,6 +17,7 @@ Documentation
 
    install
    release
+   templates
    api
    ci
 
diff --git a/doc/templates.rst b/doc/templates.rst
new file mode 100644
index 00000000..17d864a3
--- /dev/null
+++ b/doc/templates.rst
@@ -0,0 +1,523 @@
+.. vim: set fileencoding=utf-8 :
+
+.. _bob.devtools.templates:
+
+==========================
+ New Package Instructions
+==========================
+
+These instructions describe how create new packages for either Bob_ or BEAT_
+and provides information on how to generate a complete, but empty package from
+scratch.
+
+.. note::
+
+   If you'd like to update part of your package setup, follow similar
+   instructions and then **copy** the relevant files to your **existing**
+   setup, overriding portions you know are correct.
+
+
+.. warning::
+
+   These instructions may change as we get more experience in what needs to be
+   changed.  In case that happens, update your package by generating a new
+   setup and copying the relevant parts to your existing package(s).
+
+
+Create a new package
+--------------------
+
+To create a new package, just use the command ``bdt new``.  Use its ``--help``
+to get more information about options you can provide.
+
+
+Continuous Integration and Deployment (CI)
+------------------------------------------
+
+If you'd like just to update CI instructions, copy the file ``.gitlab-ci.yml``
+from ``bob/devtools/templates/.gitlab-ci.yml`` **overriding** your existing
+one:
+
+
+.. code-block:: sh
+
+   $ curl -k --silent https://gitlab.idiap.ch/bob/bob.devtools/raw/master/bob/devtools/templates/.gitlab-ci.yml > .gitlab-ci.yml
+   $ git add .gitlab-ci.yml
+   $ git commit -m '[ci] Updated CI instructions' .gitlab-ci.yml
+
+
+The ci file should work out of the box, it is just a reference to a global
+configuration file that is adequate for all packages inside the Bob_/BEAT_
+ecosystem.
+
+You also remember to enable the following options on your project:
+
+1. In the project "Settings" page, make sure builds are enabled
+2. Visit the "Runners" section of your package settings and enable all runners
+   with the `docker` and `macosx` tags.
+3. Setup the coverage regular expression under "CI/CD pipelines" to have the
+   value `^TOTAL.*\s+(\d+\%)$`, which is adequate for figuring out the output
+   of `coverage report`
+
+
+New unexisting dependencies
+---------------------------
+
+If your package depends on **third-party packages** (not Bob_ or BEAT_ existing
+resources) that are not in the CI, but exist on the conda ``defaults`` channel,
+you should perform some extra steps:
+
+1. Add the package in the ``meta.yml`` file of bob-devel in
+   ``bob/bob.conda/conda/bob-devel``:
+
+
+   .. code-block:: yaml
+
+      requirements:
+        host:
+          - python {{ python }}
+          - {{ compiler('c') }}
+          - {{ compiler('cxx') }}
+          # Dependency list of bob packages. Everything is pinned to allow for better
+          # reproducibility. Please keep this list sorted. It is recommended that you
+          # update all dependencies at once (to their latest version) each time you
+          # modify the dependencies here. Use ``conda search`` to find the latest
+          # version of packages.
+          - boost 1.65.1
+          - caffe 1.0  # [linux]
+          - click 6.7
+          - click-plugins 1.0.3
+          - ..
+          - [your dependency here]
+
+2. At the same file, update the version with the current date, in the format
+   preset.
+
+   .. code-block:: yaml
+
+      package:
+        name: bob-devel
+        version: 2018.05.02  <-- HERE
+
+3. Update the ``beat-devel`` and ``bob-devel`` versions in the ``meta.yml``
+   file inside ``bob/bob.conda/conda/beat-devel``:
+
+   .. code-block:: yaml
+
+      package:
+        name: beat-devel
+        version: 2018.05.02  <-- HERE
+
+      [...]
+
+      requirements:
+        host:
+          - python {{ python }}
+          - bob-devel 2018.05.02  <-- HERE
+          - requests 2.18.4
+
+4. Update the ``conda_build_config.yaml`` in
+   ``bob/bob.devtools/bob/devtools/data/conda_build_config.yaml`` with your
+   dependencies, and with the updated version of bob-devel and beat-devel. See
+   `this here <https://gitlab.idiap.ch/bob/bob.conda/merge_requests/363>`_ and
+   `this MR here <https://gitlab.idiap.ch/bob/bob.admin/merge_requests/89>`_
+   for concrete examples on how to do this.
+
+   .. note::
+
+      **This step should be performed after bob.conda's pipeline on master is
+      finished** (i.e. perform steps 1 to 3 in a branch, open a merge request
+      and wait for it to be merged, and wait for the new master branch to be
+      "green").
+
+
+Conda recipe
+------------
+
+The CI system is based on conda recipes to build the package.  The recipes are
+located in the ``conda/meta.yaml`` file of each package.  You can start
+to modify the recipe of each package from the template generated by ``bdt
+template`` command as explained above, for new packages.
+
+The template ``meta.yaml`` file in this package is up-to-date. If you see a
+Bob_ or BEAT_ package that does not look similar to this recipe, please let us
+know as soon as possible.
+
+You should refrain from modifying the recipe except for the places that you are
+asked to modify. We want to keep recipes as similar as possible so that
+updating all of them in future would be possible by a script.
+
+Each recipe is unique to the package and need to be further modified by the
+package maintainer to work. The reference definition of the ``meta.yaml`` file
+is https://conda.io/docs/user-guide/tasks/build-packages/define-metadata.html.
+The ``meta.yaml`` file (referred to as the recipe) will contain duplicate
+information that is already documented in ``setup.py``, ``requirements.txt``,
+and, eventually, in ``test-requirements.txt``. For the time being you have to
+maintain both the ``meta.yaml`` file and the other files.
+
+Let's walk through the ``conda/meta.yaml`` file (the recipe) that you just
+created and further customize it to your package.  You need to carry out all
+the steps below otherwise the template ``meta.yaml`` is not usable as it is.
+
+
+Entry-points in the ``build`` section
+=====================================
+
+You need to check if your package has any ``console_scripts``. These are
+documented in ``setup.py`` of each package. You need to list the
+``console_scripts`` entry points (only ``console_scripts``; other entry points
+**should not** be listed in ``conda/meta.yaml``) in the build section of the
+recipe.
+
+* If there are no ``console_scripts``, then you don't need to add anything
+* If there are some, list them in the ``conda/meta.yaml`` file as well:
+  (`information on entry-points at conda recipes here
+  <https://conda.io/docs/user-guide/tasks/build-packages/define-metadata.html#python-entry-points>`_).
+  For example, if the ``setup.py`` file contains:
+
+  .. code-block:: python
+
+     entry_points={
+       'console_scripts': [
+         'jman = gridtk.script.jman:main',
+         'jgen = gridtk.script.jgen:main',
+       ]
+
+  You would add the following entry-points on ``conda/meta.yaml``:
+
+  .. code-block:: yaml
+
+     build:  # add entry points at the "build" section
+       entry_points:
+         - jman = gridtk.script.jman:main
+         - jgen = gridtk.script.jgen:main
+
+
+.. note::
+
+   If your conda package runs only on linux, please add this recipe under
+   build:
+
+   .. code-block:: yaml
+
+      build:
+         skip: true  # [not linux]
+
+
+Build and host dependencies
+===========================
+
+This part of the recipe lists the packages that are required during build time
+(`information on conda package requirements here
+<https://conda.io/docs/user-guide/tasks/build-packages/define-metadata.html#requirements-section>`_).
+Having build and host requirements separately enables cross-compiling of the
+recipes.  Here are some notes:
+
+* If the packages does not contain C/C++ code, you may skip adding build
+  dependencies (pure-python packages do not typically have build dependencies
+  (that is, dependencies required for installing the package itself, except for
+  ``setuptools`` and ``python`` itself)
+* If the package does contain C/C++ code, then you need to augment the entries
+  in the section ``requirements / build`` to include:
+
+  .. code-block:: yaml
+
+     requirements:
+       build:
+         - {{ compiler('c') }}
+         - {{ compiler('cxx') }}
+         - pkg-config {{ pkg_config }}
+         - cmake {{ cmake }}
+
+  The pkg-config and cmake lines are optional. If the package uses them, you
+  need to include these as well.
+
+* List all the packages that are in ``requirements.txt`` in the
+  ``requirements / host`` section, adding a new line per dependence.  For
+  example, here is what ``bob/bob.measure`` has in its host:
+
+  .. code-block:: yaml
+
+     host:
+       - python {{ python }}
+       - setuptools {{ setuptools }}
+       - bob.extension
+       - bob.blitz
+       - bob.core
+       - bob.math
+       - bob.io.base
+       - matplotlib {{ matplotlib }}
+       - libblitz {{ libblitz }}
+       - boost {{ boost }}
+       - numpy {{ numpy }}
+       - docopt {{ docopt }}
+
+  You need to add a jinja variable like `{{ dependence }}` in front of the
+  dependencies that we **do not** develop.  The jinja variable name should not
+  contain ``.`` or ``-``; replace those with ``_``.  Bob_ and BEAT_ packages
+  (and gridtk) should be listed as is.
+
+* Unlike ``pip``, ``conda`` is **not** limited to Python programs. If the
+  package depends on some non-python package (like ``boost``), you need to list
+  it in the `host` section.
+
+
+Runtime dependencies
+====================
+
+In the ``requirements / run`` section of the conda recipe, you will list
+dependencies that are needed when a package is used (run-time) dependencies.
+Usually, for pure-python packages, you list the same packages as in the host
+section also in the run section.  This is simple, **but** conda build version
+3.x introduced a new concept named ``run_exports`` (`read more about this
+feature here
+<https://conda.io/docs/user-guide/tasks/build-packages/define-metadata.html#pin-downstream>`_)
+which makes this slightly complicated.  In summary, you put all the run-time
+dependencies in the ``requirements / run`` section **unless** this dependency
+was listed in the host section **and** the dependency has a ``run_exports`` set
+on their own recipe (what a mess!).  The problem is that you cannot easily find
+which packages actually do have ``run_exports`` unless you look at their conda
+recipe.  Usually, all the C/C++ libraries like ``jpeg``, ``hdf5`` have
+``run_exports`` (with exceptions - ``boost``, for instance,  does not have
+one!).  All ``bob`` packages have this too.  For example, here is what is
+inside the ``requirements / run`` section of ``bob/bob.measure``:
+
+.. code-block:: yaml
+
+   run:
+     - setuptools
+     - matplotlib
+     - boost
+     - {{ pin_compatible('numpy') }}
+     - docopt
+
+The ``pin_compatible`` jinja function is `explained in here
+<https://conda.io/docs/user-guide/tasks/build-packages/define-metadata.html#pin-downstream>`_.
+You need to use it on ``numpy`` if and only if you use ``numpy`` in C level.
+Otherwise, just list numpy normally. We do not know of any other package
+besides numpy used in C level that needs to use the ``pin_compatible`` jinja
+function.
+
+Here is a list of packages that we know that they have ``run_exports``:
+
+.. code-block:: yaml
+
+   - bzip2
+   - dbus
+   - expat
+   - ffmpeg
+   - fontconfig
+   - freetype
+   - giflib
+   - glib
+   - gmp
+   - gst-plugins-base
+   - gstreamer
+   - hdf5
+   - icu
+   - jpeg
+   - kaldi
+   - libblitz
+   - libboost
+   - libffi
+   - libmatio
+   - libogg
+   - libopus
+   - libpng
+   - libsvm
+   - libtiff
+   - libvpx
+   - libxcb
+   - libxml2
+   - menpo
+   - mkl # not this one but mkl-devel - no need to list mkl if you use mkl-devel in host
+   - mkl-devel
+   - ncurses
+   - openfst
+   - openssl
+   - readline
+   - sox
+   - speex
+   - speexdsp
+   - sqlite
+   - tk
+   - vlfeat
+   - xz
+   - yaml
+   - zlib
+
+
+Testing entry-points
+====================
+
+If you listed some of your ``setup.py`` ``console_sripts`` in the ``build / entry_points`` section of the conda recipe, it is adviseable you test these.  For
+example, if you had the examples entry points above, you would test them like:
+
+.. code-block:: yaml
+
+   test:
+     imports:
+       - {{ name }}
+     commands:
+       - jman --help
+       - jgen --help
+
+
+Test-time dependencies
+======================
+
+You need to list the packages here that are required during **test-time only**.
+By default, add some packages.  Do not remove them.  The test-time dependencies
+are listed in ``test-requirements.txt``, which is an optional file, not
+included in the template.   It has the same syntax as ``requirements.txt``, but
+list only things that are needed to test the package and are not part of its
+runtime.  If you do not need any test-time dependencies, you may skip these
+instructions.
+
+You may read more information about `conda test-time dependencies here <https://conda.io/docs/user-guide/tasks/build-packages/define-metadata.html#test-requirements>`_.
+
+
+Left-over conda build files
+---------------------------
+
+The conda build command may create a temporary file named ``record.txt`` in the
+project directory. Please make sure it is added in the ``.gitignore`` file so
+that is not committed to the project repository by mistake.
+
+
+Database packages and packages with extra data
+----------------------------------------------
+
+Sometimes databases or other packages require an extra download command after
+installation. If this extra data is downloaded from Idiap severs, you can
+include this data in the conda package itself to avoid downloading it two
+times. If the data is supposed to be downloaded from somewhere other than Idiap
+servers, do not include it in its conda package. For example, the database
+packages typically require this download command to be added in the
+``build:script`` section:
+
+
+.. code-block:: yaml
+
+   - python setup.py install --single-version-externally-managed --record record.txt # this line is already in the recipe. Do not add.
+   - bob_dbmanage.py {{ name.replace('bob.db.', '') }} download --missing
+
+
+Licensing
+---------
+
+There are 2 possible cases for the majority of packages in our ecosystem:
+
+1. If the package is supposed to be licensed under (a 3-clause) BSD license,
+   ensure a file called ``LICENSE`` exists at the root of your package and has
+   the correct authorship information.
+2. If the package is supposed to be licensed under GPLv3 license, then ensure a
+   file called ``COPYING`` exists on the root of your package
+
+The templating generation has an option to address this.
+
+More info about Idiap's `open-source policy here
+<https://secure.idiap.ch/intranet/services/technology-transfer/idiap-open-source-policy>`.
+
+
+Headers
+-------
+
+Sometimes people add headers with licensing terms to their files. You should
+inspect your library to make sure you don't have those. The Idiap TTO says this
+strategy is OK and simplifies our lives. Make the headers of each file you have
+as simple as possible, so they don't get outdated in case things change.
+
+Here is a minimal example (adapt to the language comment style if needed):
+
+```text
+#!/usr/bin/env python
+# vim: set fileencoding=utf-8 :
+```
+
+It is OK to also have your author name on the file if you wish to do so.
+**Don't repeat licensing terms** already explained on the root of your package
+and on the `setup.py` file.  If we need to change the license, it is painful to
+go through all the headers.
+
+
+The ``setup.py`` file
+---------------------
+
+The ``setup.py`` should be changed to include eventual ``entry_points`` you
+also included in the ``conda/meta.yaml``.  We cannot guess these.
+
+
+Buildout
+--------
+
+The default buildout file ``buildout.cfg`` should buildout from the installed
+distribution (use ``bdt create`` for that purpose) and **avoid mr.developer
+checkouts**.  If you have one of those, move it to ``develop.cfg`` and create a
+new `buildout.cfg` which should be as simple as possible.  The template project
+provided by this package takes care of this.
+
+
+The ``README.rst`` file
+-----------------------
+
+You should make the README smaller and easier to maintain.  As of today, many
+packages contain outdated installation instructions or outdated links.  More
+information can always be found at the documentation, which is automatically
+linked from the badges.
+
+You may want to revise the short introduction after automatic template
+generation.  Make it short, a single phrase is the most common size.
+
+
+Sphinx documentation
+--------------------
+
+Sphinx documentation configuration goes to a file named ``doc/conf.py``.  The
+file ``doc/index.rst`` is the root of the documentation for your package.
+
+The new documentation configuration allows for two *optional* configuration
+text files to be placed inside the ``doc/`` directory, alongside the ``conf.py`` file:
+
+* ``extra-intersphinx.txt``, which lists extra packages that should be
+  cross-linked to the documentation (as with `Sphinx's intersphinx extension
+  <http://www.sphinx-doc.org/en/stable/ext/intersphinx.html>`_. The format of
+  this text file is simple: it contains the PyPI names of packages to
+  cross-reference. One per line.
+* ``nitpick-exceptions.txt``, which lists which documentation objects to ignore
+  (for warnings and errors). The format of this text file is two-column. On the
+  first column, you should refer to `Sphinx the object
+  type <http://www.sphinx-doc.org/en/stable/domains.html#the-python-domain>`_,
+  e.g. ``py:class``, followed by a space and then the name of the that should be
+  ignored. E.g.: ``bob.bio.base.Database``.  The file may optionally contain
+  empty lines. Lines starting with ``#`` are ignored (so you can comment on why
+  you're ignoring these objects).  Ignoring errors should be used only as a
+  **last resource**.  You should first try to fix the errors as best as you can,
+  so your documentation links are properly working.
+
+
+.. tip::
+
+   You may use ``bdt dumpsphinx`` to list *documented* objects in remote sphinx
+   documentations.  This resource can be helpful to fix issues during sphinx
+   documentation building.
+
+
+Project logo and branding
+-------------------------
+
+In the gitlab Settings / General page of your project, update the logo to use
+one of ours:
+
+* For Bob_:
+
+  .. image:: https://gitlab.idiap.ch/bob/bob.devtools/raw/master/bob/devtools/templates/doc/img/bob-128x128.png
+     :alt: Bob's logo for gitlab
+
+* Fob BEAT_:
+
+  .. image:: https://gitlab.idiap.ch/bob/bob.devtools/raw/master/bob/devtools/templates/doc/img/beat-128x128.png
+     :alt: BEAT's logo for gitlab
+
+
+.. include:: links.rst
diff --git a/setup.py b/setup.py
index 518246ba..178fd465 100644
--- a/setup.py
+++ b/setup.py
@@ -18,6 +18,7 @@ requires = [
     'pyyaml',
     'twine',
     'lxml',
+    'jinja2',
     ]
 
 setup(
@@ -43,6 +44,7 @@ setup(
         ],
         'bdt.cli': [
           'release = bob.devtools.scripts.release:release',
+          'new = bob.devtools.scripts.new:new',
           'changelog = bob.devtools.scripts.changelog:changelog',
           'lasttag = bob.devtools.scripts.lasttag:lasttag',
           'visibility = bob.devtools.scripts.visibility:visibility',
-- 
GitLab