Hello world
=========== 

This tutorial is intendend to give you a working setup of a "Hello world"
project with batou. It will not do anything useful but you will get in touch
with core concepts and the tool to perform deployments locally.

As you may already know, batou is a tool to automate deployments. It is
intended to be used with multiple components, environments, and hosts.
However, before diving into anything complex, we'll show you the most simple
deployment: managing a file with some given content locally.

We assume that you are a developer and are comfortable working in Python. We
also expect that you are working in a Unix environment and have some experience
with administrating it.

.. contents::
    :local:

To follow this tutorial you will need:

* Python 2.7
* Mercurial
* virtualenv
* enough header files to compile dependencies
* an Internet connection


Create a project directory
--------------------------

First, a deployment needs a directory to live in:

.. code-block:: console

  $ mkdir tutorial
  $ cd tutorial

Install batou
-------------

Now, to install batou we initialize a virtualenv and `buildout <http://pypi.python.org/zc.buildout>`_.

First, create a file ``buildout.cfg`` with the following content:

.. literalinclude:: ../../../examples/tutorial-helloworld/buildout.cfg
    :language: ini

Now, the following steps will install batou:

.. code-block:: console

  $ virtualenv --no-site-packages .
  $ curl -o bootstrap.py "http://svn.zope.org/*checkout*/zc.buildout/trunk/bootstrap/bootstrap.py?rev=123006"
  $ bin/python bootstrap.py -d
  $ bin/buildout

Now, batou has been installed in your project directory and the tool for
running local deployments is in the ``bin`` directory:

.. code-block:: console

  $ ls -l bin/batou-local
  -rwxr-xr-x 1 user user 672 Jul  4 15:18 bin/batou-local

Define a component
------------------

.. 
  Explain components, especially the configure method and how it needs to be recomputed.

Components are defined in a directory named ``components``. Every component in
turn lives in a directory with the name of the component. Let's create a
directory for our hello world component:

.. code-block:: console

 $ mkdir -p components/hello

In every component directory we expect a file named ``component.py`` which
contains the actual component definition. Put the following in a file named ``components/hello/component.py``:

.. literalinclude:: ../../../examples/tutorial-helloworld/components/hello/component.py
    :language: python

The remainder of the component directory can be used by you to store any other
files you need to support your component.

Define an environment
---------------------

Before we can perform a deployment we need to define an environment.
Environments configure how components are mapped to various hosts. 

Environments are stored in a directory called ``environments``:

.. code-block:: console

  $ mkdir environments

Each environment gets a config file that maps the components to the involved
hosts. For our tutorial deployment, create a file ``environments/tutorial.cfg`` with the following content:

.. literalinclude:: ../../../examples/tutorial-helloworld/environments/tutorial.cfg
    :language: ini

Run deployments
---------------

Now, we are all set to run a deployment. To deploy something locally we use the
``batou-local`` tool. It is called with two arguments: the environment and the
host you want to deploy:

.. code-block:: console

  $ bin/batou-local tutorial localhost
  Updating Hello > File(hello) > Presence(hello)
  Updating Hello > File(hello) > Content(hello)

The components will manage their results in the ``work`` directory by default,
each in its own directory:

.. code-block:: console

  $ find work
  work
  work/hello
  work/hello/hello

The file ``hello`` now contains the content we asked it to contain:

.. code-block:: console

  $ cat work/hello/hello
  Hello world

We're almost at the end of this tutorial. However, we'd like to quickly show
you two important features of batou.

If you make any change to the deployment target that contradicts the component
definition, then the next deployment run will clean it up:

.. code-block:: console

  $ echo "asdf" > work/hello/hello 
  $ bin/batou-local tutorial localhost
  Updating Hello > File(hello) > Content(hello)
  $ cat work/hello/hello
  Hello world

However, did you notice that compared to the first run batou does not change
the presence of the file? This is the second feature - if nothing needs to be
changed then running the ``batou-local`` utility will not make any changes:

.. code-block:: console

  $ bin/batou-local tutorial localhost
  $
